github.com/stampzilla/stampzilla-go@v2.0.0-rc9+incompatible/nodes/stampzilla-modbus/main.go (about) 1 package main 2 3 import ( 4 "bytes" 5 "encoding/binary" 6 "encoding/json" 7 "log" 8 "time" 9 10 "github.com/sirupsen/logrus" 11 "github.com/stampzilla/stampzilla-go/nodes/stampzilla-server/models/devices" 12 "github.com/stampzilla/stampzilla-go/pkg/node" 13 ) 14 15 // MAIN - This is run when the init function is done 16 func main() { 17 node := node.New("modbus") 18 config := NewConfig() 19 20 node.OnConfig(updatedConfig(config)) 21 wait := node.WaitForFirstConfig() 22 23 err := node.Connect() 24 if err != nil { 25 logrus.Error(err) 26 return 27 } 28 logrus.Info("Waiting for config from server") 29 err = wait() 30 if err != nil { 31 logrus.Error(err) 32 return 33 } 34 35 modbusConnection := &Modbus{} 36 logrus.Infof("Connecting to modbus device: %s", config.Device) 37 err = modbusConnection.Connect() 38 39 if err != nil { 40 logrus.Error("error connecting to modbus: ", err) 41 return 42 } 43 44 defer modbusConnection.Close() 45 46 results, _ := modbusConnection.ReadInputRegister(214) 47 log.Println("REG_HC_TEMP_IN1: ", results) 48 results, _ = modbusConnection.ReadInputRegister(215) 49 log.Println("REG_HC_TEMP_IN2: ", results) 50 results, _ = modbusConnection.ReadInputRegister(216) 51 log.Println("REG_HC_TEMP_IN3: ", results) 52 results, _ = modbusConnection.ReadInputRegister(217) 53 log.Println("REG_HC_TEMP_IN4: ", results) 54 results, _ = modbusConnection.ReadInputRegister(218) 55 log.Println("REG_HC_TEMP_IN5: ", binary.BigEndian.Uint16(results)) 56 results, _ = modbusConnection.ReadInputRegister(207) 57 log.Println("REG_HC_TEMP_LVL: ", results) 58 results, _ = modbusConnection.ReadInputRegister(301) 59 log.Println("REG_DAMPER_PWM: ", results) 60 results, _ = modbusConnection.ReadInputRegister(204) 61 log.Println("REG_HC_WC_SIGNAL: ", results) 62 results, _ = modbusConnection.ReadInputRegister(209) 63 log.Println("REG_HC_TEMP_LVL1-5: ", results) 64 results, _ = modbusConnection.ReadInputRegister(101) 65 log.Println("100 REG_FAN_SPEED_LEVEL: ", results) 66 67 //connection := basenode.Connect() 68 dev := &devices.Device{ 69 Name: "modbusDevice", 70 Type: "sensor", //TODO if we add modbus write support we need to have another type 71 ID: devices.ID{ID: "1"}, 72 Online: true, 73 Traits: []string{}, 74 State: make(devices.State), 75 } 76 77 node.AddOrUpdate(dev) 78 79 //node.SetState(registers) 80 81 // This worker recives all incomming commands 82 ticker := time.NewTicker(30 * time.Second) 83 for { 84 select { 85 case <-ticker.C: 86 if len(config.Registers) == 0 { 87 logrus.Info("no configured registers to poll yet") 88 continue 89 } 90 fetchRegisters(config.Registers, modbusConnection) 91 92 for _, v := range config.Registers { 93 dev.State[v.Name] = v.Value 94 } 95 node.SyncDevices() 96 case <-node.Stopped(): 97 ticker.Stop() 98 log.Println("Stopping modbus node") 99 return 100 } 101 } 102 } 103 104 func updatedConfig(config *Config) func(data json.RawMessage) error { 105 return func(data json.RawMessage) error { 106 return json.Unmarshal(data, config) 107 } 108 } 109 110 func fetchRegisters(registers Registers, connection *Modbus) { 111 for _, v := range registers { 112 113 data, err := connection.ReadInputRegister(v.Id) 114 if err != nil { 115 /* 116 if connection.handler.Logger == nil { 117 log.Println("Adding debug logging to handler") 118 connection.handler.Logger = log.New(os.Stdout, "modbus-debug: ", log.LstdFlags) 119 } 120 */ 121 logrus.Error(err) 122 continue 123 } 124 if len(data) != 2 { 125 logrus.Error("Wrong length, expected 2") 126 continue 127 } 128 if v.Base != 0 { 129 v.Value = decode(data) / float64(v.Base) 130 continue 131 } 132 v.Value = decode(data) 133 } 134 } 135 136 func decode(data []byte) float64 { 137 var i int16 138 buf := bytes.NewBuffer(data) 139 binary.Read(buf, binary.BigEndian, &i) 140 return float64(i) 141 }