Modbus: add bool16 type and supporting bitmask (#2196)

This commit is contained in:
andig 2022-01-03 19:06:55 +01:00 • committed by GitHub
parent 3bac55c494
commit 20a8acb365
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 1 deletions

View file

@ -1,6 +1,12 @@
package modbus
import "strings"
import (
"encoding/binary"
"encoding/hex"
"fmt"
"strconv"
"strings"
)
// ReadingName formats MBMD reading names
func ReadingName(val string) string {
@ -9,3 +15,42 @@ func ReadingName(val string) string {
}
return val
}
// decodeMask converts a bit mask in decimal or hex format to uint64
func decodeMask(mask string) (uint64, error) {
mask = strings.ToLower(mask)
if strings.HasPrefix(mask, "0x") {
if len(mask) < 3 {
return 0, fmt.Errorf("invalid mask: %s", mask)
}
b, err := hex.DecodeString(mask[2:])
if err != nil {
return 0, fmt.Errorf("invalid mask: %w", err)
}
var u uint64
for _, v := range b {
u = u<<8 | uint64(v)
}
return u, nil
}
return strconv.ParseUint(mask, 10, 64)
}
// decodeBool16 converts a masked uint16 to a bool
func decodeBool16(mask uint64) func(b []byte) float64 {
return func(b []byte) float64 {
u := binary.BigEndian.Uint16(b)
if mask > 0 {
u = u & uint16(mask)
}
if u > 0 {
return 1
}
return 0
}
}

View file

@ -243,6 +243,7 @@ type Register struct {
Address uint16 // Length uint16
Type string
Decode string
BitMask string
}
// RegisterOperation creates a read operation from a register definition
@ -288,6 +289,13 @@ func RegisterOperation(r Register) (rs485.Operation, error) {
op.Transform = rs485.RTUInt32ToFloat64
case "int32s":
op.Transform = rs485.RTUInt32ToFloat64Swapped
case "bool16":
mask, err := decodeMask(r.BitMask)
if err != nil {
return op, err
}
op.Transform = decodeBool16(mask)
op.ReadLen = 1
default:
return rs485.Operation{}, fmt.Errorf("invalid register decoding: %s", r.Decode)
}