86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
package crm3000
|
|
|
|
import (
|
|
"encoding/hex"
|
|
"fmt"
|
|
|
|
"src.dualinventive.com/go/dinet"
|
|
"src.dualinventive.com/go/dinet/rpc"
|
|
"src.dualinventive.com/go/lib/dilog"
|
|
)
|
|
|
|
// SensorMessageHandler handles a CRM sensor report.
|
|
type SensorMessageHandler struct {
|
|
log dilog.Logger
|
|
pd dinet.ParentDevice
|
|
}
|
|
|
|
//Handle takes hexData byte array and publishes it on dinet.
|
|
//Given IMEI will be overwritten if the payload contains a SerialNumber.
|
|
func (c *SensorMessageHandler) Handle(payload []byte, imei string) {
|
|
msg, err := Decode(payload)
|
|
if err != nil {
|
|
c.log.WithFields(dilog.Fields{
|
|
"imei": imei,
|
|
"payload": hex.EncodeToString(payload),
|
|
}).WithError(err).Error("Handle crm3000.Decode failed")
|
|
return
|
|
}
|
|
|
|
if msg.IMEI != "" {
|
|
imei = msg.IMEI
|
|
}
|
|
if imei == "" {
|
|
c.log.Error("no imei found in message payload")
|
|
return
|
|
}
|
|
dev, err := c.crm3000GetDevice(imei, c.pd)
|
|
if err != nil {
|
|
c.log.WithError(err).Error("crm3000GetDevice failed")
|
|
return
|
|
}
|
|
|
|
dev.Logger().WithFields(dilog.Fields{
|
|
"imei": imei,
|
|
}).Debug("received uplink message report")
|
|
err = dev.Send(&rpc.Msg{
|
|
ClassMethod: rpc.ClassMethodSensorData,
|
|
Type: rpc.MsgTypePublish,
|
|
Result: rpc.NewResult(msg.ResultValueItems(msg.Timestamp)),
|
|
})
|
|
if err != nil {
|
|
dev.Logger().WithError(err).Error("dev.send failed")
|
|
}
|
|
}
|
|
|
|
//NewSensorMessageHandler returns a SensorMessageHandler
|
|
func NewSensorMessageHandler(log dilog.Logger, pd dinet.ParentDevice) *SensorMessageHandler {
|
|
return &SensorMessageHandler{log: log, pd: pd}
|
|
}
|
|
|
|
func (c *SensorMessageHandler) crm3000GetDevice(imei string, pd dinet.ParentDevice) (*dinet.ChildDevice, error) {
|
|
uid, err := rpc.GenerateDeviceUID(rpc.DeviceUIDPrefixNBIoT, imei)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
dev, err := pd.Search(uid)
|
|
if err == nil {
|
|
cdev, ok := dev.(*Device)
|
|
if !ok {
|
|
return nil, fmt.Errorf("device is not of *crm3000.Device type (type is: %T)", dev)
|
|
}
|
|
return cdev.ChildDevice, nil
|
|
}
|
|
|
|
crm3000dev := &Device{IMEI: imei, DeviceUID: uid}
|
|
cdev := dinet.NewChildDevice(crm3000dev, pd)
|
|
cdev.Subscribe(rpc.ClassMethodSensorInfo, rpc.MsgTypeRequest, crm3000dev.SensorInfo)
|
|
err = cdev.Handshake()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
crm3000dev.ChildDevice = cdev
|
|
return cdev, nil
|
|
}
|