102 lines
2.2 KiB
Go
102 lines
2.2 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"time"
|
||
|
|
||
|
"github.com/simonvetter/modbus"
|
||
|
)
|
||
|
|
||
|
func modbusValuesToFloat(v uint16) float32 {
|
||
|
return float32(v) / 10.0
|
||
|
}
|
||
|
|
||
|
func (d *daemon) modbusConnect() error {
|
||
|
var err error
|
||
|
|
||
|
d.mu.Lock()
|
||
|
defer d.mu.Unlock()
|
||
|
|
||
|
// Setup modbus client
|
||
|
d.modbusClient, err = modbus.NewClient(&modbus.ClientConfiguration{
|
||
|
URL: "tcp://10.250.241.20:8887",
|
||
|
Timeout: 5 * time.Second,
|
||
|
})
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
// Connect to modbus client
|
||
|
err = d.modbusClient.Open()
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// There are currently two devices connected to the modbus.
|
||
|
// The first one (slave 1) is a temperature/humidity sensor.
|
||
|
// The second one (slave 2) is a PTA8D08 transmitter
|
||
|
func (d *daemon) modbusUpdate() error {
|
||
|
d.mu.Lock()
|
||
|
defer d.mu.Unlock()
|
||
|
|
||
|
var err error
|
||
|
var registers []uint16 // temperature, humidity
|
||
|
|
||
|
// Switch to slave 1
|
||
|
d.modbusClient.SetUnitId(1)
|
||
|
|
||
|
// Read temperature and humidity
|
||
|
registers, err = d.modbusClient.ReadRegisters(1, 2, modbus.INPUT_REGISTER)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(registers) != 2 {
|
||
|
msg := fmt.Sprintf("Expected two registers from modbus slave 1, but got %d", len(registers))
|
||
|
return errors.New(msg)
|
||
|
}
|
||
|
|
||
|
d.daemonState.tempSEM = modbusValuesToFloat(registers[0])
|
||
|
d.daemonState.humiditySEM = modbusValuesToFloat(registers[1])
|
||
|
|
||
|
// Switch to slave 2
|
||
|
d.modbusClient.SetUnitId(2)
|
||
|
|
||
|
// PT100 mapping
|
||
|
// Channel 0: Cable -WGA6, Sensor "dp bottom"
|
||
|
// Channel 1: Cable -WGA8, Sensor "dp inlet"
|
||
|
// Channel 2: Cable WGA7, Sensor "dp top"
|
||
|
registers, err = d.modbusClient.ReadRegisters(0, 3, modbus.HOLDING_REGISTER)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
|
||
|
if len(registers) != 3 {
|
||
|
msg := fmt.Sprintf("Expected three registers from modbus slave 2, but got %d", len(registers))
|
||
|
return errors.New(msg)
|
||
|
}
|
||
|
|
||
|
d.daemonState.tempDPBottom = modbusValuesToFloat(registers[0])
|
||
|
d.daemonState.tempDPInlet = modbusValuesToFloat(registers[1])
|
||
|
d.daemonState.tempDPTop = modbusValuesToFloat(registers[2])
|
||
|
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Call modbusUpdate every second
|
||
|
func (d *daemon) modbusProcess(ctx context.Context) {
|
||
|
for {
|
||
|
select {
|
||
|
case <-ctx.Done():
|
||
|
return
|
||
|
default:
|
||
|
d.modbusUpdate()
|
||
|
time.Sleep(time.Second * 1)
|
||
|
}
|
||
|
}
|
||
|
}
|