Add FLOAT64-IEEE support to inputs.modbus (#8361) (by @Nemecsek) (#8474)

This commit is contained in:
SoerMan 2020-11-30 22:22:57 +01:00 committed by GitHub
parent 01fc69da47
commit 05378980a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 75 additions and 6 deletions

View File

@ -67,7 +67,7 @@ Registers via Modbus TCP or Modbus RTU/ASCII.
## |---BA, DCBA - Little Endian ## |---BA, DCBA - Little Endian
## |---BADC - Mid-Big Endian ## |---BADC - Mid-Big Endian
## |---CDAB - Mid-Little Endian ## |---CDAB - Mid-Little Endian
## data_type - INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32-IEEE (the IEEE 754 binary representation) ## data_type - INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32-IEEE, FLOAT64-IEEE (the IEEE 754 binary representation)
## FLOAT32 (deprecated), FIXED, UFIXED (fixed-point representation on input) ## FLOAT32 (deprecated), FIXED, UFIXED (fixed-point representation on input)
## scale - the final numeric variable representation ## scale - the final numeric variable representation
## address - variable address ## address - variable address
@ -105,10 +105,10 @@ and cannot be configured.
These types are used for integer input values. Select the one that matches your modbus data source. These types are used for integer input values. Select the one that matches your modbus data source.
#### Floating Point: `FLOAT32-IEEE` #### Floating Point: `FLOAT32-IEEE`, `FLOAT64-IEEE`
Use this type if your modbus registers contain a value that is encoded in this format. This type Use these types if your modbus registers contain a value that is encoded in this format. These types
always includes the sign and therefore there exists no variant. always include the sign and therefore there exists no variant.
#### Fixed Point: `FIXED`, `UFIXED` (`FLOAT32`) #### Fixed Point: `FIXED`, `UFIXED` (`FLOAT32`)

View File

@ -132,7 +132,8 @@ const sampleConfig = `
## |---BA, DCBA - Little Endian ## |---BA, DCBA - Little Endian
## |---BADC - Mid-Big Endian ## |---BADC - Mid-Big Endian
## |---CDAB - Mid-Little Endian ## |---CDAB - Mid-Little Endian
## data_type - INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT32-IEEE (the IEEE 754 binary representation) ## data_type - INT16, UINT16, INT32, UINT32, INT64, UINT64,
## FLOAT32-IEEE, FLOAT64-IEEE (the IEEE 754 binary representation)
## FLOAT32, FIXED, UFIXED (fixed-point representation on input) ## FLOAT32, FIXED, UFIXED (fixed-point representation on input)
## scale - the final numeric variable representation ## scale - the final numeric variable representation
## address - variable address ## address - variable address
@ -355,7 +356,7 @@ func validateFieldContainers(t []fieldContainer, n string) error {
// search data type // search data type
switch item.DataType { switch item.DataType {
case "UINT16", "INT16", "UINT32", "INT32", "UINT64", "INT64", "FLOAT32-IEEE", "FLOAT32", "FIXED", "UFIXED": case "UINT16", "INT16", "UINT32", "INT32", "UINT64", "INT64", "FLOAT32-IEEE", "FLOAT64-IEEE", "FLOAT32", "FIXED", "UFIXED":
break break
default: default:
return fmt.Errorf("invalid data type '%s' in '%s' - '%s'", item.DataType, n, item.Name) return fmt.Errorf("invalid data type '%s' in '%s' - '%s'", item.DataType, n, item.Name)
@ -512,6 +513,10 @@ func convertDataType(t fieldContainer, bytes []byte) interface{} {
e32 := convertEndianness32(t.ByteOrder, bytes) e32 := convertEndianness32(t.ByteOrder, bytes)
f32 := math.Float32frombits(e32) f32 := math.Float32frombits(e32)
return scaleFloat32(t.Scale, f32) return scaleFloat32(t.Scale, f32)
case "FLOAT64-IEEE":
e64 := convertEndianness64(t.ByteOrder, bytes)
f64 := math.Float64frombits(e64)
return scaleFloat64(t.Scale, f64)
case "FIXED": case "FIXED":
if len(bytes) == 2 { if len(bytes) == 2 {
e16 := convertEndianness16(t.ByteOrder, bytes) e16 := convertEndianness16(t.ByteOrder, bytes)
@ -662,6 +667,10 @@ func scaleFloat32(s float64, v float32) float32 {
return float32(float64(v) * s) return float32(float64(v) * s)
} }
func scaleFloat64(s float64, v float64) float64 {
return v * s
}
func scaleUint64(s float64, v uint64) uint64 { func scaleUint64(s float64, v uint64) uint64 {
return uint64(float64(v) * float64(s)) return uint64(float64(v) * float64(s))
} }

View File

@ -549,6 +549,66 @@ func TestHoldingRegisters(t *testing.T) {
write: []byte{0xF6, 0x84, 0xF9, 0x45, 0xFE, 0xBC, 0xFF, 0xFF}, write: []byte{0xF6, 0x84, 0xF9, 0x45, 0xFE, 0xBC, 0xFF, 0xFF},
read: uint64(18446742686322259968), read: uint64(18446742686322259968),
}, },
{
name: "register214_to_register217_abcdefgh_float64_ieee",
address: []uint16{214, 215, 216, 217},
quantity: 4,
byteOrder: "ABCDEFGH",
dataType: "FLOAT64-IEEE",
scale: 1,
write: []byte{0xBF, 0x9C, 0x6A, 0x40, 0xC3, 0x47, 0x8F, 0x55},
read: float64(-0.02774907295123737),
},
{
name: "register214_to_register217_abcdefgh_float64_ieee_scaled",
address: []uint16{214, 215, 216, 217},
quantity: 4,
byteOrder: "ABCDEFGH",
dataType: "FLOAT64-IEEE",
scale: 0.1,
write: []byte{0xBF, 0x9C, 0x6A, 0x40, 0xC3, 0x47, 0x8F, 0x55},
read: float64(-0.002774907295123737),
},
{
name: "register218_to_register221_abcdefgh_float64_ieee_pos",
address: []uint16{218, 219, 220, 221},
quantity: 4,
byteOrder: "ABCDEFGH",
dataType: "FLOAT64-IEEE",
scale: 1,
write: []byte{0x3F, 0x9C, 0x6A, 0x40, 0xC3, 0x47, 0x8F, 0x55},
read: float64(0.02774907295123737),
},
{
name: "register222_to_register225_hgfecdba_float64_ieee",
address: []uint16{222, 223, 224, 225},
quantity: 4,
byteOrder: "HGFEDCBA",
dataType: "FLOAT64-IEEE",
scale: 1,
write: []byte{0x55, 0x8F, 0x47, 0xC3, 0x40, 0x6A, 0x9C, 0xBF},
read: float64(-0.02774907295123737),
},
{
name: "register226_to_register229_badcfehg_float64_ieee",
address: []uint16{226, 227, 228, 229},
quantity: 4,
byteOrder: "BADCFEHG",
dataType: "FLOAT64-IEEE",
scale: 1,
write: []byte{0x9C, 0xBF, 0x40, 0x6A, 0x47, 0xC3, 0x55, 0x8F},
read: float64(-0.02774907295123737),
},
{
name: "register230_to_register233_ghefcdab_float64_ieee",
address: []uint16{230, 231, 232, 233},
quantity: 4,
byteOrder: "GHEFCDAB",
dataType: "FLOAT64-IEEE",
scale: 1,
write: []byte{0x8F, 0x55, 0xC3, 0x47, 0x6A, 0x40, 0xBF, 0x9C},
read: float64(-0.02774907295123737),
},
} }
serv := mbserver.NewServer() serv := mbserver.NewServer()