mirror of
https://github.com/jpeletier/koolnova2mqtt.git
synced 2026-04-20 11:40:12 +00:00
try to work around timeouts
This commit is contained in:
62
kn/bridge.go
62
kn/bridge.go
@@ -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 {
|
||||
|
||||
@@ -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
13
main.go
@@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user