Don't persist Z2M state with "zero" values

When storing Z2M state, skip properties with default "zero" values. This
should skip devices and properties that were not updated via MQTT yet.
This commit is contained in:
Darell Tan
2023-05-14 02:09:17 +08:00
parent 5c47a410cf
commit e44f33aa29
2 changed files with 48 additions and 5 deletions

View File

@@ -11,6 +11,7 @@ import (
"fmt" "fmt"
"log" "log"
"net/http" "net/http"
"reflect"
"strings" "strings"
"sync" "sync"
"time" "time"
@@ -196,6 +197,11 @@ func (br *Bridge) saveZ2MState() error {
devState := make(map[string]any) devState := make(map[string]any)
for prop, mapping := range dev.Mappings { for prop, mapping := range dev.Mappings {
// don't bother persisting property if it is "zero"
if reflect.ValueOf(mapping.Characteristic.Val).IsZero() {
continue
}
v, err := mapping.ToExposedValue(mapping.Characteristic.Val) v, err := mapping.ToExposedValue(mapping.Characteristic.Val)
if err != nil { if err != nil {
return err return err
@@ -205,12 +211,19 @@ func (br *Bridge) saveZ2MState() error {
} }
// serialize into JSON // serialize into JSON
jsonState, err := json.Marshal(devState) if len(devState) > 0 {
if err != nil { jsonState, err := json.Marshal(devState)
return err if err != nil {
} return err
}
devices[name] = jsonState devices[name] = jsonState
}
}
// return early if there was nothing to persist
if len(devices) == 0 {
return nil
} }
allJson, err := json.Marshal(devices) allJson, err := json.Marshal(devices)

View File

@@ -31,6 +31,15 @@ const ContactSensorTemplate = `
} }
}` }`
func fileSize(path string) (int64, error) {
fi, err := os.Stat(path)
sz := int64(0)
if err == nil {
sz = fi.Size()
}
return sz, err
}
func TestBridgePersistState(t *testing.T) { func TestBridgePersistState(t *testing.T) {
dir, err := os.MkdirTemp("", "hapz2m-bridge*") dir, err := os.MkdirTemp("", "hapz2m-bridge*")
if err != nil { if err != nil {
@@ -64,6 +73,27 @@ func TestBridgePersistState(t *testing.T) {
t.Errorf("can't persist state: %v", err) t.Errorf("can't persist state: %v", err)
} }
storeFname := dir + string(os.PathSeparator) + Z2M_STATE_STORE
if sz, err := fileSize(storeFname); err == nil && sz != 0 {
t.Errorf("expecting defaults to not be persisted, but got size %d, err %v", sz, err)
}
// alter sensor states to non-defaults
for _, dev := range b.devices {
dev.Mappings["contact"].Characteristic.Val = 1
}
// save 2 devices, again
t.Logf("persisting state with non-defaults")
if err := b.saveZ2MState(); err != nil {
t.Errorf("can't persist state: %v", err)
}
if sz, err := fileSize(storeFname); err != nil || sz == 0 {
t.Errorf("expecting state to be persisted, but got size %d, err %v", sz, err)
}
// re-create with less devices // re-create with less devices
b2 := NewBridge(ctx, dir) b2 := NewBridge(ctx, dir)
b2.AddDevicesFromJSON(fmt.Appendf(nil, "[%s]", s1)) b2.AddDevicesFromJSON(fmt.Appendf(nil, "[%s]", s1))