From dc77e34b6752423d5510ac4836e9f10e720f68fd Mon Sep 17 00:00:00 2001 From: Rob Landry Date: Sun, 25 Jan 2026 08:16:44 -0500 Subject: [PATCH 1/3] Add Cloud --- devices/CLOUD/aquarium/data | 155 ++++++++ devices/CLOUD/device/data | 682 ++++++++++++++++++++++++++++++++++++ devices/CLOUD/meta.json | 9 + devices/CLOUD/user/data | 15 + 4 files changed, 861 insertions(+) create mode 100644 devices/CLOUD/aquarium/data create mode 100644 devices/CLOUD/device/data create mode 100644 devices/CLOUD/meta.json create mode 100644 devices/CLOUD/user/data diff --git a/devices/CLOUD/aquarium/data b/devices/CLOUD/aquarium/data new file mode 100644 index 0000000..6178823 --- /dev/null +++ b/devices/CLOUD/aquarium/data @@ -0,0 +1,155 @@ +[ + { + "dst_enabled": false, + "height": 40.64, + "id": 111111, + "length": 60.96, + "measuring_unit": "gallons", + "name": "Aquarium 1", + "net_water_volume": 120, + "online": true, + "properties": { + "emergency": false, + "emergency_1": { + "code": "emergency_1", + "enabled": false, + "name": "Emergency", + "type": "emergency" + }, + "feeding": false, + "feeding_1": { + "code": "feeding_1", + "enabled": false, + "name": "Feeding", + "scheduled_feeding": false, + "skip_next": [], + "start": [], + "type": "feeding" + }, + "led_emergency": false, + "maintenance": false, + "maintenance_1": { + "code": "maintenance_1", + "enabled": false, + "name": "Maintenance", + "type": "maintenance" + }, + "shortcut_reminder": false, + "staggered": false, + "staggered_delay": 0 + }, + "serial_number": "", + "staggered": false, + "staggered_delay": 0, + "system_model": "Aquarium System", + "system_series": "other", + "system_type": "mixed-reef", + "timezone_offset": -300, + "uid": "00000000-0000-0000-0000-000000000001", + "user_uid": "00000000-0000-0000-0000-000000000001", + "water_volume": 80, + "width": 121.92 + }, + { + "dst_enabled": false, + "height": 0.0, + "id": 111112, + "length": 0.0, + "measuring_unit": "gallons", + "name": "Aquarium 2", + "net_water_volume": 20, + "online": false, + "properties": { + "emergency": false, + "emergency_1": { + "code": "emergency_1", + "enabled": false, + "name": "Emergency", + "type": "emergency" + }, + "feeding": false, + "feeding_1": { + "code": "feeding_1", + "enabled": false, + "name": "Feeding", + "scheduled_feeding": false, + "skip_next": [], + "start": [], + "type": "feeding" + }, + "led_emergency": false, + "maintenance": false, + "maintenance_1": { + "code": "maintenance_1", + "enabled": false, + "name": "Maintenance", + "type": "maintenance" + }, + "shortcut_reminder": false, + "staggered": false, + "staggered_delay": 0 + }, + "serial_number": "12345", + "staggered": false, + "staggered_delay": 0, + "system_model": "Aquarium System", + "system_series": "Red Sea MAX", + "system_type": "mixed-reef", + "timezone_offset": -300, + "uid": "00000000-0000-0000-0000-000000000002", + "user_uid": "00000000-0000-0000-0000-000000000001", + "water_volume": 75, + "width": 0.0 + }, + { + "dst_enabled": false, + "height": 0.0, + "id": 111113, + "length": 0.0, + "measuring_unit": "gallons", + "name": "Aquarium 3", + "net_water_volume": 53, + "online": true, + "properties": { + "emergency": false, + "emergency_1": { + "code": "emergency_1", + "enabled": false, + "name": "Emergency", + "type": "emergency" + }, + "feeding": false, + "feeding_1": { + "code": "feeding_1", + "enabled": false, + "name": "Feeding", + "scheduled_feeding": false, + "skip_next": [], + "start": [], + "type": "feeding" + }, + "led_emergency": false, + "maintenance": false, + "maintenance_1": { + "code": "maintenance_1", + "enabled": false, + "name": "Maintenance", + "type": "maintenance" + }, + "shortcut_reminder": false, + "staggered": false, + "staggered_delay": 0 + }, + "serial_number": "11926", + "staggered": false, + "staggered_delay": 0, + "system_model": "Aquarium System", + "system_series": "Red Sea REEFER", + "system_type": "mixed-reef", + "timezone_offset": -300, + "uid": "00000000-0000-0000-0000-000000000003", + "user_uid": "00000000-0000-0000-0000-000000000001", + "water_volume": 200, + "width": 0.0 + } +] \ No newline at end of file diff --git a/devices/CLOUD/device/data b/devices/CLOUD/device/data new file mode 100644 index 0000000..82e12bf --- /dev/null +++ b/devices/CLOUD/device/data @@ -0,0 +1,682 @@ +[ + { + "aquarium_id": 111111, + "aquarium_uid": "00000000-0000-0000-0000-000000000001", + "board": "esp32", + "bssid": "02:00:01:F7:34:AE", + "connected": true, + "firmware_version": "1.11.1", + "framework": "i", + "group_index": 0, + "grouped": false, + "hw_revision": "V1.2A_24C", + "hwid": "0700084ae021", + "id": 990068, + "in_service": true, + "ip_address": "10.0.0.11", + "last_seen": "2026-01-15T20:20:55.949188Z", + "mac": "02:00:00:EA:92:7D", + "model": "RSATO+", + "name": "RSATO+10000000000", + "offset": 0, + "onboarding_date": "2025-12-21T23:07:17.192522Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "ato_sensor": { + "connected": true, + "is_calibrated": true, + "is_sensor_error": false, + "last_adjustment_date": null, + "last_installation_date": 1766358323, + "serial_code": "cfaeed54730f5d5d" + }, + "check_sensor": false, + "device_settings": { + "auto_fill": true, + "buzzer": { + "duty_cycle": 50, + "enabled": true, + "frequency": 12 + }, + "flow_rate_override": -1, + "hose": { + "height": 38, + "length": 137 + }, + "leak": { + "dry_threshold": 1, + "emergency_shutdown": false, + "rodi_threshold": 20, + "sensor_enabled": true + }, + "pump_speed_override": -1, + "rvm_enabled": true, + "shortcut_off_delay": 0, + "temp_enabled": false, + "temperature": { + "acceptable_range_high": 28, + "acceptable_range_low": 21, + "code": "515", + "desired_range_high": 26, + "desired_range_low": 23, + "enabled": false, + "log_enabled": false, + "offset": 0 + } + }, + "device_setup_date": 1766340517, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "factory_reset_time": 1766340517, + "is_pump_on": false, + "leak_sensor": { + "buzzer_on": false, + "connected": true, + "status": "dry" + }, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "mode": "auto", + "shortcut_settings": { + "shortcut_off_delay": 0 + }, + "timezone": -300 + }, + "ssid": "REDACTED_SSID", + "type": "reef-ato" + }, + { + "aquarium_id": 111111, + "aquarium_uid": "00000000-0000-0000-0000-000000000001", + "board": "esp32", + "bssid": "02:00:01:F7:34:AE", + "connected": true, + "firmware_version": "3.0.0", + "framework": "a", + "group_index": 0, + "grouped": false, + "hwid": "ae8f6238d45a", + "id": 961753, + "in_service": true, + "ip_address": "10.0.0.12", + "last_seen": "2026-01-02T21:47:42.294008Z", + "mac": "02:00:00:23:79:22", + "model": "RSDOSE4", + "name": "RSDOSE4-000000001", + "offset": 0, + "onboarding_date": "2025-11-01T21:18:49.887027Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "battery_level": "high", + "calibration_reminder": false, + "calibration_reminder_days": 60, + "calibration_reminder_steps": 35000, + "daily_metrics_last_compute_time": 1768608000, + "device_settings": { + "auto_fill_schedule": false, + "bundled_heads": false, + "shortcut_off_delay": 0 + }, + "dosing_waiting_period": 60, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "factory_reset_time": 1577836800, + "feeding": false, + "feeding_1": { + "duration": 20, + "subscribed": false + }, + "feeding_duration": 20, + "file_error": false, + "food_head_schedule": {}, + "heads": { + "1": { + "daily_dose": 0, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 0, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 0, + "nd": 1, + "schedule_enabled": false, + "schedule_type": "single", + "shortcut_code": "no_shortcut", + "show": false, + "slm": true, + "state": "not-setup", + "supplement": { + "brand_name": "Red Sea", + "concentration": 0, + "display_name": "Coral food", + "made_by_redsea": true, + "name": "Reef Energy Plus", + "short_name": "RE+", + "type": "null", + "uid": "bf9a7da3-741b-4c1d-8542-d9344a95fb70" + }, + "vps": 0 + }, + "2": { + "daily_dose": 0, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 0, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 1762103199, + "nd": 1, + "schedule_enabled": false, + "schedule_type": "single", + "shortcut_code": "no_shortcut", + "show": true, + "slm": true, + "state": "on", + "supplement": { + "brand_name": "API", + "concentration": 0, + "display_name": "Magnesium", + "made_by_redsea": false, + "name": "Magnesium", + "short_name": "Mag", + "type": "null", + "uid": "184238cc-8840-4a47-9e0e-d22ad5e3f6fe" + }, + "vps": 0.075758 + }, + "3": { + "daily_dose": 10, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 10, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 1762102146, + "nd": 24, + "schedule_enabled": true, + "schedule_type": "hourly", + "shortcut_code": "no_shortcut", + "show": true, + "slm": true, + "state": "on", + "supplement": { + "brand_name": "Ocean's Blend", + "concentration": 0, + "display_name": "Calcium", + "made_by_redsea": false, + "name": "Calcium (Part 1)", + "short_name": "Cal", + "type": "null", + "uid": "55a13d1a-c217-45f9-aa0f-640160a3c166" + }, + "vps": 0.075758 + }, + "4": { + "daily_dose": 10, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 10, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 1762101944, + "nd": 24, + "schedule_enabled": false, + "schedule_type": "hourly", + "shortcut_code": "no_shortcut", + "show": true, + "slm": true, + "state": "on", + "supplement": { + "brand_name": "Ocean's Blend", + "concentration": 0, + "display_name": "Alkalinity", + "made_by_redsea": false, + "name": "Alkalinity (Part 2)", + "short_name": "Alk", + "type": "null", + "uid": "6537abd2-4bce-43db-a567-360dab0684aa" + }, + "vps": 0.075758 + } + }, + "is_factory_reset": false, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "missed_doses_reminder": true, + "mode": "auto", + "ntp_sync": true, + "shortcut_settings": { + "shortcut_off_delay": 0 + }, + "start_of_schedule_for_next_day": 0, + "stock_alert_days": 7, + "time_error": false, + "time_error_unixtime": 0, + "timezone": -300, + "turned_off": false + }, + "ssid": "REDACTED_SSID", + "type": "reef-dosing" + }, + { + "aquarium_id": 111111, + "aquarium_uid": "00000000-0000-0000-0000-000000000001", + "board": "esp32", + "bssid": "02:00:01:F7:34:AE", + "connected": true, + "firmware_version": "1.10.2", + "framework": "i", + "group_index": 0, + "grouped": false, + "hw_revision": "v0.4_24G", + "hwid": "dd957a828b11", + "id": 974323, + "in_service": true, + "ip_address": "10.0.0.13", + "last_seen": "2026-01-02T21:16:11.668173Z", + "mac": "02:00:00:49:C4:49", + "model": "RSMAT500", + "name": "RSMAT-0000000001", + "offset": 0, + "onboarding_date": "2025-11-24T22:30:55.987165Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "auto_advance": true, + "cumulative_steps": 11201, + "daily_average_usage": 151.6634979248047, + "days_till_end_of_roll": 0, + "device_settings": { + "auto_advance": true, + "custom_advance_value": 2.28, + "end_of_roll_monitor": 7, + "fresh_water_aquarium": false, + "model": "RSMAT500", + "position": "left", + "schedule_enable": false, + "schedule_length": 20, + "schedule_time": 0 + }, + "device_setup_date": 1764005514, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "external_ec_average": 0, + "internal_ec_average": 0, + "is_advancing": false, + "last_advance_cause": "self_test", + "lifetime_steps": 30158, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "material": { + "external_diameter": 10.105999946594238, + "is_partial": false, + "name": "28 Meter", + "thickness": 0.02370000071823597 + }, + "mode": "end_of_roll", + "remaining_length": 1.9223999977111816, + "roll_level": "empty", + "setup_date": "2026-01-01T11:29:30Z", + "timezone": -300, + "today_usage": 0, + "total_usage": 2798.04443359375, + "unclean_sensor": false + }, + "ssid": "REDACTED_SSID", + "type": "reef-mat" + }, + { + "aquarium_id": 111113, + "aquarium_uid": "00000000-0000-0000-0000-000000000003", + "board": "esp32", + "bssid": "02:00:01:21:86:CB", + "connected": true, + "firmware_version": "1.11.0", + "framework": "i", + "group_index": 0, + "grouped": false, + "hw_revision": "V1.2A_23B", + "hwid": "1ce62c40421c", + "id": 974385, + "in_service": true, + "ip_address": "10.0.0.14", + "last_seen": "2026-01-03T22:58:48.338262Z", + "mac": "02:00:00:4C:B8:8F", + "model": "RSATO+", + "name": "RSATO+10000000000", + "offset": 0, + "onboarding_date": "2025-11-25T03:15:15.939717Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "ato_sensor": { + "connected": true, + "is_calibrated": true, + "is_sensor_error": false, + "last_adjustment_date": null, + "last_installation_date": 1764040557, + "serial_code": "sc4ffa02131a155a" + }, + "check_sensor": false, + "device_settings": { + "auto_fill": true, + "buzzer": { + "duty_cycle": 50, + "enabled": true, + "frequency": 12 + }, + "flow_rate_override": -1, + "hose": { + "height": 40, + "length": 300 + }, + "leak": { + "dry_threshold": 1, + "emergency_shutdown": false, + "rodi_threshold": 20, + "sensor_enabled": true + }, + "pump_speed_override": -1, + "rvm_enabled": true, + "shortcut_off_delay": 0, + "temp_enabled": true, + "temperature": { + "acceptable_range_high": 28, + "acceptable_range_low": 21, + "code": "515", + "desired_range_high": 26, + "desired_range_low": 23, + "enabled": true, + "log_enabled": true, + "offset": 0 + } + }, + "device_setup_date": 0, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "factory_reset_time": 1716134143, + "is_pump_on": false, + "leak_sensor": { + "buzzer_on": false, + "connected": true, + "status": "dry" + }, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "mode": "auto", + "shortcut_settings": { + "shortcut_off_delay": 0 + }, + "timezone": -300 + }, + "ssid": "REDACTED_SSID", + "type": "reef-ato" + }, + { + "aquarium_id": 111113, + "aquarium_uid": "00000000-0000-0000-0000-000000000003", + "board": "esp32", + "bssid": "02:00:01:F7:34:AE", + "connected": true, + "firmware_version": "3.0.0", + "framework": "a", + "group_index": 0, + "grouped": false, + "hwid": "7f366f7d1803", + "id": 974876, + "in_service": true, + "ip_address": "10.0.0.15", + "last_seen": "2026-01-03T22:58:47.391361Z", + "mac": "02:00:00:49:43:B2", + "model": "RSDOSE2", + "name": "RSDOSE2-000000001", + "offset": 0, + "onboarding_date": "2025-11-25T22:03:46.609809Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "battery_level": "high", + "calibration_reminder": false, + "calibration_reminder_days": 60, + "calibration_reminder_steps": 35000, + "daily_metrics_last_compute_time": 1768608000, + "device_settings": { + "auto_fill_schedule": false, + "bundled_heads": false, + "shortcut_off_delay": 0 + }, + "dosing_waiting_period": 60, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "factory_reset_time": 1577836800, + "feeding": false, + "feeding_1": { + "duration": 20, + "subscribed": false + }, + "feeding_duration": 20, + "file_error": false, + "food_head_schedule": {}, + "heads": { + "1": { + "daily_dose": 4, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 4, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 1762537564, + "nd": 4, + "schedule_enabled": true, + "schedule_type": "custom", + "shortcut_code": "no_shortcut", + "show": true, + "slm": true, + "state": "on", + "supplement": { + "brand_name": "Ocean's Blend", + "concentration": 0, + "display_name": "Alkalinity", + "made_by_redsea": false, + "name": "Alkalinity", + "short_name": "Alk", + "type": "null", + "uid": "e10dbae3-9d4f-4637-91ef-cb30f10e87e0" + }, + "vps": 0.056818 + }, + "2": { + "daily_dose": 4, + "days": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "dc": true, + "dd": 4, + "enable_ratio": true, + "food_delay": 0, + "is_food_head": false, + "last_calibrated": 1762537765, + "nd": 4, + "schedule_enabled": true, + "schedule_type": "custom", + "shortcut_code": "no_shortcut", + "show": true, + "slm": true, + "state": "on", + "supplement": { + "brand_name": "Ocean's Blend", + "concentration": 0, + "display_name": "Calcium", + "made_by_redsea": false, + "name": "Calcium", + "short_name": "Cal", + "type": "null", + "uid": "c9e5ef78-3190-4813-b80c-a38fcee8b5fb" + }, + "vps": 0.059091 + } + }, + "is_factory_reset": false, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "missed_doses_reminder": true, + "mode": "auto", + "ntp_sync": true, + "shortcut_settings": { + "shortcut_off_delay": 0 + }, + "start_of_schedule_for_next_day": 0, + "stock_alert_days": 7, + "time_error": false, + "time_error_unixtime": 0, + "timezone": -300, + "turned_off": false + }, + "ssid": "REDACTED_SSID", + "type": "reef-dosing" + }, + { + "aquarium_id": 111113, + "aquarium_uid": "00000000-0000-0000-0000-000000000003", + "board": "esp32", + "bssid": "02:00:01:21:86:CB", + "connected": true, + "firmware_version": "1.10.2", + "framework": "i", + "group_index": 0, + "grouped": false, + "hw_revision": "v1.0_23A", + "hwid": "840ca07e3087", + "id": 973622, + "in_service": true, + "ip_address": "10.0.0.16", + "last_seen": "2026-01-03T22:58:51.927951Z", + "mac": "02:00:00:E8:AA:EB", + "model": "RSMAT250", + "name": "RSMAT-000000002", + "offset": 0, + "onboarding_date": "2025-11-23T19:26:33.480627Z", + "previously_grouped": false, + "properties": { + "active_shortcut": "no_shortcut", + "auto_advance": true, + "cumulative_steps": 3404, + "daily_average_usage": 62.6347999572754, + "days_till_end_of_roll": 33, + "device_settings": { + "auto_advance": true, + "custom_advance_value": 2.79, + "end_of_roll_monitor": 3, + "fresh_water_aquarium": false, + "model": "RSMAT250", + "position": "right", + "schedule_enable": false, + "schedule_length": 20, + "schedule_time": 0 + }, + "device_setup_date": 1760885816, + "emergency": false, + "emergency_1": { + "subscribed": false + }, + "external_ec_average": 0, + "internal_ec_average": 254, + "is_advancing": false, + "last_advance_cause": "ec_sensor", + "lifetime_steps": 87767, + "maintenance": false, + "maintenance_1": { + "subscribed": false + }, + "material": { + "external_diameter": 10.600000381469727, + "is_partial": false, + "name": "32 Meter", + "thickness": 0.023000000044703484 + }, + "mode": "auto", + "remaining_length": 2078.33740234375, + "roll_level": "full", + "setup_date": "2026-01-03T16:37:46Z", + "timezone": -300, + "today_usage": 39.11090087890625, + "total_usage": 1156.1343994140625, + "unclean_sensor": false + }, + "ssid": "REDACTED_SSID", + "type": "reef-mat" + } +] \ No newline at end of file diff --git a/devices/CLOUD/meta.json b/devices/CLOUD/meta.json new file mode 100644 index 0000000..319d2cd --- /dev/null +++ b/devices/CLOUD/meta.json @@ -0,0 +1,9 @@ +{ + "exported_at": 1768703152, + "server": "cloud.reef-beat.com", + "endpoints": [ + "/user", + "/aquarium", + "/device" + ] +} \ No newline at end of file diff --git a/devices/CLOUD/user/data b/devices/CLOUD/user/data new file mode 100644 index 0000000..312b5bf --- /dev/null +++ b/devices/CLOUD/user/data @@ -0,0 +1,15 @@ +{ + "backup_email": "user@example.com", + "country": "United States", + "country_code": "US", + "created_at": "2025-01-01T00:00:00Z", + "email": "user@example.com", + "first_name": "User", + "id": 123456, + "language": "en", + "last_name": "User", + "mobile_number": "+10000000000", + "onboarding_complete": true, + "uid": "00000000-0000-0000-0000-000000000001", + "zip_code": "00000" +} \ No newline at end of file From a50e3369fac261afc35227ecf4d2136ab46d6904 Mon Sep 17 00:00:00 2001 From: Rob Landry Date: Sun, 25 Jan 2026 08:58:49 -0500 Subject: [PATCH 2/3] Refactor for led naming --- run.py | 119 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 110 insertions(+), 9 deletions(-) diff --git a/run.py b/run.py index fdfab95..e1c5961 100755 --- a/run.py +++ b/run.py @@ -258,6 +258,26 @@ _UUID_RE: Final[re.Pattern[str]] = re.compile(r"uuid:[0-9a-zA-Z\-]+") +# LED model strings look like RSLED90 / RSLED160 / RSLED115. +_RSLED_MODEL_RE: Final[re.Pattern[str]] = re.compile(r"\bRSLED(?P\d+)\b", re.IGNORECASE) + +# Override maps for LED generation inference. +# +# Some firmwares report ambiguous hw_revision strings (e.g. "v2.2_23F") that don't +# explicitly include "G1"/"G2". By default we assume G1 unless we see "G2" in the +# device identity fields. If you find exceptions, pin them here. +# +# Examples: +# - Override by HWID (preferred / stable): +# LED_GEN_OVERRIDE_BY_HWID = {"521f271d32c8": "G2"} +# +# - Override by name (fallback when hwid is missing or bogus like "null"). +# Note: this must match the *exact* payload["name"] string returned by /device-info +# for your device/firmware (some firmwares append a suffix). +# LED_GEN_OVERRIDE_BY_NAME = {"RSLED90": "G1"} +LED_GEN_OVERRIDE_BY_HWID: Final[dict[str, str]] = {} +LED_GEN_OVERRIDE_BY_NAME: Final[dict[str, str]] = {} + _EMAIL_RE: Final[re.Pattern[str]] = re.compile(r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b") _PHONE_RE: Final[re.Pattern[str]] = re.compile(r"\+\d{7,15}") _RAW_UUID_RE: Final[re.Pattern[str]] = re.compile( @@ -960,9 +980,10 @@ def probe_one(ip: str) -> dict[str, str] | None: payload = cast(dict[str, Any], payload_any) name = payload.get("name") hwid = payload.get("hwid") - model = payload.get("model") - fw = payload.get("firmware_version") - dtype = payload.get("type") + # Different firmware revisions use different key names. + model = payload.get("model") if payload.get("model") is not None else payload.get("hw_model") + fw = payload.get("firmware_version") if payload.get("firmware_version") is not None else payload.get("fw") + dtype = payload.get("type") if payload.get("type") is not None else payload.get("hw_type") if not isinstance(name, str) or not name: return None @@ -1270,6 +1291,10 @@ def iter_urls(device_type: str) -> list[str]: if fixture_urls: return fixture_urls + # Support LED variants (e.g. LED_G1_90) during first-time capture. + if device_type.startswith("LED_"): + return [*BASE_URLS, *LED_URLS] + if device_type not in TYPE_MAP: raise ValueError(f"Unsupported TYPE {device_type!r}. Use one of {sorted(available_device_types())}") return [*BASE_URLS, *TYPE_MAP[device_type]] @@ -1321,7 +1346,7 @@ def detect_device_type(ip: str, *, timeout: int) -> str: timeout: HTTP timeout in seconds. Returns: - Fixture type string (e.g. ``ATO``, ``DOSE4``, ``LED``). + Fixture type string (e.g. ``ATO``, ``DOSE4``, ``LED_G1_90``). Raises: RuntimeError: If the device-info payload is missing/invalid or cannot be mapped. @@ -1332,8 +1357,51 @@ def detect_device_type(ip: str, *, timeout: int) -> str: raise RuntimeError("Could not parse /device-info JSON") payload = cast(dict[str, Any], payload_any) - hw_type = payload.get("hw_type") - hw_model = payload.get("hw_model") + return device_type_from_device_info_payload(payload) + + +def _detect_led_variant( + hw_model_s: str, + hw_revision: Any, + *, + evidence_s: str, + override_gen: str | None, +) -> str | None: + """Map RSLED model/revision to a fixture folder name. + + Examples: + RSLED90 + G1... -> LED_G1_90 + RSLED160 + v2... -> LED_G1_160 (default when generation is ambiguous) + RSLED115 + G2... -> LED_G2_115 + """ + + m = _RSLED_MODEL_RE.search(hw_model_s) + if not m: + return None + size = m.group("size") + + gen = (override_gen or "").strip().upper() if override_gen else "" + if gen not in {"G1", "G2"}: + # Prefer explicit generation markers when present. + rev_s = hw_revision.strip().upper() if isinstance(hw_revision, str) else "" + if "G2" in rev_s or "G2" in evidence_s: + gen = "G2" + else: + # Conservative default: assume G1 unless explicitly G2. + gen = "G1" + + return f"LED_{gen}_{size}" + + +def device_type_from_device_info_payload(payload: Mapping[str, Any]) -> str: + """Convert a /device-info payload into a fixture folder type.""" + + # Prefer hw_* keys; fall back to older/newer key names when present. + hw_type = payload.get("hw_type") if payload.get("hw_type") is not None else payload.get("type") + hw_model = payload.get("hw_model") if payload.get("hw_model") is not None else payload.get("model") + hw_rev = payload.get("hw_revision") + name = payload.get("name") + hwid = payload.get("hwid") hw_type_s = hw_type.strip().lower() if isinstance(hw_type, str) else "" hw_model_s = hw_model.strip().upper() if isinstance(hw_model, str) else "" @@ -1341,7 +1409,23 @@ def detect_device_type(ip: str, *, timeout: int) -> str: if hw_type_s == "reef-ato": return "ATO" if hw_type_s == "reef-lights": - return "LED" + override_gen = None + if isinstance(hwid, str) and hwid and hwid in LED_GEN_OVERRIDE_BY_HWID: + override_gen = LED_GEN_OVERRIDE_BY_HWID[hwid] + elif isinstance(name, str) and name and name in LED_GEN_OVERRIDE_BY_NAME: + override_gen = LED_GEN_OVERRIDE_BY_NAME[name] + + evidence_parts: list[str] = [hw_model_s] + if isinstance(hw_rev, str) and hw_rev: + evidence_parts.append(hw_rev) + if isinstance(name, str) and name: + evidence_parts.append(name) + if isinstance(hwid, str) and hwid: + evidence_parts.append(hwid) + evidence_s = " ".join(evidence_parts).upper() + + led = _detect_led_variant(hw_model_s, hw_rev, evidence_s=evidence_s, override_gen=override_gen) + return led or "LED" if hw_type_s == "reef-run": return "RUN" if hw_type_s == "reef-wave": @@ -1356,14 +1440,31 @@ def detect_device_type(ip: str, *, timeout: int) -> str: return "DOSE4" return "DOSE4" + # Fallback: infer from model string. if "DOSE2" in hw_model_s: return "DOSE2" if "DOSE4" in hw_model_s: return "DOSE4" if "ATO" in hw_model_s: return "ATO" - if "LED" in hw_model_s: - return "LED" + if "RSLED" in hw_model_s or "LED" in hw_model_s: + evidence_parts: list[str] = [hw_model_s] + if isinstance(hw_rev, str) and hw_rev: + evidence_parts.append(hw_rev) + if isinstance(name, str) and name: + evidence_parts.append(name) + if isinstance(hwid, str) and hwid: + evidence_parts.append(hwid) + evidence_s = " ".join(evidence_parts).upper() + + override_gen = None + if isinstance(hwid, str) and hwid and hwid in LED_GEN_OVERRIDE_BY_HWID: + override_gen = LED_GEN_OVERRIDE_BY_HWID[hwid] + elif isinstance(name, str) and name and name in LED_GEN_OVERRIDE_BY_NAME: + override_gen = LED_GEN_OVERRIDE_BY_NAME[name] + + led = _detect_led_variant(hw_model_s, hw_rev, evidence_s=evidence_s, override_gen=override_gen) + return led or "LED" if "RUN" in hw_model_s: return "RUN" if "WAVE" in hw_model_s: From 1fef6caa5eac6ea339e8b985b865da60fc242c3f Mon Sep 17 00:00:00 2001 From: Rob Landry Date: Sun, 25 Jan 2026 09:02:45 -0500 Subject: [PATCH 3/3] Remove cloud from pr for clean diff --- devices/CLOUD/aquarium/data | 155 -------- devices/CLOUD/device/data | 682 ------------------------------------ devices/CLOUD/meta.json | 9 - devices/CLOUD/user/data | 15 - 4 files changed, 861 deletions(-) delete mode 100644 devices/CLOUD/aquarium/data delete mode 100644 devices/CLOUD/device/data delete mode 100644 devices/CLOUD/meta.json delete mode 100644 devices/CLOUD/user/data diff --git a/devices/CLOUD/aquarium/data b/devices/CLOUD/aquarium/data deleted file mode 100644 index 6178823..0000000 --- a/devices/CLOUD/aquarium/data +++ /dev/null @@ -1,155 +0,0 @@ -[ - { - "dst_enabled": false, - "height": 40.64, - "id": 111111, - "length": 60.96, - "measuring_unit": "gallons", - "name": "Aquarium 1", - "net_water_volume": 120, - "online": true, - "properties": { - "emergency": false, - "emergency_1": { - "code": "emergency_1", - "enabled": false, - "name": "Emergency", - "type": "emergency" - }, - "feeding": false, - "feeding_1": { - "code": "feeding_1", - "enabled": false, - "name": "Feeding", - "scheduled_feeding": false, - "skip_next": [], - "start": [], - "type": "feeding" - }, - "led_emergency": false, - "maintenance": false, - "maintenance_1": { - "code": "maintenance_1", - "enabled": false, - "name": "Maintenance", - "type": "maintenance" - }, - "shortcut_reminder": false, - "staggered": false, - "staggered_delay": 0 - }, - "serial_number": "", - "staggered": false, - "staggered_delay": 0, - "system_model": "Aquarium System", - "system_series": "other", - "system_type": "mixed-reef", - "timezone_offset": -300, - "uid": "00000000-0000-0000-0000-000000000001", - "user_uid": "00000000-0000-0000-0000-000000000001", - "water_volume": 80, - "width": 121.92 - }, - { - "dst_enabled": false, - "height": 0.0, - "id": 111112, - "length": 0.0, - "measuring_unit": "gallons", - "name": "Aquarium 2", - "net_water_volume": 20, - "online": false, - "properties": { - "emergency": false, - "emergency_1": { - "code": "emergency_1", - "enabled": false, - "name": "Emergency", - "type": "emergency" - }, - "feeding": false, - "feeding_1": { - "code": "feeding_1", - "enabled": false, - "name": "Feeding", - "scheduled_feeding": false, - "skip_next": [], - "start": [], - "type": "feeding" - }, - "led_emergency": false, - "maintenance": false, - "maintenance_1": { - "code": "maintenance_1", - "enabled": false, - "name": "Maintenance", - "type": "maintenance" - }, - "shortcut_reminder": false, - "staggered": false, - "staggered_delay": 0 - }, - "serial_number": "12345", - "staggered": false, - "staggered_delay": 0, - "system_model": "Aquarium System", - "system_series": "Red Sea MAX", - "system_type": "mixed-reef", - "timezone_offset": -300, - "uid": "00000000-0000-0000-0000-000000000002", - "user_uid": "00000000-0000-0000-0000-000000000001", - "water_volume": 75, - "width": 0.0 - }, - { - "dst_enabled": false, - "height": 0.0, - "id": 111113, - "length": 0.0, - "measuring_unit": "gallons", - "name": "Aquarium 3", - "net_water_volume": 53, - "online": true, - "properties": { - "emergency": false, - "emergency_1": { - "code": "emergency_1", - "enabled": false, - "name": "Emergency", - "type": "emergency" - }, - "feeding": false, - "feeding_1": { - "code": "feeding_1", - "enabled": false, - "name": "Feeding", - "scheduled_feeding": false, - "skip_next": [], - "start": [], - "type": "feeding" - }, - "led_emergency": false, - "maintenance": false, - "maintenance_1": { - "code": "maintenance_1", - "enabled": false, - "name": "Maintenance", - "type": "maintenance" - }, - "shortcut_reminder": false, - "staggered": false, - "staggered_delay": 0 - }, - "serial_number": "11926", - "staggered": false, - "staggered_delay": 0, - "system_model": "Aquarium System", - "system_series": "Red Sea REEFER", - "system_type": "mixed-reef", - "timezone_offset": -300, - "uid": "00000000-0000-0000-0000-000000000003", - "user_uid": "00000000-0000-0000-0000-000000000001", - "water_volume": 200, - "width": 0.0 - } -] \ No newline at end of file diff --git a/devices/CLOUD/device/data b/devices/CLOUD/device/data deleted file mode 100644 index 82e12bf..0000000 --- a/devices/CLOUD/device/data +++ /dev/null @@ -1,682 +0,0 @@ -[ - { - "aquarium_id": 111111, - "aquarium_uid": "00000000-0000-0000-0000-000000000001", - "board": "esp32", - "bssid": "02:00:01:F7:34:AE", - "connected": true, - "firmware_version": "1.11.1", - "framework": "i", - "group_index": 0, - "grouped": false, - "hw_revision": "V1.2A_24C", - "hwid": "0700084ae021", - "id": 990068, - "in_service": true, - "ip_address": "10.0.0.11", - "last_seen": "2026-01-15T20:20:55.949188Z", - "mac": "02:00:00:EA:92:7D", - "model": "RSATO+", - "name": "RSATO+10000000000", - "offset": 0, - "onboarding_date": "2025-12-21T23:07:17.192522Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "ato_sensor": { - "connected": true, - "is_calibrated": true, - "is_sensor_error": false, - "last_adjustment_date": null, - "last_installation_date": 1766358323, - "serial_code": "cfaeed54730f5d5d" - }, - "check_sensor": false, - "device_settings": { - "auto_fill": true, - "buzzer": { - "duty_cycle": 50, - "enabled": true, - "frequency": 12 - }, - "flow_rate_override": -1, - "hose": { - "height": 38, - "length": 137 - }, - "leak": { - "dry_threshold": 1, - "emergency_shutdown": false, - "rodi_threshold": 20, - "sensor_enabled": true - }, - "pump_speed_override": -1, - "rvm_enabled": true, - "shortcut_off_delay": 0, - "temp_enabled": false, - "temperature": { - "acceptable_range_high": 28, - "acceptable_range_low": 21, - "code": "515", - "desired_range_high": 26, - "desired_range_low": 23, - "enabled": false, - "log_enabled": false, - "offset": 0 - } - }, - "device_setup_date": 1766340517, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "factory_reset_time": 1766340517, - "is_pump_on": false, - "leak_sensor": { - "buzzer_on": false, - "connected": true, - "status": "dry" - }, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "mode": "auto", - "shortcut_settings": { - "shortcut_off_delay": 0 - }, - "timezone": -300 - }, - "ssid": "REDACTED_SSID", - "type": "reef-ato" - }, - { - "aquarium_id": 111111, - "aquarium_uid": "00000000-0000-0000-0000-000000000001", - "board": "esp32", - "bssid": "02:00:01:F7:34:AE", - "connected": true, - "firmware_version": "3.0.0", - "framework": "a", - "group_index": 0, - "grouped": false, - "hwid": "ae8f6238d45a", - "id": 961753, - "in_service": true, - "ip_address": "10.0.0.12", - "last_seen": "2026-01-02T21:47:42.294008Z", - "mac": "02:00:00:23:79:22", - "model": "RSDOSE4", - "name": "RSDOSE4-000000001", - "offset": 0, - "onboarding_date": "2025-11-01T21:18:49.887027Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "battery_level": "high", - "calibration_reminder": false, - "calibration_reminder_days": 60, - "calibration_reminder_steps": 35000, - "daily_metrics_last_compute_time": 1768608000, - "device_settings": { - "auto_fill_schedule": false, - "bundled_heads": false, - "shortcut_off_delay": 0 - }, - "dosing_waiting_period": 60, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "factory_reset_time": 1577836800, - "feeding": false, - "feeding_1": { - "duration": 20, - "subscribed": false - }, - "feeding_duration": 20, - "file_error": false, - "food_head_schedule": {}, - "heads": { - "1": { - "daily_dose": 0, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 0, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 0, - "nd": 1, - "schedule_enabled": false, - "schedule_type": "single", - "shortcut_code": "no_shortcut", - "show": false, - "slm": true, - "state": "not-setup", - "supplement": { - "brand_name": "Red Sea", - "concentration": 0, - "display_name": "Coral food", - "made_by_redsea": true, - "name": "Reef Energy Plus", - "short_name": "RE+", - "type": "null", - "uid": "bf9a7da3-741b-4c1d-8542-d9344a95fb70" - }, - "vps": 0 - }, - "2": { - "daily_dose": 0, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 0, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 1762103199, - "nd": 1, - "schedule_enabled": false, - "schedule_type": "single", - "shortcut_code": "no_shortcut", - "show": true, - "slm": true, - "state": "on", - "supplement": { - "brand_name": "API", - "concentration": 0, - "display_name": "Magnesium", - "made_by_redsea": false, - "name": "Magnesium", - "short_name": "Mag", - "type": "null", - "uid": "184238cc-8840-4a47-9e0e-d22ad5e3f6fe" - }, - "vps": 0.075758 - }, - "3": { - "daily_dose": 10, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 10, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 1762102146, - "nd": 24, - "schedule_enabled": true, - "schedule_type": "hourly", - "shortcut_code": "no_shortcut", - "show": true, - "slm": true, - "state": "on", - "supplement": { - "brand_name": "Ocean's Blend", - "concentration": 0, - "display_name": "Calcium", - "made_by_redsea": false, - "name": "Calcium (Part 1)", - "short_name": "Cal", - "type": "null", - "uid": "55a13d1a-c217-45f9-aa0f-640160a3c166" - }, - "vps": 0.075758 - }, - "4": { - "daily_dose": 10, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 10, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 1762101944, - "nd": 24, - "schedule_enabled": false, - "schedule_type": "hourly", - "shortcut_code": "no_shortcut", - "show": true, - "slm": true, - "state": "on", - "supplement": { - "brand_name": "Ocean's Blend", - "concentration": 0, - "display_name": "Alkalinity", - "made_by_redsea": false, - "name": "Alkalinity (Part 2)", - "short_name": "Alk", - "type": "null", - "uid": "6537abd2-4bce-43db-a567-360dab0684aa" - }, - "vps": 0.075758 - } - }, - "is_factory_reset": false, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "missed_doses_reminder": true, - "mode": "auto", - "ntp_sync": true, - "shortcut_settings": { - "shortcut_off_delay": 0 - }, - "start_of_schedule_for_next_day": 0, - "stock_alert_days": 7, - "time_error": false, - "time_error_unixtime": 0, - "timezone": -300, - "turned_off": false - }, - "ssid": "REDACTED_SSID", - "type": "reef-dosing" - }, - { - "aquarium_id": 111111, - "aquarium_uid": "00000000-0000-0000-0000-000000000001", - "board": "esp32", - "bssid": "02:00:01:F7:34:AE", - "connected": true, - "firmware_version": "1.10.2", - "framework": "i", - "group_index": 0, - "grouped": false, - "hw_revision": "v0.4_24G", - "hwid": "dd957a828b11", - "id": 974323, - "in_service": true, - "ip_address": "10.0.0.13", - "last_seen": "2026-01-02T21:16:11.668173Z", - "mac": "02:00:00:49:C4:49", - "model": "RSMAT500", - "name": "RSMAT-0000000001", - "offset": 0, - "onboarding_date": "2025-11-24T22:30:55.987165Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "auto_advance": true, - "cumulative_steps": 11201, - "daily_average_usage": 151.6634979248047, - "days_till_end_of_roll": 0, - "device_settings": { - "auto_advance": true, - "custom_advance_value": 2.28, - "end_of_roll_monitor": 7, - "fresh_water_aquarium": false, - "model": "RSMAT500", - "position": "left", - "schedule_enable": false, - "schedule_length": 20, - "schedule_time": 0 - }, - "device_setup_date": 1764005514, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "external_ec_average": 0, - "internal_ec_average": 0, - "is_advancing": false, - "last_advance_cause": "self_test", - "lifetime_steps": 30158, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "material": { - "external_diameter": 10.105999946594238, - "is_partial": false, - "name": "28 Meter", - "thickness": 0.02370000071823597 - }, - "mode": "end_of_roll", - "remaining_length": 1.9223999977111816, - "roll_level": "empty", - "setup_date": "2026-01-01T11:29:30Z", - "timezone": -300, - "today_usage": 0, - "total_usage": 2798.04443359375, - "unclean_sensor": false - }, - "ssid": "REDACTED_SSID", - "type": "reef-mat" - }, - { - "aquarium_id": 111113, - "aquarium_uid": "00000000-0000-0000-0000-000000000003", - "board": "esp32", - "bssid": "02:00:01:21:86:CB", - "connected": true, - "firmware_version": "1.11.0", - "framework": "i", - "group_index": 0, - "grouped": false, - "hw_revision": "V1.2A_23B", - "hwid": "1ce62c40421c", - "id": 974385, - "in_service": true, - "ip_address": "10.0.0.14", - "last_seen": "2026-01-03T22:58:48.338262Z", - "mac": "02:00:00:4C:B8:8F", - "model": "RSATO+", - "name": "RSATO+10000000000", - "offset": 0, - "onboarding_date": "2025-11-25T03:15:15.939717Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "ato_sensor": { - "connected": true, - "is_calibrated": true, - "is_sensor_error": false, - "last_adjustment_date": null, - "last_installation_date": 1764040557, - "serial_code": "sc4ffa02131a155a" - }, - "check_sensor": false, - "device_settings": { - "auto_fill": true, - "buzzer": { - "duty_cycle": 50, - "enabled": true, - "frequency": 12 - }, - "flow_rate_override": -1, - "hose": { - "height": 40, - "length": 300 - }, - "leak": { - "dry_threshold": 1, - "emergency_shutdown": false, - "rodi_threshold": 20, - "sensor_enabled": true - }, - "pump_speed_override": -1, - "rvm_enabled": true, - "shortcut_off_delay": 0, - "temp_enabled": true, - "temperature": { - "acceptable_range_high": 28, - "acceptable_range_low": 21, - "code": "515", - "desired_range_high": 26, - "desired_range_low": 23, - "enabled": true, - "log_enabled": true, - "offset": 0 - } - }, - "device_setup_date": 0, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "factory_reset_time": 1716134143, - "is_pump_on": false, - "leak_sensor": { - "buzzer_on": false, - "connected": true, - "status": "dry" - }, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "mode": "auto", - "shortcut_settings": { - "shortcut_off_delay": 0 - }, - "timezone": -300 - }, - "ssid": "REDACTED_SSID", - "type": "reef-ato" - }, - { - "aquarium_id": 111113, - "aquarium_uid": "00000000-0000-0000-0000-000000000003", - "board": "esp32", - "bssid": "02:00:01:F7:34:AE", - "connected": true, - "firmware_version": "3.0.0", - "framework": "a", - "group_index": 0, - "grouped": false, - "hwid": "7f366f7d1803", - "id": 974876, - "in_service": true, - "ip_address": "10.0.0.15", - "last_seen": "2026-01-03T22:58:47.391361Z", - "mac": "02:00:00:49:43:B2", - "model": "RSDOSE2", - "name": "RSDOSE2-000000001", - "offset": 0, - "onboarding_date": "2025-11-25T22:03:46.609809Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "battery_level": "high", - "calibration_reminder": false, - "calibration_reminder_days": 60, - "calibration_reminder_steps": 35000, - "daily_metrics_last_compute_time": 1768608000, - "device_settings": { - "auto_fill_schedule": false, - "bundled_heads": false, - "shortcut_off_delay": 0 - }, - "dosing_waiting_period": 60, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "factory_reset_time": 1577836800, - "feeding": false, - "feeding_1": { - "duration": 20, - "subscribed": false - }, - "feeding_duration": 20, - "file_error": false, - "food_head_schedule": {}, - "heads": { - "1": { - "daily_dose": 4, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 4, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 1762537564, - "nd": 4, - "schedule_enabled": true, - "schedule_type": "custom", - "shortcut_code": "no_shortcut", - "show": true, - "slm": true, - "state": "on", - "supplement": { - "brand_name": "Ocean's Blend", - "concentration": 0, - "display_name": "Alkalinity", - "made_by_redsea": false, - "name": "Alkalinity", - "short_name": "Alk", - "type": "null", - "uid": "e10dbae3-9d4f-4637-91ef-cb30f10e87e0" - }, - "vps": 0.056818 - }, - "2": { - "daily_dose": 4, - "days": [ - 1, - 2, - 3, - 4, - 5, - 6, - 7 - ], - "dc": true, - "dd": 4, - "enable_ratio": true, - "food_delay": 0, - "is_food_head": false, - "last_calibrated": 1762537765, - "nd": 4, - "schedule_enabled": true, - "schedule_type": "custom", - "shortcut_code": "no_shortcut", - "show": true, - "slm": true, - "state": "on", - "supplement": { - "brand_name": "Ocean's Blend", - "concentration": 0, - "display_name": "Calcium", - "made_by_redsea": false, - "name": "Calcium", - "short_name": "Cal", - "type": "null", - "uid": "c9e5ef78-3190-4813-b80c-a38fcee8b5fb" - }, - "vps": 0.059091 - } - }, - "is_factory_reset": false, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "missed_doses_reminder": true, - "mode": "auto", - "ntp_sync": true, - "shortcut_settings": { - "shortcut_off_delay": 0 - }, - "start_of_schedule_for_next_day": 0, - "stock_alert_days": 7, - "time_error": false, - "time_error_unixtime": 0, - "timezone": -300, - "turned_off": false - }, - "ssid": "REDACTED_SSID", - "type": "reef-dosing" - }, - { - "aquarium_id": 111113, - "aquarium_uid": "00000000-0000-0000-0000-000000000003", - "board": "esp32", - "bssid": "02:00:01:21:86:CB", - "connected": true, - "firmware_version": "1.10.2", - "framework": "i", - "group_index": 0, - "grouped": false, - "hw_revision": "v1.0_23A", - "hwid": "840ca07e3087", - "id": 973622, - "in_service": true, - "ip_address": "10.0.0.16", - "last_seen": "2026-01-03T22:58:51.927951Z", - "mac": "02:00:00:E8:AA:EB", - "model": "RSMAT250", - "name": "RSMAT-000000002", - "offset": 0, - "onboarding_date": "2025-11-23T19:26:33.480627Z", - "previously_grouped": false, - "properties": { - "active_shortcut": "no_shortcut", - "auto_advance": true, - "cumulative_steps": 3404, - "daily_average_usage": 62.6347999572754, - "days_till_end_of_roll": 33, - "device_settings": { - "auto_advance": true, - "custom_advance_value": 2.79, - "end_of_roll_monitor": 3, - "fresh_water_aquarium": false, - "model": "RSMAT250", - "position": "right", - "schedule_enable": false, - "schedule_length": 20, - "schedule_time": 0 - }, - "device_setup_date": 1760885816, - "emergency": false, - "emergency_1": { - "subscribed": false - }, - "external_ec_average": 0, - "internal_ec_average": 254, - "is_advancing": false, - "last_advance_cause": "ec_sensor", - "lifetime_steps": 87767, - "maintenance": false, - "maintenance_1": { - "subscribed": false - }, - "material": { - "external_diameter": 10.600000381469727, - "is_partial": false, - "name": "32 Meter", - "thickness": 0.023000000044703484 - }, - "mode": "auto", - "remaining_length": 2078.33740234375, - "roll_level": "full", - "setup_date": "2026-01-03T16:37:46Z", - "timezone": -300, - "today_usage": 39.11090087890625, - "total_usage": 1156.1343994140625, - "unclean_sensor": false - }, - "ssid": "REDACTED_SSID", - "type": "reef-mat" - } -] \ No newline at end of file diff --git a/devices/CLOUD/meta.json b/devices/CLOUD/meta.json deleted file mode 100644 index 319d2cd..0000000 --- a/devices/CLOUD/meta.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "exported_at": 1768703152, - "server": "cloud.reef-beat.com", - "endpoints": [ - "/user", - "/aquarium", - "/device" - ] -} \ No newline at end of file diff --git a/devices/CLOUD/user/data b/devices/CLOUD/user/data deleted file mode 100644 index 312b5bf..0000000 --- a/devices/CLOUD/user/data +++ /dev/null @@ -1,15 +0,0 @@ -{ - "backup_email": "user@example.com", - "country": "United States", - "country_code": "US", - "created_at": "2025-01-01T00:00:00Z", - "email": "user@example.com", - "first_name": "User", - "id": 123456, - "language": "en", - "last_name": "User", - "mobile_number": "+10000000000", - "onboarding_complete": true, - "uid": "00000000-0000-0000-0000-000000000001", - "zip_code": "00000" -} \ No newline at end of file