mirror of
https://github.com/nikdoof/hapz2m.git
synced 2026-01-30 04:38:20 +00:00
Introduce SetCharacteristicValueFunc to the Mapping
This function allows either replacing or modifying the usual Exposed->Characteristic value propagation. It also adds a CurrentValue to the mapping to monitor for changes/updates, regardless of whether the value was updated into the Characteristic. This will be the source of truth.
This commit is contained in:
27
bridge.go
27
bridge.go
@@ -697,9 +697,34 @@ func (br *Bridge) UpdateAccessoryState(devName string, payload []byte) {
|
||||
if BRIDGE_DEVMODE {
|
||||
log.Printf("updating %q to %+v", prop, newVal)
|
||||
}
|
||||
_, errCode := mapping.SetCharacteristicValue(newVal)
|
||||
|
||||
// convert to Characteristic value to determine if it has changed
|
||||
// since we don't know what the Exposed -> Characteristic mapping would be
|
||||
newCv, err := mapping.ToCharacteristicValue(newVal)
|
||||
if err != nil {
|
||||
log.Printf("unable to convert characteristic value for %q: %v", prop, err)
|
||||
continue
|
||||
}
|
||||
|
||||
oldCv := mapping.SetCurrentValue(newCv)
|
||||
changed := oldCv != newCv
|
||||
|
||||
// call the Set func if defined
|
||||
doDefault := true
|
||||
setFunc := mapping.SetCharacteristicValueFunc
|
||||
if setFunc != nil {
|
||||
doDefault, err = setFunc(mapping, newCv, changed)
|
||||
if err != nil {
|
||||
log.Printf("SetCharacteristicValueFunc for %s error: %+v", mapping, err)
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
if doDefault {
|
||||
_, errCode := mapping.Characteristic.SetValueRequest(newCv, nil)
|
||||
if errCode != 0 {
|
||||
log.Printf("unable to update characteristic value for %q: %d", prop, errCode)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
42
z2m.go
42
z2m.go
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"reflect"
|
||||
"runtime"
|
||||
@@ -228,6 +229,9 @@ func uniq[T comparable](items []T) []T {
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// sentinel nil value for atomic.Value
|
||||
var nilValue = &struct{}{}
|
||||
|
||||
// Maps a zigbee2mqtt device property into a HAP characteristic.
|
||||
// Contains convenience methods to translate values between the two systems.
|
||||
// z2m "binary" types are inherently translated to bool using the ValueOn/Off properties defined,
|
||||
@@ -240,6 +244,15 @@ type ExposeMapping struct {
|
||||
Characteristic *characteristic.C
|
||||
|
||||
Translator MappingTranslator
|
||||
|
||||
// Hook function for setting Characteristic value.
|
||||
// It returns a bool to allow/prevent the normal setting of Characteristic value.
|
||||
// If an error is returned, the handler stops any further processing for this mapping.
|
||||
SetCharacteristicValueFunc func(m *ExposeMapping, newVal any, changed bool) (doDefault bool, err error)
|
||||
|
||||
// keeps track of current value, regardless of whether it's been
|
||||
// transferred to Characteristic or not
|
||||
currentVal atomic.Value
|
||||
}
|
||||
|
||||
// Creates a new ExposeMapping
|
||||
@@ -262,6 +275,11 @@ func (m *ExposeMapping) ToExposedValue(v any) (any, error) {
|
||||
return m.Translator.ToExposedValue(v)
|
||||
}
|
||||
|
||||
// Converts an Exposed value to a Characteristic value
|
||||
func (m *ExposeMapping) ToCharacteristicValue(v any) (any, error) {
|
||||
return m.Translator.ToCharacteristicValue(v)
|
||||
}
|
||||
|
||||
// Calls c.SetValueRequest() with the translated exposed value
|
||||
// if the error code is -1, there was a translation error.
|
||||
// Otherwise it's a HAP error code
|
||||
@@ -274,6 +292,30 @@ func (m *ExposeMapping) SetCharacteristicValue(v any) (any, int) {
|
||||
return m.Characteristic.SetValueRequest(cv, nil)
|
||||
}
|
||||
|
||||
// Gets the current value
|
||||
func (m *ExposeMapping) CurrentValue() any {
|
||||
v := m.currentVal.Load()
|
||||
if v == nilValue {
|
||||
return nil
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// Sets the current value for this mapping.
|
||||
// This value is persisted and used for detecting changes, regardless of
|
||||
// whether it is propagated to the Characteristic
|
||||
func (m *ExposeMapping) SetCurrentValue(v any) any {
|
||||
if v == nil {
|
||||
v = nilValue
|
||||
}
|
||||
|
||||
old := m.currentVal.Swap(v)
|
||||
if old == nilValue {
|
||||
old = nil
|
||||
}
|
||||
return old
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
|
||||
// Function that creates services from a z2m Device, invoked by createAccessory()
|
||||
|
||||
Reference in New Issue
Block a user