Files
shelly-exporter/collector/gen1_status.go
T
lostakj 9db7aa2560
Build Docker image on push / docker (push) Successful in 22s
Initila commit
2026-08-18 00:46:59 +02:00

244 lines
7.6 KiB
Go

package collector
import (
"bytes"
"encoding/json"
)
// gen1Status is a superset of the optional blocks returned by Gen1 /status
// endpoints. Pointers distinguish a missing capability from a valid zero value.
type gen1Status struct {
WiFiStation *struct {
Connected bool `json:"connected"`
SSID string `json:"ssid"`
IP string `json:"ip"`
RSSI int `json:"rssi"`
} `json:"wifi_sta"`
Cloud *struct {
Enabled bool `json:"enabled"`
Connected bool `json:"connected"`
} `json:"cloud"`
MQTT *struct {
Connected bool `json:"connected"`
} `json:"mqtt"`
Serial *uint64 `json:"serial"`
HasUpdate *bool `json:"has_update"`
MAC string `json:"mac"`
Update *struct {
Status string `json:"status"`
HasUpdate bool `json:"has_update"`
NewVersion string `json:"new_version"`
OldVersion string `json:"old_version"`
} `json:"update"`
RAMTotal *uint64 `json:"ram_total"`
RAMFree *uint64 `json:"ram_free"`
FSSize *uint64 `json:"fs_size"`
FSFree *uint64 `json:"fs_free"`
Uptime *float64 `json:"uptime"`
Relays []gen1Relay `json:"relays"`
Meters []gen1Meter `json:"meters"`
EMeters []gen1EMeter `json:"emeters"`
Inputs []gen1Input `json:"inputs"`
Input *float64 `json:"input"`
Rollers []gen1Roller `json:"rollers"`
Lights []gen1Light `json:"lights"`
ADCs []gen1ADC `json:"adcs"`
Thermostats []gen1Thermostat `json:"thermostats"`
Calibrated *bool `json:"calibrated"`
Temperature *float64 `json:"temperature"`
Overtemperature *bool `json:"overtemperature"`
TemperatureStatus string `json:"temperature_status"`
TemperatureSensor *gen1TemperatureSensor `json:"tmp"`
Humidity *gen1ValueSensor `json:"hum"`
Battery *gen1Battery `json:"bat"`
Lux *gen1Lux `json:"lux"`
Sensor *gen1MotionSensor `json:"sensor"`
Acceleration *gen1Acceleration `json:"accel"`
Motion *bool `json:"motion"`
Charger *bool `json:"charger"`
Smoke *bool `json:"smoke"`
Flood *bool `json:"flood"`
RainSensor *bool `json:"rain_sensor"`
Valid *bool `json:"is_valid"`
SensorError *float64 `json:"sensor_error"`
ConnectRetries *float64 `json:"connect_retries"`
ExternalTemperature map[string]gen1ExternalTemperature `json:"ext_temperature"`
ExternalHumidity map[string]gen1ExternalHumidity `json:"ext_humidity"`
TotalPower *float64 `json:"total_power"`
FSMounted *bool `json:"fs_mounted"`
GasSensor *struct {
SensorState string `json:"sensor_state"`
SelfTestState string `json:"self_test_state"`
AlarmState string `json:"alarm_state"`
} `json:"gas_sensor"`
Concentration *struct {
PPM *float64 `json:"ppm"`
Valid *bool `json:"is_valid"`
} `json:"concentration"`
Valves []struct {
State string `json:"state"`
} `json:"valves"`
}
type gen1Relay struct {
On *bool `json:"ison"`
HasTimer *bool `json:"has_timer"`
TimerDuration *float64 `json:"timer_duration"`
TimerRemaining *float64 `json:"timer_remaining"`
Overpower *bool `json:"overpower"`
Valid *bool `json:"is_valid"`
}
type gen1Meter struct {
Power *float64 `json:"power"`
Overpower *numberOrBool `json:"overpower"`
Valid *bool `json:"is_valid"`
Timestamp *float64 `json:"timestamp"`
Counters []float64 `json:"counters"`
Total *float64 `json:"total"`
}
type gen1EMeter struct {
Power *float64 `json:"power"`
ReactivePower *float64 `json:"reactive"`
PowerFactor *float64 `json:"pf"`
Current *float64 `json:"current"`
Voltage *float64 `json:"voltage"`
Valid *bool `json:"is_valid"`
Total *float64 `json:"total"`
TotalReturned *float64 `json:"total_returned"`
}
type gen1Input struct {
Input *float64 `json:"input"`
Event string `json:"event"`
EventCount *float64 `json:"event_cnt"`
LastSequence string `json:"last_sequence"`
}
type gen1Roller struct {
State string `json:"state"`
Power *float64 `json:"power"`
Valid *bool `json:"is_valid"`
SafetySwitch *bool `json:"safety_switch"`
Overtemperature *bool `json:"overtemperature"`
StopReason string `json:"stop_reason"`
LastDirection string `json:"last_direction"`
CurrentPosition *float64 `json:"current_pos"`
Calibrating *bool `json:"calibrating"`
Positioning *bool `json:"positioning"`
}
type gen1Light struct {
On *bool `json:"ison"`
HasTimer *bool `json:"has_timer"`
TimerRemaining *float64 `json:"timer_remaining"`
Mode string `json:"mode"`
Brightness *float64 `json:"brightness"`
Red *float64 `json:"red"`
Green *float64 `json:"green"`
Blue *float64 `json:"blue"`
White *float64 `json:"white"`
Gain *float64 `json:"gain"`
Temperature *float64 `json:"temp"`
Effect *float64 `json:"effect"`
}
type gen1ADC struct {
Voltage *float64 `json:"voltage"`
}
type gen1Thermostat struct {
Position *float64 `json:"pos"`
Target *struct {
Enabled *bool `json:"enabled"`
Value *float64 `json:"value"`
Units string `json:"units"`
} `json:"target_t"`
Temperature *gen1TemperatureSensor `json:"tmp"`
Schedule *bool `json:"schedule"`
ScheduleProfile *float64 `json:"schedule_profile"`
BoostMinutes *float64 `json:"boost_minutes"`
WindowOpen *bool `json:"window_open"`
}
type gen1TemperatureSensor struct {
Value *float64 `json:"value"`
Units string `json:"units"`
C *float64 `json:"tC"`
F *float64 `json:"tF"`
Valid *bool `json:"is_valid"`
}
type gen1ValueSensor struct {
Value *float64 `json:"value"`
Valid *bool `json:"is_valid"`
}
type gen1Battery struct {
Value *float64 `json:"value"`
Voltage *float64 `json:"voltage"`
}
type gen1Lux struct {
Value *float64 `json:"value"`
Illumination string `json:"illumination"`
Valid *bool `json:"is_valid"`
}
type gen1MotionSensor struct {
Motion *bool `json:"motion"`
Vibration *bool `json:"vibration"`
Timestamp *float64 `json:"timestamp"`
Active *bool `json:"active"`
Valid *bool `json:"is_valid"`
State string `json:"state"`
}
type gen1Acceleration struct {
Tilt *float64 `json:"tilt"`
Vibration *float64 `json:"vibration"`
VibrationTime *float64 `json:"vibration_time"`
}
type gen1ExternalTemperature struct {
HardwareID string `json:"hwID"`
C *float64 `json:"tC"`
F *float64 `json:"tF"`
}
type gen1ExternalHumidity struct {
HardwareID string `json:"hwID"`
Humidity *float64 `json:"hum"`
}
// numberOrBool handles the inconsistent Gen1 "overpower" representation:
// depending on the product it is either a threshold in watts or a boolean state.
type numberOrBool struct {
Number *float64
Bool *bool
}
func (value *numberOrBool) UnmarshalJSON(data []byte) error {
data = bytes.TrimSpace(data)
if bytes.Equal(data, []byte("null")) {
return nil
}
var boolean bool
if err := json.Unmarshal(data, &boolean); err == nil {
value.Bool = &boolean
return nil
}
var number float64
if err := json.Unmarshal(data, &number); err == nil {
value.Number = &number
return nil
}
// Unknown representations should not make every other metric unavailable.
return nil
}