You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
3.0 KiB
115 lines
3.0 KiB
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
|
|
}
|