第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