Skip to content
Snippets Groups Projects
xaal.go 5.75 KiB
package main

import (
	"math"

	"gitlab.imt-atlantique.fr/xaal/code/go/core/schemas"
	"gitlab.imt-atlantique.fr/xaal/code/go/core/uuid"
	"gitlab.imt-atlantique.fr/xaal/code/go/core/xaal"
)

type XAALDevice struct {
	*xaal.Device
}

type Contact struct {
	XAALDevice
}

type Thermometer struct {
	XAALDevice
}

type Hygrometer struct {
	XAALDevice
}

type LinkQuality struct {
	XAALDevice
}

type Battery struct {
	XAALDevice
}

type PowerRelay struct {
	XAALDevice
	Z2MDevice
}

type Lamp struct {
	XAALDevice
	Z2MDevice
}

type XAALDeviceInterface interface {
	update(map[string]interface{})
}

func (dev *XAALDevice) setup(zDev *Z2MDevice) {
	dev.VendorID = zDev.Definition.Vendor
	dev.ProductID = zDev.Definition.Model
	dev.HWID = zDev.IeeeAddress
	dev.Version = zDev.SwBuildID
	dev.Info = "z2m:" + zDev.Type + ":" + zDev.FriendlyName
	GetGW().engine.AddDevice(dev.Device)
}

// ----------------------------------------------------------------------------
// Contact
// ----------------------------------------------------------------------------
func NewContact(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &Contact{XAALDevice{schemas.NewContact(addr)}}
	dev.setup(zDev)
	// TODO: put this in Z2MDevice
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *Contact) update(payload map[string]interface{}) {
	value := payload["contact"].(bool)
	dev.GetAttribute("detected").SetValue(!value)
}

// ----------------------------------------------------------------------------
// Thermometer
// ----------------------------------------------------------------------------
func NewThermometer(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &Thermometer{XAALDevice{schemas.NewThermometer(addr)}}
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *Thermometer) update(payload map[string]interface{}) {
	value := payload["temperature"].(float64)
	dev.GetAttribute("temperature").SetValue(value)
}

// ----------------------------------------------------------------------------
// Hygrometer
// ----------------------------------------------------------------------------
func NewHygrometer(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &Hygrometer{XAALDevice{schemas.NewHygrometer(addr)}}
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *Hygrometer) update(payload map[string]interface{}) {
	value := payload["humidity"].(float64)
	dev.GetAttribute("humidity").SetValue(value)
}

// ----------------------------------------------------------------------------
// LinkQuality
// ----------------------------------------------------------------------------
func NewLinkQuality(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &LinkQuality{XAALDevice{schemas.NewLinkquality(addr)}}
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *LinkQuality) update(payload map[string]interface{}) {
	value := payload["linkquality"].(float64)
	value = math.Round(value / 255 * 100)
	dev.GetAttribute("level").SetValue(value)
}

// ----------------------------------------------------------------------------
// Battery
// ----------------------------------------------------------------------------
func NewBattery(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &Battery{XAALDevice{schemas.NewBattery(addr)}}
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *Battery) update(payload map[string]interface{}) {
	value := payload["battery"].(float64)
	dev.GetAttribute("level").SetValue(value)
}

// ----------------------------------------------------------------------------
// PowerRelay
// ----------------------------------------------------------------------------
func NewPowerRelay(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &PowerRelay{XAALDevice{schemas.NewPowerrelayToggle(addr)}, *zDev}
	dev.SetMethod("turn_on", dev.On)
	dev.SetMethod("turn_off", dev.Off)
	dev.SetMethod("toggle", dev.Toggle)
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *PowerRelay) update(payload map[string]interface{}) {
	value := payload["state"].(string)
	if value == "ON" {
		dev.GetAttribute("power").SetValue(true)
	} else {
		dev.GetAttribute("power").SetValue(false)
	}
}

func (dev *PowerRelay) setState(value string) {
	// TODO: put this in Z2MDevice
	topic := dev.Z2MDevice.SetTopic()
	client := GetGW().client
	body := `{"state": "` + value + `"}`
	client.Publish(topic, 0, false, body)
}

func (dev *PowerRelay) On(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("ON")
	return nil
}

func (dev *PowerRelay) Off(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("OFF")
	return nil
}

func (dev *PowerRelay) Toggle(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("TOGGLE")
	return nil
}

// ----------------------------------------------------------------------------
// Lamp
// ----------------------------------------------------------------------------
func NewLamp(addr uuid.UUID, zDev *Z2MDevice) {
	dev := &Lamp{XAALDevice{schemas.NewLamp(addr)}, *zDev}
	dev.SetMethod("turn_on", dev.On)
	dev.SetMethod("turn_off", dev.Off)
	dev.SetMethod("toggle", dev.Toggle)
	dev.setup(zDev)
	zDev.XAALDevices = append(zDev.XAALDevices, dev)
}

func (dev *Lamp) update(payload map[string]interface{}) {
	value := payload["state"].(string)
	if value == "ON" {
		dev.GetAttribute("light").SetValue(true)
	} else {
		dev.GetAttribute("light").SetValue(false)
	}
}

func (dev *Lamp) setState(value string) {
	// TODO: put this in Z2MDevice
	topic := dev.Z2MDevice.SetTopic()
	client := GetGW().client
	body := `{"state": "` + value + `"}`
	client.Publish(topic, 0, false, body)
}

func (dev *Lamp) On(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("ON")
	return nil
}

func (dev *Lamp) Off(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("OFF")
	return nil
}

func (dev *Lamp) Toggle(xaal.MessageBody) *xaal.MessageBody {
	dev.setState("TOGGLE")
	return nil
}