github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/triggers/state_change.go (about) 1 // This file is part of the Smart Home 2 // Program complex distribution https://github.com/e154/smart-home 3 // Copyright (C) 2016-2023, Filippov Alex 4 // 5 // This library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU Lesser General Public 7 // License as published by the Free Software Foundation; either 8 // version 3 of the License, or (at your option) any later version. 9 // 10 // This library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 // Library General Public License for more details. 14 // 15 // You should have received a copy of the GNU Lesser General Public 16 // License along with this library. If not, see 17 // <https://www.gnu.org/licenses/>. 18 19 // EventStateChanged 20 21 package triggers 22 23 import ( 24 "sync" 25 26 "go.uber.org/atomic" 27 28 "github.com/e154/smart-home/common/events" 29 "github.com/e154/smart-home/system/bus" 30 ) 31 32 const ( 33 // StateChangeName ... 34 StateChangeName = "state_change" 35 // StateChangeFunctionName ... 36 StateChangeFunctionName = "automationTriggerStateChanged" 37 ) 38 39 var _ ITrigger = (*StateChangeTrigger)(nil) 40 41 // StateChangeTrigger ... 42 type StateChangeTrigger struct { 43 baseTrigger 44 counter *atomic.Int32 45 } 46 47 // NewStateChangedTrigger ... 48 func NewStateChangedTrigger(eventBus bus.Bus) ITrigger { 49 return &StateChangeTrigger{ 50 baseTrigger: baseTrigger{ 51 eventBus: eventBus, 52 msgQueue: bus.NewBus(), 53 functionName: StateChangeFunctionName, 54 name: StateChangeName, 55 }, 56 counter: atomic.NewInt32(0), 57 } 58 } 59 60 // AsyncAttach ... 61 func (t *StateChangeTrigger) AsyncAttach(wg *sync.WaitGroup) { 62 63 if err := t.eventBus.Subscribe("system/entities/+", t.eventHandler); err != nil { 64 log.Error(err.Error()) 65 } 66 67 wg.Done() 68 } 69 70 func (t *StateChangeTrigger) eventHandler(_ string, event interface{}) { 71 if t.counter.Load() <= 0 { 72 return 73 } 74 switch v := event.(type) { 75 case events.EventStateChanged: 76 message := TriggerStateChangedMessage{ 77 StorageSave: v.StorageSave, 78 DoNotSaveMetric: v.DoNotSaveMetric, 79 PluginName: v.PluginName, 80 EntityId: v.EntityId, 81 OldState: EventEntityState{ 82 EntityId: v.OldState.EntityId, 83 Value: v.OldState.Value, 84 State: v.OldState.State, 85 Attributes: v.OldState.Attributes.Serialize(), 86 Settings: v.OldState.Settings.Serialize(), 87 LastChanged: v.OldState.LastChanged, 88 LastUpdated: v.OldState.LastUpdated, 89 }, 90 NewState: EventEntityState{ 91 EntityId: v.NewState.EntityId, 92 Value: v.NewState.Value, 93 State: v.NewState.State, 94 Attributes: v.NewState.Attributes.Serialize(), 95 Settings: v.NewState.Settings.Serialize(), 96 LastChanged: v.NewState.LastChanged, 97 LastUpdated: v.NewState.LastUpdated, 98 }, 99 } 100 t.msgQueue.Publish(v.EntityId.String(), message) 101 } 102 } 103 104 // Subscribe ... 105 func (t *StateChangeTrigger) Subscribe(options Subscriber) error { 106 //log.Infof("subscribe topic %s", options.EntityId) 107 t.counter.Inc() 108 return t.msgQueue.Subscribe(options.EntityId.String(), options.Handler) 109 } 110 111 // Unsubscribe ... 112 func (t *StateChangeTrigger) Unsubscribe(options Subscriber) error { 113 //log.Infof("unsubscribe topic %s", options.EntityId) 114 t.counter.Dec() 115 return t.msgQueue.Unsubscribe(options.EntityId.String(), options.Handler) 116 }