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

相关推荐
前端程序媛-Tian17 小时前
前端 AI 提效实战:从 0 到 1 打造团队专属 AI 代码评审工具
前端·人工智能·ai
Irissgwe17 小时前
LangChain之核心组件(输出解析器)
ai·langchain·llm·ai编程·输出解析器
风吹落叶花飘荡18 小时前
Hermes-Agent:开源自主智能体的范式革命
开源
研究点啥好呢18 小时前
专为求职者开发的“面馆”!!!摆脱面试焦虑!!!
python·面试·开源·reactjs·求职招聘·fastapi
阿珊和她的猫20 小时前
从实践中提炼的架构设计与工程规范
ai·agent·llama·cli·mcp
❀͜͡傀儡师20 小时前
从“爱马仕”到“过街鼠”:Nous Research Hermes Agent 是如何被钉在开源耻辱柱上的
开源·manus·hermes agent
俊哥V20 小时前
每日 AI 研究简报 · 2026-05-05
人工智能·ai
adouwt21 小时前
给 AI 用的代码索引器
ai
F_U_N_21 小时前
新手不会搭建知识平台 手把手教你 PandaWiki 零基础快速部署
人工智能·开源