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  }