update
This commit is contained in:
169
pkg/devices/manager.go
Normal file
169
pkg/devices/manager.go
Normal file
@@ -0,0 +1,169 @@
|
||||
package devices
|
||||
|
||||
import (
|
||||
"app/pkg/datastore"
|
||||
"app/pkg/mqtt"
|
||||
"app/pkg/telldus"
|
||||
"fmt"
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventManager handles telldus events and callbacks
|
||||
type EventManager struct {
|
||||
store *datastore.DataStore
|
||||
mqttClient *mqtt.Client
|
||||
rawEvents []datastore.RawEvent
|
||||
sensorEvents []datastore.SensorEvent
|
||||
mu sync.Mutex
|
||||
maxEvents int
|
||||
}
|
||||
|
||||
// NewEventManager creates a new event manager
|
||||
func NewEventManager(store *datastore.DataStore, mqttClient *mqtt.Client, maxEvents int) *EventManager {
|
||||
return &EventManager{
|
||||
store: store,
|
||||
mqttClient: mqttClient,
|
||||
maxEvents: maxEvents,
|
||||
}
|
||||
}
|
||||
|
||||
// GetRawEvents returns a copy of raw events
|
||||
func (em *EventManager) GetRawEvents() []datastore.RawEvent {
|
||||
em.mu.Lock()
|
||||
defer em.mu.Unlock()
|
||||
events := make([]datastore.RawEvent, len(em.rawEvents))
|
||||
copy(events, em.rawEvents)
|
||||
return events
|
||||
}
|
||||
|
||||
// GetSensorEvents returns a copy of sensor events
|
||||
func (em *EventManager) GetSensorEvents() []datastore.SensorEvent {
|
||||
em.mu.Lock()
|
||||
defer em.mu.Unlock()
|
||||
events := make([]datastore.SensorEvent, len(em.sensorEvents))
|
||||
copy(events, em.sensorEvents)
|
||||
return events
|
||||
}
|
||||
|
||||
// HandleDeviceEvent handles device state change events
|
||||
func (em *EventManager) HandleDeviceEvent(deviceID, method int, data string, callbackID int) {
|
||||
fmt.Printf("Device event: ID=%d, Method=%d, Data=%s\n", deviceID, method, data)
|
||||
|
||||
var state string
|
||||
switch method {
|
||||
case telldus.MethodTurnOn:
|
||||
state = "ON"
|
||||
case telldus.MethodTurnOff:
|
||||
state = "OFF"
|
||||
}
|
||||
|
||||
if state != "" {
|
||||
em.mqttClient.PublishDeviceState(deviceID, state)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleSensorEvent handles sensor data events
|
||||
func (em *EventManager) HandleSensorEvent(protocol, model string, id, dataType int, value string, timestamp, callbackID int) {
|
||||
fmt.Printf("Sensor event: Protocol=%s, Model=%s, ID=%d, Type=%d, Value=%s, Timestamp=%d\n",
|
||||
protocol, model, id, dataType, value, timestamp)
|
||||
|
||||
// Publish to MQTT
|
||||
em.mqttClient.PublishSensorValue(protocol, model, id, dataType, value)
|
||||
|
||||
// Store in history
|
||||
em.mu.Lock()
|
||||
em.sensorEvents = append(em.sensorEvents, datastore.SensorEvent{
|
||||
Timestamp: time.Now(),
|
||||
Protocol: protocol,
|
||||
Model: model,
|
||||
ID: id,
|
||||
DataType: dataType,
|
||||
Value: value,
|
||||
})
|
||||
if len(em.sensorEvents) > em.maxEvents {
|
||||
em.sensorEvents = em.sensorEvents[1:]
|
||||
}
|
||||
em.mu.Unlock()
|
||||
|
||||
// Update last value in DB
|
||||
if err := em.store.UpdateSensorValue(protocol, model, id, dataType, value); err != nil {
|
||||
log.Printf("Error updating sensor %s %s %d: %v", protocol, model, id, err)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleRawDeviceEvent handles raw device detection events
|
||||
func (em *EventManager) HandleRawDeviceEvent(data string, controllerID, callbackID int) {
|
||||
fmt.Printf("Raw device event: ControllerID=%d, Data=%s\n", controllerID, data)
|
||||
|
||||
// Parse data
|
||||
fields := strings.Split(data, ";")
|
||||
var class, protocol, model, deviceID string
|
||||
for _, field := range fields {
|
||||
kv := strings.SplitN(field, ":", 2)
|
||||
if len(kv) == 2 {
|
||||
key, val := kv[0], kv[1]
|
||||
switch key {
|
||||
case "class":
|
||||
class = val
|
||||
case "protocol":
|
||||
protocol = val
|
||||
case "model":
|
||||
model = val
|
||||
case "id":
|
||||
deviceID = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Store in potential_devices
|
||||
potentialDev := &datastore.PotentialDevice{
|
||||
Class: class,
|
||||
Protocol: protocol,
|
||||
Model: model,
|
||||
DeviceID: deviceID,
|
||||
LastData: data,
|
||||
LastSeen: time.Now().Unix(),
|
||||
}
|
||||
if err := em.store.UpsertPotentialDevice(potentialDev); err != nil {
|
||||
log.Printf("Error storing potential device: %v", err)
|
||||
}
|
||||
|
||||
// If sensor, ensure in sensors table
|
||||
if class == "sensor" {
|
||||
idInt, _ := strconv.Atoi(deviceID)
|
||||
sensor := &datastore.Sensor{
|
||||
Protocol: protocol,
|
||||
Model: model,
|
||||
ID: idInt,
|
||||
Name: fmt.Sprintf("%s %s %s", protocol, model, deviceID),
|
||||
TemperatureUniqueID: fmt.Sprintf("telldus_sensor_%s_%s_%s_temperature", protocol, model, deviceID),
|
||||
HumidityUniqueID: fmt.Sprintf("telldus_sensor_%s_%s_%s_humidity", protocol, model, deviceID),
|
||||
}
|
||||
if err := em.store.UpsertSensor(sensor); err != nil {
|
||||
log.Printf("Error inserting sensor from raw: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Log the raw event data
|
||||
em.mu.Lock()
|
||||
em.rawEvents = append(em.rawEvents, datastore.RawEvent{
|
||||
Timestamp: time.Now(),
|
||||
ControllerID: controllerID,
|
||||
Data: data,
|
||||
})
|
||||
if len(em.rawEvents) > em.maxEvents {
|
||||
em.rawEvents = em.rawEvents[1:]
|
||||
}
|
||||
em.mu.Unlock()
|
||||
}
|
||||
|
||||
// RegisterCallbacks registers all event callbacks with telldus
|
||||
func (em *EventManager) RegisterCallbacks() {
|
||||
telldus.RegisterDeviceEvent(em.HandleDeviceEvent)
|
||||
telldus.RegisterSensorEvent(em.HandleSensorEvent)
|
||||
telldus.RegisterRawDeviceEvent(em.HandleRawDeviceEvent)
|
||||
}
|
||||
Reference in New Issue
Block a user