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  }