diff --git a/docs/images/bridge.png b/docs/images/bridge.png index 490399f..e7ca849 100644 Binary files a/docs/images/bridge.png and b/docs/images/bridge.png differ diff --git a/docs/images/fixture.json b/docs/images/fixture.json index 3173789..9504a8b 100644 --- a/docs/images/fixture.json +++ b/docs/images/fixture.json @@ -3,7 +3,7 @@ "bridge": { "id": "heliograph-a1b2c3", "name": "Heliograph", - "firmware_version": "0.25.1 (Jul 31 2026 10:11:29)", + "firmware_version": "0.27.2 (Aug 27 2026 08:36:35)", "board_id": "rs485-can", "ip_address": "192.168.1.50", "ip_mode": "dhcp", @@ -11,18 +11,18 @@ "devices_configured": 1, "devices_started": 1, "device_problems": [], - "uptime_seconds": 5710, + "uptime_seconds": 8503, "wifi_connected": true, - "wifi_rssi_dbm": -53, + "wifi_rssi_dbm": -55, "mqtt_connected": true, "modbus_listening": true, "modbus_clients": 0, "time_synced": true, - "time": "2026-07-31 13:50:59", - "ntp_last_sync": "2026-07-31 12:15:59", + "time": "2026-08-27 13:02:21", + "ntp_last_sync": "2026-08-27 10:40:44", "ntp_server": "pool.ntp.org", "ntp_server_source": "dhcp", - "free_heap_bytes": 135508, + "free_heap_bytes": 144468, "boot_button_pressed": false }, "device": { @@ -37,79 +37,79 @@ "data_valid": true, "data_stale": false, "consecutive_poll_failures": 0, - "last_successful_poll_seconds_ago": 8 + "last_successful_poll_seconds_ago": 6 }, "measurements": { "ac.power.total": { - "value": 2608, + "value": 2076, "unit": "W", "valid": true, "stale": false }, "ac.phase_l1.voltage": { - "value": 243.8, + "value": 239.7, "unit": "V", "valid": true, "stale": false }, "ac.phase_l1.current": { - "value": 10.6, + "value": 8.6, "unit": "A", "valid": true, "stale": false }, "ac.frequency": { - "value": 50.01, + "value": 49.98, "unit": "Hz", "valid": true, "stale": false }, "dc.mppt_1.voltage": { - "value": 323.9, + "value": 323.8, "unit": "V", "valid": true, "stale": false }, "dc.mppt_1.current": { - "value": 8.3, + "value": 6.6, "unit": "A", "valid": true, "stale": false }, "dc.mppt_1.power": { - "value": 2688.37, + "value": 2137.08, "unit": "W", "valid": true, "stale": false, "derived": true }, "dc.power.total": { - "value": 2688.37, + "value": 2137.08, "unit": "W", "valid": true, "stale": false, "derived": true }, "energy.today": { - "value": 5.35, + "value": 2.57, "unit": "kWh", "valid": true, "stale": false }, "energy.total": { - "value": 35613.1, + "value": 35997.8, "unit": "kWh", "valid": true, "stale": false }, "inverter.temperature": { - "value": 45, + "value": 40, "unit": "\u00b0C", "valid": true, "stale": false }, "inverter.operating_hours": { - "value": 47596, + "value": 47996, "unit": "h", "valid": true, "stale": false @@ -126,26 +126,26 @@ "data_valid": true, "data_stale": false, "modbus_unit_id": 1, - "last_successful_poll_seconds_ago": 8, - "energy_today_kwh": 5.35, - "ac_voltage_v": 243.8, - "temperature_c": 45, + "last_successful_poll_seconds_ago": 6, + "energy_today_kwh": 2.57, + "ac_voltage_v": 239.7, + "temperature_c": 40, "battery_soc_pct": null, "battery_power_w": null, - "ac_power_w": 2608 + "ac_power_w": 2076 } ], "totals": { "devices_answering": 1, "devices_polled": 1, - "ac_power_w": 2608, + "ac_power_w": 2076, "ac_power_devices": 1, - "energy_today_kwh": 5.35, + "energy_today_kwh": 2.57, "energy_today_devices": 1, - "energy_total_kwh": 35613.1, + "energy_total_kwh": 35997.8, "energy_total_devices": 1 }, - "poll_success_total": 559, + "poll_success_total": 834, "poll_failure_total": 1 }, "config": { @@ -221,12 +221,12 @@ } }, "diagnostics": { - "uptime_seconds": 5710, - "firmware_version": "0.25.1 (Jul 31 2026 10:11:29)", + "uptime_seconds": 8503, + "firmware_version": "0.27.2 (Aug 27 2026 08:36:35)", "board": "Waveshare ESP32-S3-RS485-CAN", - "free_heap_bytes": 135752, - "minimum_free_heap_bytes": 107372, - "max_alloc_heap_bytes": 90100, + "free_heap_bytes": 144712, + "minimum_free_heap_bytes": 88980, + "max_alloc_heap_bytes": 94196, "psram_size_bytes": 8388608, "psram_free_bytes": 8378140, "reset_reason": 3, @@ -238,19 +238,19 @@ "coredump_cause_name": null, "coredump_fault_address": null, "wifi_connected": true, - "wifi_rssi_dbm": -53, + "wifi_rssi_dbm": -55, "mqtt_connected": true, "time_synced": true, - "time": "2026-07-31 13:50:59", - "ntp_last_sync": "2026-07-31 12:15:59", + "time": "2026-08-27 13:02:21", + "ntp_last_sync": "2026-08-27 10:40:44", "ntp_server": "pool.ntp.org", "ntp_server_source": "dhcp", - "poll_success_total": 559, - "poll_duration_count": 559, - "poll_duration_last_ms": 103, - "poll_duration_min_ms": 97, + "poll_success_total": 834, + "poll_duration_count": 834, + "poll_duration_last_ms": 101, + "poll_duration_min_ms": 99, "poll_duration_max_ms": 108, - "poll_duration_ewma_ms": 102, + "poll_duration_ewma_ms": 101, "poll_failure_total": 1, "consecutive_poll_failures": 0, "checksum_error_total": 0, @@ -259,15 +259,15 @@ "wifi_reconnect_total": 0, "mqtt_reconnect_total": 0, "modbus_client_connections_total": 0, - "rest_requests_total": 5602, + "rest_requests_total": 16, "mqtt_publish_failure_total": 0, - "last_successful_poll_ms": 5702164, - "rs485_stack_free_bytes": 3356, - "loop_stack_free_bytes": 3672, + "last_successful_poll_ms": 8496462, + "rs485_stack_free_bytes": 3264, + "loop_stack_free_bytes": 3624, "last_error": "poll failed: timeout", - "boot_count": 4, - "previous_uptime_ms": 55258153, - "previous_firmware": "0.25.0", + "boot_count": 11, + "previous_uptime_ms": 1341958057, + "previous_firmware": "0.27.1", "coredump_backtrace": null, "coredump_backtrace_corrupted": null }, @@ -318,6 +318,36 @@ } ] }, + { + "id": "0000000001", + "display_name": "SolarMax (MaxTalk RS485)", + "manufacturer": "SolarMax", + "protocol": "MaxTalk RS485", + "support_level": "experimental", + "supports_read": true, + "supports_write": false, + "auto_detection": true, + "supports_multiple_devices": false, + "serial_profiles": [ + { + "baud_rate": 19200, + "parity": "none", + "data_bits": 8, + "stop_bits": 1 + } + ], + "options": [ + { + "key": "address", + "display_name": "Inverter address", + "description": "The address set in the inverter's own display menu. Each unit on a shared bus needs its own; there is no auto-assignment in this protocol, so a duplicate here is a duplicate on the wire.", + "default_value": "1", + "min_value": 0, + "max_value": 255, + "allowed_values": [] + } + ] + }, { "id": "eversolar_legacy", "display_name": "Ever-Solar / Zeversolar (legacy PMU)", @@ -436,6 +466,8 @@ "min_tl_x", "sph", "huawei_sun2000", + "sofar_hyd_3ph", + "sofar_hyd_ep", "solis_rhi_hybrid", "sungrow_sh_hybrid" ], @@ -447,6 +479,8 @@ "Growatt MIN TL-X (2.5-6 kW) \u2014 Growatt (experimental)", "Growatt SPH (3-6 kW) \u2014 Growatt (experimental)", "Huawei SUN2000 (residential) \u2014 Huawei (experimental)", + "Sofar HYD 5\u202620K-3PH hybrid (three phase) \u2014 Sofar Solar (experimental)", + "Sofar HYD 3\u20266K-EP hybrid (single phase) \u2014 Sofar Solar (experimental)", "Solis RHI hybrid (3-6 kW, single phase) \u2014 Solis (experimental)", "Sungrow SH residential hybrid \u2014 Sungrow (experimental)" ] diff --git a/docs/images/health.png b/docs/images/health.png index 6e09140..1c10641 100644 Binary files a/docs/images/health.png and b/docs/images/health.png differ diff --git a/docs/images/integrations.png b/docs/images/integrations.png index 0b20f30..a32d9d5 100644 Binary files a/docs/images/integrations.png and b/docs/images/integrations.png differ diff --git a/docs/images/inverters.png b/docs/images/inverters.png index 6c83539..4d27f23 100644 Binary files a/docs/images/inverters.png and b/docs/images/inverters.png differ diff --git a/docs/images/live.png b/docs/images/live.png index 9ab057c..7930bf5 100644 Binary files a/docs/images/live.png and b/docs/images/live.png differ