From 54aa0795c3cbd81c1a23af15ecf6911bb7830a31 Mon Sep 17 00:00:00 2001 From: Darell Tan Date: Sun, 25 Jun 2023 02:34:34 +0800 Subject: [PATCH] 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. --- bridge.go | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/bridge.go b/bridge.go index 8d06eb8..783c634 100644 --- a/bridge.go +++ b/bridge.go @@ -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"