Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: supply string type #262

Merged
merged 9 commits into from
Aug 3, 2021
17 changes: 17 additions & 0 deletions cmd/res/devices/modbus.test.devices.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,20 @@
UnitID = '1'
Timeout = "5"
IdleTimeout = "5"

# Pre-define Devices
[[DeviceList]]
Name = 'Modbus TCP Read String'
Profile = 'Test.Device.Modbus.String.Profile'
Description = 'use for auto read a string value'
labels = [ 'modbus TCP' ]
[DeviceList.Protocols]
[DeviceList.Protocols.modbus-tcp]
Address = '0.0.0.0'
Port = '1502'
UnitID = '1'
[[DeviceList.AutoEvents]]
Frequency = '20s'
OnChange = false
Resource = 'ReadString'
hongda3141 marked this conversation as resolved.
Show resolved Hide resolved

41 changes: 41 additions & 0 deletions cmd/res/profiles/modbus.test.device.string.profile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
name: "Test.Device.Modbus.String.Profile"
manufacturer: "no manufacturer"
model: "string value type"
labels:
- "no lable"
description: "this profile is testing string value type with read and write"

deviceResources:
-
name: "StringA"
description: "no description"
attributes:
{ primaryTable: "INPUT_REGISTERS", startingAddress: "1", stringRegisterSize: "1"}
hongda3141 marked this conversation as resolved.
Show resolved Hide resolved
properties:
valueType: "String"
readWrite: "R"

-
name: "StringB"
description: "no description"
attributes:
{ primaryTable: "HOLDING_REGISTERS", startingAddress: "15", stringRegisterSize: "5"}
hongda3141 marked this conversation as resolved.
Show resolved Hide resolved
properties:
valueType: "String"
readWrite: "RW"



deviceCommands:
-
name: "ReadString"
readWrite: "R"
isHidden: false
resourceOperations:
- { deviceResource: "StringA"}
-
name: "WriteString"
readWrite: "RW"
isHidden: false
resourceOperations:
- { deviceResource: "StringB" }
5 changes: 4 additions & 1 deletion internal/driver/constant.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ const (
// RAW_TYPE define binary data type which read from Modbus device
RAW_TYPE = "rawType"

// STRING_REGISTER_SIZE E.g. "abcd" need 4 bytes as is 2 registers(2 words), so STRING_REGISTER_SIZE=2
STRING_REGISTER_SIZE = "stringRegisterSize"
SERVICE_STOP_WAIT_TIME = 1
)

Expand All @@ -58,5 +60,6 @@ var ValueTypeBitCountMap = map[string]uint16{
common.ValueTypeFloat32: 32,
common.ValueTypeFloat64: 64,

common.ValueTypeBool: 1,
common.ValueTypeBool: 1,
common.ValueTypeString: 16,
}
31 changes: 28 additions & 3 deletions internal/driver/deviceclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,17 @@ func createCommandInfo(req *models.CommandRequest) (*CommandInfo, error) {
return nil, err
}
}
length := calculateAddressLength(primaryTable, rawType)
var length uint16
if req.Type == common.ValueTypeString {
length, err = castStartingAddress(req.Attributes[STRING_REGISTER_SIZE])
if err != nil {
return nil, err
} else if (length > 123) || (length < 1) {
return nil, errors.NewCommonEdgeX(errors.KindLimitExceeded, fmt.Sprintf("register size should be within the range of 1~123, get %v.", length), nil)
}
} else {
length = calculateAddressLength(primaryTable, rawType)
}

var isByteSwap = false
if _, ok := req.Attributes[IS_BYTE_SWAP]; ok {
Expand Down Expand Up @@ -157,6 +167,8 @@ func TransformDataBytesToResult(req *models.CommandRequest, dataBytes []byte, co
if (dataBytes[0] & 1) > 0 {
res = true
}
case common.ValueTypeString:
res = string(dataBytes)
default:
return nil, fmt.Errorf("return result fail, none supported value type: %v", commandInfo.ValueType)
}
Expand Down Expand Up @@ -195,7 +207,7 @@ func TransformCommandValueToDataBytes(commandInfo *CommandInfo, value *models.Co
dataBytes = swap32BitDataBytes(dataBytes, commandInfo.IsByteSwap, commandInfo.IsWordSwap)
}

// Cast value according to the rawType, this feature only converts float value to integer 32bit value
// Cast value according to the rawType, this feature converts float value to integer 32bit value
if commandInfo.ValueType == common.ValueTypeFloat32 {
val, edgexErr := value.Float32Value()
if edgexErr != nil {
Expand Down Expand Up @@ -228,8 +240,21 @@ func TransformCommandValueToDataBytes(commandInfo *CommandInfo, value *models.Co
return dataBytes, err
}
}
} else if commandInfo.ValueType == common.ValueTypeString {
// Cast value of string type
oriStr := value.ValueToString()
tempBytes := []byte(oriStr)
bytesL := len(tempBytes)
oriByteL := int(commandInfo.Length * 2)
if bytesL < oriByteL {
less := make([]byte, oriByteL-bytesL)
dataBytes = append(tempBytes, less...)
} else if bytesL > oriByteL {
dataBytes = tempBytes[:oriByteL]
} else {
dataBytes = []byte(oriStr)
}
}

driver.Logger.Debugf("Transfer CommandValue to dataBytes for write command, %v, %v", commandInfo.ValueType, dataBytes)
return dataBytes, err
}
Expand Down