Reading state
All reads are GET under /api-gateway/v1/iot-shadow/device/{deviceId}/ and return the standard envelope. See Overview for caching behaviour and units.
Dashboard
Section titled “Dashboard”GET…/dashboardInfo
The same overview the SplashMe app shows on its home screen.
{ "status": "SUCCESS", "data": { "dashboard": { "actual_ph": 74, "actual_orp": 652, "d_ph": 74, "d_orp_mineral": 650, "d_orp_liquid": 650, "chemistry_stable": true, "ph_switch_status": false, "orp_switch_status": true, "actual_pump_speed": 60, "actual_flow_rate": 180, "actual_pressure": 12, "main_pump_status": 99, "dry_run_status": 0, "flow_status": 1, "pump_calib": false, "heater_state": false, "solar_state": false, "spa_heater_state": false, "desired_water_temp": 28, "water_temp": 26, "solar_temp": 0, "solar_mode": 0, "is_naked": false, "cost_savings": [0, 0, 0], "backwash_pressure": 0, "prime_pressure": 0 } }}| Field | Meaning |
|---|---|
actual_ph, actual_orp |
Current readings, pH × 10 and mV |
d_ph, d_orp_mineral, d_orp_liquid |
Set points for pH, mineral chlorinator ORP and liquid chlorine ORP |
chemistry_stable |
Readings are settled enough to dose on |
ph_switch_status, orp_switch_status |
The acid and chlorine dosing outputs are energised right now |
actual_pump_speed |
Main pump speed, percent |
actual_flow_rate |
Measured flow |
main_pump_status |
0 off, 1 to 20 running under that schedule number, 99 running manually |
dry_run_status |
0 normal, otherwise dry-run protection has tripped |
pump_calib |
Flow calibration has been performed |
heater_state, solar_state, spa_heater_state |
Heat sources currently on |
desired_water_temp, water_temp |
Heating set point and current water temperature, whole °C. Use ambientTemp for a tenth-of-a-degree reading |
is_naked |
A Naked ioniser is installed |
This read has a 10-second controller timeout and its cached copy expires after 10 minutes.
Chemistry card
Section titled “Chemistry card”GET…/chemistryCard
Four reads in one: current chemistry, pH dosing settings, chlorine settings and the equipment slot assignment. Each part is fetched in turn; a part that fails is null, partial is true, and errors lists one "<part>: <message>" string per failed part. The call fails outright only when all four parts fail, with the same joined messages.
{ "status": "SUCCESS", "data": { "chemistry": { "ph_value": 74, "orp_value": 652, "tds_value": 0, "desire_ph_value": 74, "desire_orp_value": 650, "desire_tds_value": 0, "device_array": [ { "name": "pH Doser", "status": 1, "volume": 12000 } ] }, "phSettings": { "ph_dosing": true, "ph_dosing_time": 60, "desired_ph_level": 74, "acid_drum_volume": 20000, "remain_acid_volume": 12000, "reset_acid_volume": false, "max_dose_pre_day": 10, "current_dose_today": 2, "dose_intervals": 30, "ph_doser_timer": 0, "ph_dose_rate": 100 }, "chlorineSettings": { "orp_controlled": true, "desired_orp_level_mineral": 650, "liquid_chlorine_dosing": false, "desired_orp_level_liquid": 650, "chlorine_dosing_time": 60, "chlorine_drum_volume": 20000, "remain_chlorine_volume": 15000, "reset_chlorine_volume": false, "max_dose_pre_day": 10, "current_dose_today": 0, "dose_intervals": 30, "liquid_doser_timer": 0, "liquid_dose_rate": 100, "mineral_dosing_duration_today": 0, "mineral_max_duration_preday": 0 }, "auxAssign": { "aux_assign": [0, 31, 6, 12, 0, 0, 0, 0, 0], "aux_name": ["", "Main Pump", "pH Doser", "Pool Light", "", "", "", "", ""], "equipment": [ { "type_code": 31, "type": "31", "label": "Main Pump", "slot": 1 }, { "type_code": 6, "type": "6", "label": "pH Doser", "slot": 2 }, { "type_code": 12, "type": "12", "label": "Pool Light", "slot": 3 } ] } }}chemistry: ph_value and desire_ph_value are pH × 10; orp_value and desire_orp_value are mV. device_array lists dosing devices with status 1 when active.
phSettings and chlorineSettings are the objects you send back to the write endpoints; their fields are described on Chemistry.
auxAssign: aux_assign[i] is the equipment type code in controller slot i and aux_name[i] the user’s label; slot 0 is the main pump. equipment lists slots from index 1 upward, including empty ones with type_code 0, so the main pump is not in it; label falls back to a generic name when the slot has no user label. Ignore the brand field; it is a legacy value. aux_timer and has_ecoclear appear when set.
GET…/pumpInfo
{ "status": "SUCCESS", "data": { "pump": { "pump_type": "VSD", "pump_brand": "SplashMe", "pump_model": "SM-1500", "motor_status": 1, "actual_speed": 60, "actual_flowrate": 180, "pump_cooldown": false, "flow_state": [1, 0], "dry_run_supported": true, "dry_run": [1, 3, 0, 0], "dry_run_info": { "status": 1, "total_rounds": 3, "current_round": 0, "protection_remaining_second": 0, "activated": false } } }}| Field | Meaning |
|---|---|
pump_type |
VSD for a variable-speed pump, otherwise a fixed-speed type |
actual_speed |
Percent. Greater than 0 means the motor is running; prefer this over the slot status for variable-speed pumps |
pump_cooldown |
The pump is being kept on to cool a heater that has just switched off; pump_cooldown_left is the remaining seconds |
prime_time_left |
Seconds left in the priming phase after start |
dry_run_supported |
Dry-run protection is available (firmware 2.5.28 or later) |
dry_run_info.activated |
Dry-run protection is currently holding the pump off |
pump_cooldown_left, prime_time_left, dry_run and dry_run_info are omitted when zero or not applicable; speed_priority may also appear. Some older firmware reports flow_state as a single number, in which case this endpoint returns 500.
Equipment slots
Section titled “Equipment slots”GET…/auxInfo
Every slot on the controller with its current state, plus the same entries grouped by category.
{ "status": "SUCCESS", "data": { "manual": { "aux": [ { "aux_tag": "Main Pump", "aux_type_code": 31, "aux_status": true, "aux_trump": false, "aux_slot_num": 0, "pump_speed": 60, "actual_flow_rate": 180 }, { "aux_tag": "Pool Light", "aux_type_code": 12, "aux_status": false, "aux_trump": false, "aux_slot_num": 2, "pump_speed": 0, "actual_flow_rate": 0, "aux_timer": 3600, "aux_timer_remain_sec": 0 } ], "pump_devices": [ { "aux_tag": "Main Pump", "aux_type_code": 31, "aux_status": true, "aux_trump": false, "aux_slot_num": 0, "pump_speed": 60, "actual_flow_rate": 180 } ], "other_devices": [ { "aux_tag": "Pool Light", "aux_type_code": 12, "aux_status": false, "aux_trump": false, "aux_slot_num": 2, "pump_speed": 0, "actual_flow_rate": 0, "aux_timer": 3600, "aux_timer_remain_sec": 0 } ] } }}| Field | Meaning |
|---|---|
aux_slot_num |
The controller’s slot index; the main pump is 0. Send this and aux_type_code when switching the slot |
aux_type_code |
Equipment type |
aux_status |
The output is on |
pump_speed |
Speed for the main pump slot, percent |
aux_timer |
Configured auto-off time in seconds, if any; aux_timer_remain_sec counts it down |
Groups: pump_devices (the main pump), spa (spa actuators), spa_devices (spa jets and blowers), pump_linked_devices (UV, ozone, ioniser and cleaners that run with the pump) and other_devices. Entries in the groups are full copies of the aux entries. A group that would be empty is omitted.
Temperatures
Section titled “Temperatures”GET…/ambientTemp
{ "status": "SUCCESS", "data": { "ambientTemp": { "water_temp": 265, "water_temp_offset": 0, "ambient_temp": 2450, "ambient_temp_offset": 0 } } }water_temp is °C × 10 (26.5 °C); ambient_temp is °C × 100 (24.5 °C) and reads 0 when there is no air sensor. The offsets are calibration corrections already applied to the readings.

