src.dualinventive.com/go/nbiot-interface/internal/device/crm3000/crm3000.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
}