13-第13章-自定义数据处理器开发

第13章:自定义数据处理器开发

13.1 处理器架构设计

13.1.1 处理器接口

go 复制代码
// 定义数据处理器接口
type DataProcessor interface {
    Process(event *edgex.EdgeXEvent) error
    Name() string
}

// 处理器注册中心
var processors = make(map[string]DataProcessor)

func RegisterProcessor(p DataProcessor) {
    processors[p.Name()] = p
}

func GetProcessors() []DataProcessor {
    result := make([]DataProcessor, 0, len(processors))
    for _, p := range processors {
        result = append(result, p)
    }
    return result
}

13.2 创建自定义处理器

13.2.1 数据过滤处理器

go 复制代码
package analyzer

import (
    "log"
    "sfsEdgeStore/edgex"
)

type FilterProcessor struct {
    allowedDevices map[string]bool
}

func NewFilterProcessor(allowedDevices []string) *FilterProcessor {
    deviceMap := make(map[string]bool)
    for _, d := range allowedDevices {
        deviceMap[d] = true
    }
    return &FilterProcessor{
        allowedDevices: deviceMap,
    }
}

func (p *FilterProcessor) Name() string {
    return "filter"
}

func (p *FilterProcessor) Process(event *edgex.EdgeXEvent) error {
    if !p.allowedDevices[event.DeviceName] {
        log.Printf("Filtering event from device: %s", event.DeviceName)
        return fmt.Errorf("device not allowed")
    }
    return nil
}

13.2.2 数据转换处理器

go 复制代码
type TransformProcessor struct {
    valueMultiplier map[string]float64
}

func NewTransformProcessor() *TransformProcessor {
    return &TransformProcessor{
        valueMultiplier: map[string]float64{
            "temperature": 1.0,
            "humidity": 1.0,
        },
    }
}

func (p *TransformProcessor) Name() string {
    return "transform"
}

func (p *TransformProcessor) Process(event *edgex.EdgeXEvent) error {
    for i := range event.Readings {
        reading := &event.Readings[i]
        if multiplier, ok := p.valueMultiplier[reading.ResourceName]; ok {
            value, err := strconv.ParseFloat(reading.Value, 64)
            if err == nil {
                newValue := value * multiplier
                reading.Value = fmt.Sprintf("%f", newValue)
            }
        }
    }
    return nil
}

13.2.3 数据聚合处理器

go 复制代码
type AggregationProcessor struct {
    deviceData map[string]*DeviceStats
    mu         sync.Mutex
}

type DeviceStats struct {
    Count       int
    Sum         float64
    Min         float64
    Max         float64
    LastUpdated int64
}

func NewAggregationProcessor() *AggregationProcessor {
    return &AggregationProcessor{
        deviceData: make(map[string]*DeviceStats),
    }
}

func (p *AggregationProcessor) Name() string {
    return "aggregation"
}

func (p *AggregationProcessor) Process(event *edgex.EdgeXEvent) error {
    p.mu.Lock()
    defer p.mu.Unlock()
    
    for _, reading := range event.Readings {
        value, err := strconv.ParseFloat(reading.Value, 64)
        if err != nil {
            continue
        }
        
        key := fmt.Sprintf("%s-%s", event.DeviceName, reading.ResourceName)
        stats, ok := p.deviceData[key]
        if !ok {
            stats = &DeviceStats{
                Count: 0,
                Sum:   0,
                Min:   math.MaxFloat64,
                Max:   -math.MaxFloat64,
            }
            p.deviceData[key] = stats
        }
        
        stats.Count++
        stats.Sum += value
        if value < stats.Min {
            stats.Min = value
        }
        if value > stats.Max {
            stats.Max = value
        }
        stats.LastUpdated = time.Now().UnixNano()
    }
    
    return nil
}

func (p *AggregationProcessor) GetStats(deviceName, resourceName string) *DeviceStats {
    p.mu.Lock()
    defer p.mu.Unlock()
    
    key := fmt.Sprintf("%s-%s", deviceName, resourceName)
    return p.deviceData[key]
}

13.3 集成到系统

13.3.1 MQTT 客户端集成

go 复制代码
// mqtt/client.go 修改
type Client struct {
    client        mqtt.Client
    config        *config.Config
    dataQueue     *queue.Queue
    batchMessages []map[string]interface{}
    batchSize     int
    batchInterval time.Duration
    monitor       *monitor.Monitor
    analyzer      *analyzer.Analyzer
    processors    []DataProcessor
}

func NewClient(cfg *config.Config, dataQueue *queue.Queue, monitor *monitor.Monitor, analyzer *analyzer.Analyzer, processors ...DataProcessor) (*Client, error) {
    return &Client{
        config:        cfg,
        dataQueue:     dataQueue,
        batchMessages: make([]map[string]interface{}, 0, cfg.MQTTBatchSize),
        batchSize:     cfg.MQTTBatchSize,
        batchInterval: time.Duration(cfg.MQTTBatchInterval) * time.Second,
        monitor:       monitor,
        analyzer:      analyzer,
        processors:    processors,
    }, nil
}

func (c *Client) messageHandler(client mqtt.Client, msg mqtt.Message) {
    event, err := edgex.ProcessMessage(msg.Payload())
    if err != nil {
        log.Printf("Failed to process EdgeX message: %v", err)
        return
    }
    if event == nil {
        return
    }
    
    for _, processor := range c.processors {
        if err := processor.Process(event); err != nil {
            log.Printf("Processor %s failed: %v", processor.Name(), err)
            return
        }
    }
    
    for _, reading := range event.Readings {
        data := map[string]interface{}{
            "id":         reading.ID,
            "deviceName": event.DeviceName,
            "reading":    reading.ResourceName,
            "value":      common.ParseValue(reading.Value),
            "valueType":  reading.ValueType,
            "baseType":   reading.BaseType,
            "timestamp":  reading.Origin,
        }
        c.batchMessages = append(c.batchMessages, data)
    }
    
    if len(c.batchMessages) >= c.batchSize {
        c.flushBatch()
    }
}

13.4 实战练习

练习 13.1:告警处理器

创建一个数据处理器,当数值超出阈值时发送告警。

练习 13.2:数据清洗处理器

创建一个处理器,清洗异常数据(如明显不合理的数值)。

练习 13.3:数据路由处理器

创建一个处理器,根据设备名称将数据路由到不同的存储。

13.5 本章小结

本章讲解了如何开发自定义数据处理器:

  • 处理器接口设计
  • 各类处理器实现(过滤、转换、聚合)
  • 如何集成到现有系统
  • 处理器的链式调用

自定义处理器是扩展系统功能的强大方式。


本书版本 :1.0.0
最后更新 :2026-03-08
sfsEdgeStore - 让边缘数据存储更简单!🚀
技术栈 - Go语言、sfsDb与EdgeX Foundry。纯golang工业物联网边缘计算技术栈
项目地址GitHub
GitCode 镜像GitCode

相关推荐
Java_ESS2 小时前
终端 AI 编程完全指南:Claude Code 和 OpenCode 深度使用教程
人工智能·ai·ai编程
roman_日积跬步-终至千里2 小时前
Harness Engineering(驾驭工程)初识
ai
启山智软2 小时前
【对比了几家电商商城系统】
java·开源
AI精钢2 小时前
在生产环境进行 vibe coding 的正确方式
大数据·人工智能·ai·agent·claude·devops·cursor
biuba10242 小时前
18 openclaw事务管理:确保数据一致性的最佳实践
开发语言·ai·c#·编程·技术
peixiuhui3 小时前
赋能智慧能源,连接储能未来:G8501网关,您储能系统的“智慧大脑”与“神经中枢”
人工智能·mqtt·能源·边缘计算·iot·储能·iotgateway
岁岁种桃花儿3 小时前
AI超级智能开发系列从入门到上天第九篇:SpringAI搭建本地知识库
数据库·人工智能·ai·llm·智能体
十六年开源服务商3 小时前
WordPress图像优化实战指南2026
开源
LQQrk智能排产物联网规则引擎3 小时前
你说的,就是“规则”(JVS-Rules规则引擎)
人工智能·决策树·ai·规则引擎·风控·jvs-rules·jvs