github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/modbus_tcp/actor.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 package modbus_tcp 20 21 import ( 22 "fmt" 23 "sync" 24 25 "github.com/pkg/errors" 26 27 "github.com/e154/smart-home/common/events" 28 m "github.com/e154/smart-home/models" 29 "github.com/e154/smart-home/plugins/node" 30 "github.com/e154/smart-home/system/supervisor" 31 ) 32 33 // Actor ... 34 type Actor struct { 35 *supervisor.BaseActor 36 actionPool chan events.EventCallEntityAction 37 stateMu *sync.Mutex 38 } 39 40 // NewActor ... 41 func NewActor(entity *m.Entity, 42 service supervisor.Service) (actor *Actor) { 43 44 actor = &Actor{ 45 BaseActor: supervisor.NewBaseActor(entity, service), 46 actionPool: make(chan events.EventCallEntityAction, 1000), 47 stateMu: &sync.Mutex{}, 48 } 49 50 if actor.Attrs == nil { 51 actor.Attrs = NewAttr() 52 } 53 54 if actor.Setts == nil { 55 actor.Setts = NewSettings() 56 } 57 58 actor.DeserializeAttr(entity.Attributes.Serialize()) 59 60 // Actions 61 for _, a := range actor.Actions { 62 if a.ScriptEngine.Engine() != nil { 63 // bind 64 a.ScriptEngine.PushFunction("ModbusTcp", NewModbusTcp(service.EventBus(), actor)) 65 } 66 } 67 68 if actor.ScriptsEngine != nil { 69 actor.ScriptsEngine.PushFunction("ModbusTcp", NewModbusTcp(service.EventBus(), actor)) 70 } 71 72 // action worker 73 go func() { 74 for msg := range actor.actionPool { 75 actor.runAction(msg) 76 } 77 }() 78 79 return actor 80 } 81 82 func (e *Actor) Destroy() { 83 84 } 85 86 // SetState ... 87 func (e *Actor) SetState(params supervisor.EntityStateParams) error { 88 89 e.SetActorState(params.NewState) 90 e.DeserializeAttr(params.AttributeValues) 91 e.SaveState(false, params.StorageSave) 92 93 return nil 94 } 95 96 func (e *Actor) addAction(event events.EventCallEntityAction) { 97 e.actionPool <- event 98 } 99 100 func (e *Actor) runAction(msg events.EventCallEntityAction) { 101 if action, ok := e.Actions[msg.ActionName]; ok { 102 if action.ScriptEngine != nil && action.ScriptEngine.Engine() != nil { 103 if _, err := action.ScriptEngine.Engine().AssertFunction(FuncEntityAction, e.Id, action.Name, msg.Args); err != nil { 104 log.Error(errors.Wrapf(err, "entity id: %s ", e.Id).Error()) 105 } 106 return 107 } 108 } 109 if e.ScriptsEngine != nil && e.ScriptsEngine.Engine() != nil { 110 if _, err := e.ScriptsEngine.AssertFunction(FuncEntityAction, e.Id, msg.ActionName, msg.Args); err != nil { 111 log.Error(errors.Wrapf(err, "entity id: %s ", e.Id).Error()) 112 } 113 } 114 } 115 116 func (e *Actor) localTopic(r string) string { 117 var parent string 118 if e.ParentId != nil { 119 parent = e.ParentId.Name() 120 } 121 return fmt.Sprintf("%s/%s/%s", node.TopicPluginNode, parent, r) 122 }