116 lines
3.0 KiB
Go
116 lines
3.0 KiB
Go
package models
|
||
|
||
import (
|
||
"context"
|
||
"strings"
|
||
)
|
||
|
||
type Device struct {
|
||
ID int `json:"id"`
|
||
BridgeID int `json:"bridgeID"`
|
||
InternalID string `json:"internalId"`
|
||
Icon string `json:"icon"`
|
||
Name string `json:"name"`
|
||
Capabilities []DeviceCapability `json:"capabilities"`
|
||
ButtonNames []string `json:"buttonNames"`
|
||
DriverProperties map[string]string `json:"driverProperties"`
|
||
UserProperties map[string]string `json:"userProperties"`
|
||
State DeviceState `json:"state"`
|
||
Tags []string `json:"tags"`
|
||
}
|
||
|
||
// DeviceState contains optional state values that
|
||
// - Power: Whether the device is powered on
|
||
// - Color: Color value, if a color setting can be set on the device
|
||
// - Intensity: e.g. brightness, range 0..=1
|
||
// - Temperature: e.g. for thermostats
|
||
type DeviceState struct {
|
||
Power bool `json:"power"`
|
||
Color ColorValue `json:"color,omitempty"`
|
||
Intensity float64 `json:"intensity,omitempty"`
|
||
Temperature float64 `json:"temperature"`
|
||
}
|
||
|
||
type NewDeviceState struct {
|
||
Power *bool `json:"power"`
|
||
Color *string `json:"color"`
|
||
Intensity int `json:"intensity"`
|
||
Temperature int `json:"temperature"`
|
||
}
|
||
|
||
type DeviceCapability string
|
||
|
||
type DeviceRepository interface {
|
||
FindByID(ctx context.Context, id int) (*Device, error)
|
||
FetchByReference(ctx context.Context, kind ReferenceKind, value string) ([]Device, error)
|
||
Save(ctx context.Context, device *Device) error
|
||
Delete(ctx context.Context, device *Device) error
|
||
}
|
||
|
||
var (
|
||
DCPower DeviceCapability = "Power"
|
||
DCColorHS DeviceCapability = "ColorHS"
|
||
DCColorKelvin DeviceCapability = "ColorKelvin"
|
||
DCButtons DeviceCapability = "Buttons"
|
||
DCIntensity DeviceCapability = "Intensity"
|
||
DCTemperature DeviceCapability = "Temperature"
|
||
)
|
||
|
||
var Capabilities = []DeviceCapability{
|
||
DCPower,
|
||
DCColorHS,
|
||
DCColorKelvin,
|
||
DCButtons,
|
||
DCIntensity,
|
||
DCTemperature,
|
||
}
|
||
|
||
func (d *Device) Validate() error {
|
||
d.Name = strings.Trim(d.Name, " \t\n ")
|
||
if d.Name == "" {
|
||
return ErrInvalidName
|
||
}
|
||
|
||
newCaps := make([]DeviceCapability, 0, len(d.Capabilities))
|
||
for _, currCap := range d.Capabilities {
|
||
for _, validCap := range Capabilities {
|
||
if currCap == validCap {
|
||
newCaps = append(newCaps, currCap)
|
||
break
|
||
}
|
||
}
|
||
}
|
||
d.Capabilities = newCaps
|
||
|
||
return nil
|
||
}
|
||
|
||
func (d *Device) HasCapability(capacity DeviceCapability) bool {
|
||
for _, c := range d.Capabilities {
|
||
if c == capacity {
|
||
return true
|
||
}
|
||
}
|
||
|
||
return false
|
||
}
|
||
|
||
func (d *Device) SetState(newState NewDeviceState) error {
|
||
if newState.Power != nil && d.HasCapability(DCPower) {
|
||
d.State.Power = *newState.Power
|
||
}
|
||
|
||
if newState.Color != nil {
|
||
parsed, err := ParseColorValue(*newState.Color)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
|
||
if (parsed.IsKelvin() && d.HasCapability(DCColorKelvin)) || (parsed.IsHueSat() && d.HasCapability(DCColorHS)) {
|
||
d.State.Color = parsed
|
||
}
|
||
}
|
||
|
||
return nil
|
||
}
|