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]interface{} `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" DCColorHSK DeviceCapability = "ColorHSK" DCColorKelvin DeviceCapability = "ColorKelvin" DCButtons DeviceCapability = "Buttons" DCPresence DeviceCapability = "Presence" DCIntensity DeviceCapability = "Intensity" DCTemperatureControl DeviceCapability = "TemperatureControl" DCTemperatureSensor DeviceCapability = "TemperatureSensor" ) var Capabilities = []DeviceCapability{ DCPower, DCColorHS, DCColorKelvin, DCButtons, DCPresence, DCIntensity, DCTemperatureControl, DCTemperatureSensor, } 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(capabilities ...DeviceCapability) bool { for _, c := range d.Capabilities { for _, c2 := range capabilities { if c == c2 { 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, DCColorHSK)) || (parsed.IsHueSat() && d.HasCapability(DCColorHS)) { d.State.Color = parsed } } return nil }