heater/pkg/device/device_manager.go

100 lines
2.4 KiB
Go

package device
import (
"fmt"
"context"
"github.com/eclipse/paho.mqtt.golang"
"github.com/rs/zerolog"
)
type Subscriber func(string, int, func(context.Context, mqtt.Message)) context.CancelFunc
type DeviceManager struct {
devices map[string]*Device
subscriber Subscriber
sub_cancel map[string]context.CancelFunc
PubChan chan Message
}
func NewDeviceManager(pubchan chan Message, subscriber Subscriber) *DeviceManager {
return &DeviceManager{
devices: make(map[string]*Device),
sub_cancel: make(map[string]context.CancelFunc),
subscriber: subscriber,
PubChan: pubchan,
}
}
func (m *DeviceManager) Get(name string) (*Device, bool) {
device, ok := m.devices[name]
return device, ok
}
func (m *DeviceManager) Add(device Device) error {
if _, prs := m.devices[device.Name]; prs {
return fmt.Errorf("device %s already exist", device.Name)
}
m.devices[device.Name] = &device
// subscribe to state topic
topic, err := device.ListenTopic()
if err != nil {
return err
}
if topic != "" {
cancel := m.subscriber(topic, 2, device.onMessage)
m.sub_cancel[device.Name] = cancel
}
return nil
}
func (m *DeviceManager) Delete(name string) error {
return nil
}
func (m *DeviceManager) SetSettings(name string, settings DeviceSettings) error {
device, ok := m.devices[name]
if !ok {
return fmt.Errorf("Not existings device %s", name)
}
device.Settings = settings
return nil
}
func (m *DeviceManager) SetState(name string, state DeviceState) error {
device, ok := m.devices[name]
if !ok {
return fmt.Errorf("Not existings device %s", name)
}
device.State = state
return nil
}
func (m *DeviceManager) Check(ctx context.Context, name string) error {
logger := zerolog.Ctx(ctx)
device, ok := m.devices[name]
if !ok {
return fmt.Errorf("Device %s don't exist", name)
}
err := device.CheckSetpoint(logger, m.PubChan)
if err != nil {
logger.Error().Err(err).Msg("")
return err
}
return nil
}
func (m *DeviceManager) CheckAll(ctx context.Context) error {
logger := zerolog.Ctx(ctx)
for _, device := range m.devices {
err := device.CheckSetpoint(logger, m.PubChan)
if err != nil {
logger.Error().Err(err).Msg("")
return err
}
}
return nil
}