115 lines
3.5 KiB
Go
115 lines
3.5 KiB
Go
// Copyright 2024 Joshua Rich <joshua.rich@gmail.com>.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package sensor
|
|
|
|
const (
|
|
requestTypeRegisterSensor = "register_sensor"
|
|
requestTypeUpdateSensor = "update_sensor_states"
|
|
requestTypeLocation = "update_location"
|
|
)
|
|
|
|
type stateRequestBody struct {
|
|
State any `json:"state" validate:"required"`
|
|
Attributes map[string]any `json:"attributes,omitempty" validate:"omitempty"`
|
|
Icon string `json:"icon,omitempty" validate:"omitempty,startswith=mdi:"`
|
|
ID string `json:"unique_id" validate:"required"`
|
|
EntityType string `json:"type" validate:"omitempty"`
|
|
}
|
|
|
|
type registrationRequestBody struct {
|
|
State any `json:"state" validate:"required"`
|
|
Attributes map[string]any `json:"attributes,omitempty" validate:"omitempty"`
|
|
Icon string `json:"icon,omitempty" validate:"omitempty,startswith=mdi:"`
|
|
ID string `json:"unique_id" validate:"required"`
|
|
EntityType string `json:"type" validate:"omitempty"`
|
|
Name string `json:"name" validate:"required"`
|
|
Units string `json:"unit_of_measurement,omitempty" validate:"omitempty"`
|
|
DeviceClass string `json:"device_class,omitempty" validate:"omitempty"`
|
|
StateClass string `json:"state_class,omitempty" validate:"omitempty"`
|
|
Category string `json:"entity_category,omitempty" validate:"omitempty"`
|
|
}
|
|
|
|
// Request represents a sensor request, either a registration, update or
|
|
// location update.
|
|
type Request struct {
|
|
Data any `json:"data"`
|
|
RequestType string `json:"type"`
|
|
retryable bool
|
|
}
|
|
|
|
func (r *Request) RequestBody() any {
|
|
return r
|
|
}
|
|
|
|
func (r *Request) Retry() bool {
|
|
return r.retryable
|
|
}
|
|
|
|
// AsSensorUpdate indicates the request will be a sensor update request.
|
|
func AsSensorUpdate(entity Entity) Option[Request] {
|
|
return func(request Request) Request {
|
|
request.RequestType = requestTypeUpdateSensor
|
|
request.Data = &stateRequestBody{
|
|
State: entity.Value,
|
|
Attributes: entity.Attributes,
|
|
Icon: entity.Icon,
|
|
ID: entity.ID,
|
|
EntityType: entity.EntityType.String(),
|
|
}
|
|
|
|
return request
|
|
}
|
|
}
|
|
|
|
// AsSensorRegistration indicates the request will be a sensor registration
|
|
// request.
|
|
func AsSensorRegistration(entity Entity) Option[Request] {
|
|
return func(request Request) Request {
|
|
request.RequestType = requestTypeRegisterSensor
|
|
request.Data = ®istrationRequestBody{
|
|
State: entity.Value,
|
|
Attributes: entity.Attributes,
|
|
Icon: entity.Icon,
|
|
ID: entity.ID,
|
|
EntityType: entity.EntityType.String(),
|
|
Name: entity.Name,
|
|
Units: entity.Units,
|
|
DeviceClass: entity.DeviceClass.String(),
|
|
StateClass: entity.StateClass.String(),
|
|
Category: entity.Category.String(),
|
|
}
|
|
|
|
return request
|
|
}
|
|
}
|
|
|
|
// AsLocationUpdate indicates the request will be a location update request.
|
|
func AsLocationUpdate(location Location) Option[Request] {
|
|
return func(request Request) Request {
|
|
request.RequestType = requestTypeLocation
|
|
request.Data = &location
|
|
|
|
return request
|
|
}
|
|
}
|
|
|
|
// AsRetryable marks that the request should be retried.
|
|
func AsRetryable(value bool) Option[Request] {
|
|
return func(request Request) Request {
|
|
request.retryable = value
|
|
return request
|
|
}
|
|
}
|
|
|
|
// NewRequest creates a new request with the given options.
|
|
func NewRequest(options ...Option[Request]) *Request {
|
|
request := Request{}
|
|
|
|
for _, option := range options {
|
|
request = option(request)
|
|
}
|
|
|
|
return &request
|
|
}
|