try to work around timeouts

This commit is contained in:
Javier Peletier
2020-12-16 21:47:55 +01:00
parent 9c7b5313e3
commit d9edc624fe
5 changed files with 64 additions and 49 deletions

View File

@@ -34,62 +34,56 @@ func getActiveZones(w Watcher) ([]*Zone, error) {
for n := 0; n < NUM_ZONES; n++ {
zone := NewZone(&ZoneConfig{
ZoneNumber: n,
ZoneNumber: n + 1,
Watcher: w,
})
isPresent := zone.IsPresent()
if isPresent {
zones = append(zones, zone)
temp := zone.GetCurrentTemperature()
fmt.Printf("Zone %d is present. Temperature %g ºC\n", zone.ZoneNumber, temp)
}
}
return zones, nil
}
func NewBridge(config *Config) *Bridge {
b := &Bridge{
Config: *config,
}
return b
}
func (b *Bridge) Start() error {
zw := watcher.New(&watcher.Config{
Address: FIRST_ZONE_REGISTER,
Quantity: TOTAL_ZONE_REGISTERS,
RegisterSize: 2,
SlaveID: config.SlaveID,
Modbus: config.Modbus,
SlaveID: b.SlaveID,
Modbus: b.Modbus,
})
sysw := watcher.New(&watcher.Config{
Address: FIRST_SYS_REGISTER,
Quantity: TOTAL_SYS_REGISTERS,
RegisterSize: 2,
SlaveID: config.SlaveID,
Modbus: config.Modbus,
SlaveID: b.SlaveID,
Modbus: b.Modbus,
})
b := &Bridge{
Config: *config,
zw: zw,
sysw: sysw,
}
return b
}
func (b *Bridge) Start() error {
b.zw = zw
b.sysw = sysw
sys := NewSys(&SysConfig{
Watcher: b.sysw,
})
err := b.zw.Poll()
log.Printf("Starting bridge for %s\n", b.ModuleName)
err := b.Tick()
if err != nil {
fmt.Println(err)
return err
}
err = b.sysw.Poll()
if err != nil {
fmt.Println(err)
return err
}
zones, err := getActiveZones(b.zw)
log.Printf("%d zones are present in %s\n", len(zones), b.ModuleName)
b.zw.Resize(len(zones) * REG_PER_ZONE)
getHVACMode := func() string {
if !sys.GetSystemEnabled() {
@@ -116,8 +110,6 @@ func (b *Bridge) Start() error {
return "unknown"
}
zones, err := getActiveZones(b.zw)
publishHvacMode := func() {
for _, zone := range zones {
if zone.IsOn() {
@@ -128,11 +120,6 @@ func (b *Bridge) Start() error {
}
}
var hvacModes []string
for k, _ := range KnModes.GetForwardMap() {
hvacModes = append(hvacModes, k.(string))
}
holdModeTopic := b.getSysTopic("holdMode")
holdModeSetTopic := holdModeTopic + "/set"
@@ -297,18 +284,19 @@ func (b *Bridge) Start() error {
return nil
}
func (b *Bridge) Tick() {
func (b *Bridge) Tick() error {
err := b.zw.Poll()
if err != nil {
fmt.Println(err)
return
log.Printf("Timeout polling %s zone registers: %s\n", b.ModuleName, err)
return err
}
err = b.sysw.Poll()
if err != nil {
fmt.Println(err)
return
log.Printf("Timeout polling %s system registers: %s\n", b.ModuleName, err)
return err
}
return nil
}
func (b *Bridge) getZoneTopic(zoneNum int, subtopic string) string {

View File

@@ -63,18 +63,18 @@ func NewZone(config *ZoneConfig) *Zone {
}
func (z *Zone) RegisterCallback(num int, f func()) {
z.Watcher.RegisterCallback(uint16(z.ZoneNumber*REG_PER_ZONE+num), func(address uint16) {
z.Watcher.RegisterCallback(uint16((z.ZoneNumber-1)*REG_PER_ZONE+num), func(address uint16) {
f()
})
}
func (z *Zone) ReadRegister(num int) uint16 {
b := z.Watcher.ReadRegister(uint16(z.ZoneNumber*REG_PER_ZONE + num))
b := z.Watcher.ReadRegister(uint16((z.ZoneNumber-1)*REG_PER_ZONE + num))
return binary.BigEndian.Uint16(b)
}
func (z *Zone) WriteRegister(num int, value uint16) error {
return z.Watcher.WriteRegister(uint16(z.ZoneNumber*REG_PER_ZONE+num), value)
return z.Watcher.WriteRegister(uint16((z.ZoneNumber-1)*REG_PER_ZONE+num), value)
}
func (z *Zone) IsOn() bool {

13
main.go
View File

@@ -143,9 +143,11 @@ func main() {
connOpts.OnConnect = func(c MQTT.Client) {
onConnect = true
}
var started bool
connOpts.OnConnectionLost = func(c MQTT.Client, err error) {
log.Printf("Connection to MQTT server lost: %s\n", err)
mqttClient = nil
started = false
}
connectMQTT := func() error {
@@ -160,8 +162,7 @@ func main() {
return nil
}
ticker := time.NewTicker(time.Second)
ticker := time.NewTicker(2 * time.Second)
go func() {
for range ticker.C {
if mqttClient == nil {
@@ -181,11 +182,15 @@ func main() {
log.Printf("Error starting bridge: %s\n", err)
client.Disconnect(100)
mqttClient = nil
} else {
started = true
}
}
} else {
for _, b := range bridges {
b.Tick()
if started {
for _, b := range bridges {
b.Tick()
}
}
}
}

View File

@@ -36,11 +36,6 @@ func New(config *Config) (Modbus, error) {
handler.StopBits = config.StopBits
handler.Timeout = config.Timeout
err := handler.Connect()
if err != nil {
return nil, err
}
return &modbus{
handler: handler,
client: gmodbus.NewClient(handler),
@@ -55,6 +50,11 @@ func (mb *modbus) ReadRegister(slaveID byte, address uint16, quantity uint16) (r
mb.lock.Lock()
defer mb.lock.Unlock()
mb.handler.SlaveId = slaveID
err = mb.handler.Connect()
if err != nil {
return nil, err
}
defer mb.handler.Close()
results, err = mb.client.ReadHoldingRegisters(address-1, quantity)
return results, err
@@ -64,6 +64,11 @@ func (mb *modbus) WriteRegister(slaveID byte, address uint16, value uint16) (res
mb.lock.Lock()
defer mb.lock.Unlock()
mb.handler.SlaveId = slaveID
err = mb.handler.Connect()
if err != nil {
return nil, err
}
defer mb.handler.Close()
results, err = mb.client.WriteSingleRegister(address-1, value)
return results, err

View File

@@ -117,3 +117,20 @@ func (w *Watcher) TriggerCallbacks() {
callback(address)
}
}
func (w *Watcher) Resize(newQuantity int) {
w.lock.Lock()
defer w.lock.Unlock()
if newQuantity < int(w.Quantity) {
w.state = w.state[:newQuantity*w.RegisterSize]
for address, _ := range w.callbacks {
if address > w.Address+uint16(newQuantity)-1 {
delete(w.callbacks, address)
}
}
} else {
w.state = nil
}
w.Quantity = uint16(newQuantity)
}