Skip to content

Commit

Permalink
Convert register data to string based on data type.
Browse files Browse the repository at this point in the history
Signed-off-by: zongke <zongk@shangyuantech.com>
  • Loading branch information
zongke committed Apr 15, 2021
1 parent 484784c commit 93da846
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 16 deletions.
2 changes: 1 addition & 1 deletion pkg/modbus/configmap/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ type ModbusVisitorConfig struct {
Register string `json:"register"`
Offset uint16 `json:"offset"`
Limit int `json:"limit"`
Scale int `json:"scale,omitempty"`
Scale float64 `json:"scale,omitempty"`
IsSwap bool `json:"isSwap,omitempty"`
IsRegisterSwap bool `json:"isRegisterSwap,omitempty"`
}
Expand Down
12 changes: 4 additions & 8 deletions pkg/modbus/device/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,9 @@ func initTwin(dev *globals.ModbusDev) {
twinData := TwinData{Client: dev.ModbusClient,
Name: dev.Instance.Twins[i].PropertyName,
Type: dev.Instance.Twins[i].Desired.Metadatas.Type,
RegisterType: visitorConfig.Register,
Address: visitorConfig.Offset,
Quantity: uint16(visitorConfig.Limit),
VisitorConfig: &visitorConfig,
Topic: fmt.Sprintf(common.TopicTwinUpdate, dev.Instance.ID)}
collectCycle := time.Duration(dev.Instance.Twins[i].PVisitor.CollectCycle)
collectCycle := time.Duration(dev.Instance.Twins[i].PVisitor.CollectCycle * 1e6)
// If the collect cycle is not set, set it to 1 second.
if collectCycle == 0 {
collectCycle = 1 * time.Second
Expand All @@ -194,11 +192,9 @@ func initData(dev *globals.ModbusDev) {
twinData := TwinData{Client: dev.ModbusClient,
Name: dev.Instance.Datas.Properties[i].PropertyName,
Type: dev.Instance.Datas.Properties[i].Metadatas.Type,
RegisterType: visitorConfig.Register,
Address: visitorConfig.Offset,
Quantity: uint16(visitorConfig.Limit),
VisitorConfig: &visitorConfig,
Topic: fmt.Sprintf(common.TopicDataUpdate, dev.Instance.ID)}
collectCycle := time.Duration(dev.Instance.Datas.Properties[i].PVisitor.CollectCycle)
collectCycle := time.Duration(dev.Instance.Datas.Properties[i].PVisitor.CollectCycle * 1e6)
// If the collect cycle is not set, set it to 1 second.
if collectCycle == 0 {
collectCycle = 1 * time.Second
Expand Down
125 changes: 118 additions & 7 deletions pkg/modbus/device/twindata.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@ package device
import (
"strconv"
"strings"
"bytes"
"encoding/binary"
"errors"
"math"

"github.com/kubeedge/mappers-go/pkg/common"
"github.com/kubeedge/mappers-go/pkg/modbus/driver"
"github.com/kubeedge/mappers-go/pkg/modbus/globals"
"github.com/kubeedge/kubeedge/mappers/modbus-go/configmap"
"k8s.io/klog/v2"
)

Expand All @@ -31,30 +36,35 @@ type TwinData struct {
Client *driver.ModbusClient
Name string
Type string
RegisterType string
Address uint16
Quantity uint16
VisitorConfig *configmap.ModbusVisitorConfig
Results []byte
Topic string
}

// Run timer function.
func (td *TwinData) Run() {
var err error
td.Results, err = td.Client.Get(td.RegisterType, td.Address, td.Quantity)
td.Results, err = td.Client.Get(td.VisitorConfig.Register,
td.VisitorConfig.Offset, uint16(td.VisitorConfig.Limit))
if err != nil {
klog.Error("Get register failed: ", err)
return
}
// transfer data according to the dpl configuration
sData, err := TransferData(td, td.Results)
if err != nil {
klog.Error("Transfer Data failed: ", err)
return
}
// construct payload
var payload []byte
if strings.Contains(td.Topic, "$hw") {
if payload, err = common.CreateMessageTwinUpdate(td.Name, td.Type, strconv.Itoa(int(td.Results[0]))); err != nil {
if payload, err = common.CreateMessageTwinUpdate(td.Name, td.Type, sData); err != nil {
klog.Error("Create message twin update failed")
return
}
} else {
if payload, err = common.CreateMessageData(td.Name, td.Type, strconv.Itoa(int(td.Results[0]))); err != nil {
if payload, err = common.CreateMessageData(td.Name, td.Type, sData); err != nil {
klog.Error("Create message data failed")
return
}
Expand All @@ -63,5 +73,106 @@ func (td *TwinData) Run() {
klog.Error(err)
}

klog.V(2).Infof("Update value: %s, topic: %s", strconv.Itoa(int(td.Results[0])), td.Topic)
klog.V(2).Infof("Update value: %s, topic: %s", sData, td.Topic)
}

func TransferBytes(isRegisterSwap bool, isSwap bool, value []byte) []byte {

if isRegisterSwap && isSwap {
for i := 0; i < len(value)/2; i++ {
j := len(value) - i - 1
value[i], value[j] = value[j], value[i]
}
} else if isRegisterSwap {
for i := 0; i < len(value)/2; i = i+2 {
j := len(value)-i-2
value[i], value[j] = value[j], value[i]
value[i+1], value[j+1] = value[j+1], value[i]
}
} else if isSwap {
for i := 0; i < len(value)/2; i++ {
j := i*2 + 1
value[i*2], value[j] = value[j], value[i*2]
}
}

return value
}

func TransferData(td *TwinData, value []byte) (string, error) {

// accord IsSwap/IsRegisterSwap to transfer byte array
TransferBytes(td.VisitorConfig.IsRegisterSwap, td.VisitorConfig.IsSwap, value)

byteBuff := bytes.NewBuffer(value)
switch td.Type {
case "int":
switch len(value) {
case 1:
var tmp int8
err := binary.Read(byteBuff, binary.BigEndian, &tmp)
if err != nil {
return "", err
}
data := float64(tmp) * td.VisitorConfig.Scale
sData := strconv.FormatInt(int64(data), 10)
return sData, nil
case 2:
var tmp int16
err := binary.Read(byteBuff, binary.BigEndian, &tmp)
if err != nil {
return "", err
}
data := float64(tmp) * td.VisitorConfig.Scale
sData := strconv.FormatInt(int64(data), 10)
return sData, nil
case 4:
var tmp int32
err := binary.Read(byteBuff, binary.BigEndian, &tmp)
if err != nil {
return "", err
}
data := float64(tmp) * td.VisitorConfig.Scale
sData := strconv.FormatInt(int64(data), 10)
return sData, nil
default:
return "", errors.New("BytesToInt bytes length is invalid")
}
case "double":
if len(value) != 8 {
return "", errors.New("BytesToDouble bytes length is invalid")
} else {
bits := binary.BigEndian.Uint64(value)
data := math.Float64frombits(bits) * td.VisitorConfig.Scale
sData := strconv.FormatFloat(data,'f', 6, 64)
return sData, nil
}
case "float":
if len(value) != 4 {
return "", errors.New("BytesToFloat bytes length is invalid")
} else {
bits := binary.BigEndian.Uint32(value)
data := float64(math.Float32frombits(bits)) * td.VisitorConfig.Scale
sData := strconv.FormatFloat(data,'f', 6, 64)
return sData, nil
}
case "boolean":
var data bool
err := binary.Read(byteBuff, binary.BigEndian, &data)
if err != nil {
return "", err
}
sData := strconv.FormatBool(data)
return sData, nil
case "string":
var data string
err := binary.Read(byteBuff, binary.BigEndian, &data)
if err != nil {
return "", err
}
return data, nil
default:
return "", errors.New("Data type is not support")
}
}

0 comments on commit 93da846

Please sign in to comment.