Fix for unacknowledged numeric Z2M state updates

So far Z2M state updates were only boolean (the device `state` on/off),
but after introducing `brightness` values, Z2M state updates may not be
recognized/acknowledged. Unmarshalled Z2M numeric values are always
float64, but updates sent out via MQTT might not be. As a result, the
values may not directly equal and may never match.

To solve this, cast the outgoing expected value into a float64 to
compare against the received Z2M value, which is already a float64.
This commit is contained in:
Darell Tan
2023-06-25 02:34:34 +08:00
parent c61da984c9
commit 54aa0795c3

View File

@@ -466,7 +466,10 @@ wait:
if BRIDGE_DEBUG {
log.Printf("received value %q (expected %q) for %s", updatedVal, expVal, key)
}
if updatedVal == expVal {
if updatedVal == expVal ||
// updatedVal is float64 coz that's how Z2M JSON values are, but expVal may not be
mapping.ExposesEntry.Type == "numeric" && cmpFloat64Numeric(updatedVal, expVal) {
updated = true
break wait
}
@@ -485,6 +488,17 @@ wait:
return updated, err
}
// Compare float64 f to numeric value n
// Both parameters are marked as `any`. f will be type-asserted to float64,
// whereas n will be converted to float64 before doing the comparison.
func cmpFloat64Numeric(f, n any) bool {
if ff, ok := f.(float64); ok {
nn, ok := valToFloat64(n)
return ff == nn && ok
}
return false
}
// Publish to the MQTT broker for the specific device
func (br *Bridge) PublishState(dev *Device, payload map[string]any) error {
topic := MQTT_TOPIC_PREFIX + dev.FriendlyName + "/set"