{"id":31044856,"url":"https://github.com/ixtalo/sf800pro2mqtt","last_synced_at":"2025-09-14T16:52:19.471Z","repository":{"id":304468166,"uuid":"1018871346","full_name":"Ixtalo/SF800Pro2MQTT","owner":"Ixtalo","description":"Capture TCP traffic from a SolarFlow 800 Pro solar battery and extract information for publishing to an own (local) MQTT broker.","archived":false,"fork":false,"pushed_at":"2025-08-22T19:53:53.000Z","size":322,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-08-22T21:56:24.082Z","etag":null,"topics":["battery","home-assistant","mqtt","smarthome","solar-energy","solarflow","zendure"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Ixtalo.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-07-13T08:24:09.000Z","updated_at":"2025-08-22T19:53:22.000Z","dependencies_parsed_at":"2025-07-13T10:27:36.926Z","dependency_job_id":"95b1c82d-216d-4749-9af9-2533ffd1c5af","html_url":"https://github.com/Ixtalo/SF800Pro2MQTT","commit_stats":null,"previous_names":["ixtalo/sf800pro2mqtt"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/Ixtalo/SF800Pro2MQTT","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ixtalo%2FSF800Pro2MQTT","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ixtalo%2FSF800Pro2MQTT/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ixtalo%2FSF800Pro2MQTT/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ixtalo%2FSF800Pro2MQTT/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Ixtalo","download_url":"https://codeload.github.com/Ixtalo/SF800Pro2MQTT/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Ixtalo%2FSF800Pro2MQTT/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":275136706,"owners_count":25411709,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-14T02:00:10.474Z","response_time":75,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["battery","home-assistant","mqtt","smarthome","solar-energy","solarflow","zendure"],"created_at":"2025-09-14T16:52:17.232Z","updated_at":"2025-09-14T16:52:19.455Z","avatar_url":"https://github.com/Ixtalo.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SolarFlow 800 Pro to Mqtt (via network traffic sniffing)\n\nCapture TCP traffic from a SolarFlow 800 Pro solar battery and\nextract information for publishing to an own (local) MQTT broker.\n\nThe tool is intended for quick, non-intrusive integrations of the “cloud only” /\n\"app only\" IoT device, here the solar battery *SolarFlow 800 Pro*.\n\n## Motivation\n\nThis integration tool is rooted in the desire for resilience, security, user autonomy, cost-effectiveness, scalability, and sustainability. By enabling local, air-gapped applications, users can leverage IoT technologies while minimizing risks and maximizing control over their systems.\n\n- *Air-Gapped*: The tool allows for the integration of IoT devices without relying on cloud services, which can be vulnerable to outages, data breaches, or service disruptions. By operating in an air-gapped environment, users can ensure that their systems remain functional even without internet connectivity.\n- *Local Control*: maintain control over your own devices locally, reducing the risk associated with external dependencies.\n- *Minimized Data Exposure*: sensitive data generated by the IoT devices can be kept within the local network. This helps protect against unauthorized access and potential data leaks.\n- *Enhanced Security*: implement tailored security measures, reduce the attack surface.\n- *Adaptability / No Lock-In*: not tied to specific cloud providers this can facilitate accommodation of emerging technologies and protocols,  without being locked into a specific ecosystem.\n- *Customizable Integrations*: facilitate quick integration in other home applicances, e.g., Home Assistant.\n- *Lower Operational Costs*: save on subscription fees and data transfer costs.\n- *Efficient Resource Utilization*:better utilization of existing infrastructure, reducing the need for additional cloud resources.\n- *Reduced Energy Consumption*: no resource and energy hungry cloud infrastructure, no data transmission to and from cloud services.\n\n\n## My Setup\n\n![Setup](./doc/setup.png)\n\n```mermaid\nflowchart TD\n    subgraph \"Server (Linux)\"\n    USBWifi[/fa:fa-usb RT5572 USB WiFi Adapter/]\n    Server[fa:fa-server Server with MQTT]\n\n    USBWifi === Server\n    Server \u003c--\u003e HA[Home Assistant]\n    Server ==tcp capture/sniff==\u003e Sniffer[/**SF800Pro2MQTT**/] --mqtt--\u003e Server\n    end\n\n    SF800Pro[fa:fa-car-battery SF800Pro]\n    SF800Pro ==fa:fa-wifi IoT SSID==\u003e USBWifi\n\n    Server --tcp fwd--\u003e Internet([fa:fa-cloud Internet])\n    Internet --mqtt--\u003e mqtteu[/fa:fa-cloud-arrow-down mqtteu.zen-iot.com/]\n```\n\n---\n\n## Features\n\n| Feature | Description |\n|---------|-------------|\n| Live packet sniffing | Uses Scapy with a BPF filter (`tcp and host …`). |\n| Zero parsing configs | Topic + payload are detected by RegEx. |\n| MQTT forwarding | Publishes to any broker (TLS/Auth optional). |\n| Minimal dependencies | `scapy` and `paho-mqtt`. |\n| Runs on Linux \u0026 Raspberry Pi | Root privileges only required for sniffing. |\n\n\n## Prerequisites\n\n* Python ≥ 3.11\n* Poetry 2.x\n* Linux with `libpcap` (already present on most systems)\n* Root/sudo rights to capture on the interface\n* An MQTT broker you can publish to\n\n\n## How-To Run\n\n1. `poetry sync --only=main`\n2. `cp env.template .env`, then adjust values to your setup\n3. Make sure all servers are set up and ready, e.g. MQTT.\n4. `sudo poetry run python sf800psniff2mqtt.py`\n\nFor permanent installation have a look at `systemd/`.\n\n\n## Example Output / Messages\n\n| Topic | Payload (trimmed) |\n|-------|-------------------|\n| `/R3mn8U/deviceId/function/invoke` | `{\"messageId\":669682,\"function\":\"hemsEP\",\"arguments\":{\"outputPower\":0,\"chargePower\":125, ...}}` |\n| `/R3mn8U/deviceId/function/invoke/reply` | `{\"messageId\":669682,\"mode\":9,\"chargeMode\":3,\"timestamp\":1751115741,\"success\":true}` |\n| `/R3mn8U/deviceId/properties/energy` | `{\"messageId\":13747,\"timestamp\":1751115744,\"properties\":{\"gridOffPower\":0,\"chargePower\":0, ...}}` |\n\n\n## Solar Flow 800 Pro MQTT Values\n\n\n| **Field Name**                     | **Field Description (presumably)**                                   |\n|------------------------------------|-----------------------------------------------------------------------|\n| energy                             | |\n| energy.deviceId                    | Unique ID of the solar battery device.                                |\n| energy.messageId                   | Sequential message identifier.                                        |\n| energy.product                     | Device model name.                                                    |\n| energy.timestamp                   | Epoch timestamp when data was recorded.                               |\n| energy.version                     | Message format version (in 07/2025 it is '2').                         |\n| energy.properties.gridOffPower     | Power in off-grid mode (watts).                                       |\n| energy.properties.chargePower      | ... |\n| energy.properties.outputPower      | ... |\n| energy.properties.mode             | ... |\n| energy.properties.chargeMode       | ... |\n| energy.properties.LCNState         | Local control network state.                                          |\n| report                             | |\n| report.deviceId                    | Unique ID of the solar battery device.                                |\n| report.messageId                   | Sequential message identifier.                                        |\n| report.product                     | Device model name.                                                    |\n| report.timestamp                   | Epoch timestamp when data was recorded.                               |\n| report.version                     | Message format version (in 07/2025 it is '2').                         |\n| report.packData[]                  | List of battery pack metrics (can contain multiple entries).          |\n| report.packData[].batcur           | Battery current (unit likely deci-amps, raw value may need scaling).  |\n| report.packData[].maxTemp          | Battery pack temperature; Celsius = (value / 10) - 273.15             |\n| report.packData[].maxVol           | Maximum cell voltage (unit tenths of volt).                           |\n| report.packData[].minVol           | Minimum cell voltage (unit tenths of volt).                           |\n| report.packData[].packType         | Encoded type or configuration of the battery pack.                    |\n| report.packData[].power            | Power value (watts).                                                  |\n| report.packData[].sn               | Serial number of the battery pack.                                    |\n| report.packData[].socLevel         | State of charge (percentage).                                         |\n| report.packData[].softVersion      | Firmware (software) version (e.g., 4117).                             |\n| report.packData[].state            | Operational state code (0=idle, 1=charging, 2=discharing).            |\n| report.packData[].totalVol         | Total voltage of the battery pack                                     |\n| report.properties                  | Real-time operational properties of the system.                       |\n| report.properties.BatVolt          | Current battery voltage.                                              |\n| report.properties.Fanmode          | Fan control mode (0=auto?, 1=manual?).                                |\n| report.properties.Fanspeed         | Current fan speed setting.                                            |\n| report.properties.IOTState         | IoT connectivity state (2=WiFi+Cloud connected).                      |\n| report.properties.LCNState         | Local control network state.                                          |\n| report.properties.OTAState         | Over-the-air update status.                                           |\n| report.properties.VoltWakeup       | Voltage threshold for system wake-up.                                 |\n| report.properties.acMode           | AC mode (2=on-grid).                                                  |\n| report.properties.acStatus         | AC output status (0=off, 1=on).                                       |\n| report.properties.aiState          | AI feature status (0=off, 1=on).                                      |\n| report.properties.bindstate        | Binding status with app/cloud.                                        |\n| report.properties.chargeMaxLimit   | Max charge power limit (watts).                                       |\n| report.properties.dataReady        | Flag indicating new data is available.                                |\n| report.properties.dcStatus         | DC output/input state.                                                |\n| report.properties.electricLevel    | Battery level (%).                                                    |\n| report.properties.factoryModeState | Factory/test mode active (0=no, 1=yes).                               |\n| report.properties.gridInputPower   | Grid power being drawn (watts).                                       |\n| report.properties.gridOffMode      | Off-grid operation mode (0=off, 1=on).                                |\n| report.properties.gridOffPower     | Power in off-grid mode (watts).                                       |\n| report.properties.gridReverse      | Grid reverse mode.                                                    |\n| report.properties.gridStandard     | Regional grid standard.                                               |\n| report.properties.gridState        | Grid connection status (0=not connected, 1=connected).                |\n| report.properties.heatState        | Heating system active (0=off, 1=on).                                  |\n| report.properties.hyperTmp         | HUB temperature sensor; Celsius = (value / 10) - 273.15               |\n| report.properties.inputLimit       | Max allowed input power (watts), typically dynamic.                   |\n| report.properties.inverseMaxPower  | Inverter max output power (watts), typically 800.                     |\n| report.properties.lampSwitch       | LED indicator state (0=off, 1=on).                                    |\n| report.properties.minSoc           | Lower SoC target (unit tenths of %), typically 100=10%.               |\n| report.properties.oldMode          | Legacy mode active (if any).                                          |\n| report.properties.outputHomePower  | Power currently supplied (watts), i.e., battery power delivery.       |\n| report.properties.outputLimit      | Max power allowed to output (watts), typically dynamic.               |\n| report.properties.outputPackPower  | Power charging into the battery pack.                                 |\n| report.properties.packInputPower   | Power being discharged from pack.                                     |\n| report.properties.packState        | Operational state of battery pack (0=idle, 1=charging, 2=discharing). |\n| report.properties.pass             | Bypass mode (0=automatic, 1=always off, 2=always on).                 |\n| report.properties.pvStatus         | Photovoltaic input status (0=on, 1=off).                              |\n| report.properties.remainOutTime    | Time remaining with current SoC.                                      |\n| report.properties.reverseState     | Grid feed-in state.                                                   |\n| report.properties.rssi             | WiFi signal strength (in dBm).                                        |\n| report.properties.smartMode        | Smart mode active (0/1).                                              |\n| report.properties.socSet           | Target state of charge (e.g., 1000 = 100%).                           |\n| report.properties.socStatus        | Current SoC control state.                                            |\n| report.properties.solarInputPower  | Total solar input power.                                              |\n| report.properties.solarPower1–4    | Power from individual solar channels.                                 |\n| report.properties.ts               | Timestamp of this property snapshot (epoch).                          |\n| report.properties.tsZone           | Time zone (an ID?; Europe/Berlin is '14').                            |\n| report.properties.writeRsp         | Response code for last write/config command.                          |\n\n\n## Home Assistant\n\n`configuration.yml`:\n\n```yaml\nmqtt:\n  # https://www.home-assistant.io/integrations/sensor.mqtt/\n  # https://www.home-assistant.io/integrations/sensor#device-class\n  # https://developers.home-assistant.io/docs/core/entity/sensor/#available-state-classes\n  - sensor:\n   - name: \"SolarFlow 800 Pro OutputHomePower\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.outputHomePower }}\"\n      unique_id: \"solarflow800pro1-outputHomePower\"\n      # energy dashboard: device_class must be energy, state_class must be total / total_increasing\n      # https://www.home-assistant.io/docs/energy/faq/#troubleshooting-missing-entities\n      device_class: \"energy\"     # must be \"energy\" to work with energy dashboard!\n      unit_of_measurement: \"Wh\"  # device-class \"energy\" =\u003e \"Wh\"!\n      state_class: \"total\"       # must be \"total\" to work with energy dashboard\n    - name: \"SolarFlow 800 Pro GridInputPower\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.gridInputPower }}\"\n      unique_id: \"solarflow800pro1-gridinputpower\"\n      # energy dashboard: device_class must be energy, state_class must be total / total_increasing\n      # https://www.home-assistant.io/docs/energy/faq/#troubleshooting-missing-entities\n      device_class: \"energy\"     # must be \"energy\" to work with energy dashboard!\n      unit_of_measurement: \"Wh\"  # device-class \"energy\" =\u003e \"Wh\"!\n      state_class: \"total\"       # must be \"total\" to work with energy dashboard\n    - name: \"SolarFlow 800 Pro PV Input\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.solarInputPower }}\"\n      unique_id: \"solarflow800pro1-pvinput\"\n      # energy dashboard: device_class must be energy, state_class must be total / total_increasing\n      # https://www.home-assistant.io/docs/energy/faq/#troubleshooting-missing-entities\n      device_class: \"energy\"     # must be \"energy\" to work with energy dashboard!\n      unit_of_measurement: \"Wh\"  # device-class \"energy\" =\u003e \"Wh\"!\n      state_class: \"total\"       # must be \"total\" to work with energy dashboard\n    # duplicate solarInputPower but with different device_class \u0026 unit \u0026 state_class\n    - name: \"SolarFlow 800 Pro PV Input Watt\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.solarInputPower }}\"\n      unique_id: \"solarflow800pro1-pvinput-watt\"\n      device_class: \"power\"\n      unit_of_measurement: \"W\"\n      state_class: \"measurement\"\n    - name: \"SolarFlow 800 Pro OutputPackPower\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.outputPackPower }}\"\n      unique_id: \"solarflow800pro1-outputpackpower\"\n      device_class: \"energy\"     # must be \"energy\" to work with energy dashboard!\n      unit_of_measurement: \"Wh\"  # device-class \"energy\" =\u003e \"Wh\"!\n      state_class: \"total\"       # must be \"total\" to work with energy dashboard\n    - name: \"SolarFlow 800 Pro PackInputPower\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.packInputPower }}\"\n      unique_id: \"solarflow800pro1-packinputpower\"\n      device_class: \"energy\"     # must be \"energy\" to work with energy dashboard!\n      unit_of_measurement: \"Wh\"  # device-class \"energy\" =\u003e \"Wh\"!\n      state_class: \"total\"       # must be \"total\" to work with energy dashboard\n    - name: \"SolarFlow 800 Pro ElectricLevel\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ value_json.properties.electricLevel }}\"\n      unique_id: \"solarflow800pro1-electriclevel\"\n      device_class: \"battery\"\n      unit_of_measurement: \"%\"\n      state_class: \"measurement\"\n    - name: \"SolarFlow 800 Pro Hub Temperature\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ (value_json.properties.hyperTmp / 10) - 273.15 | round(1) }}\"\n      unique_id: \"solarflow800pro1-hypertmp\"\n      device_class: \"temperature\"\n      unit_of_measurement: \"°C\"\n      state_class: \"measurement\"\n    - name: \"SolarFlow 800 Pro Battery1 Temperature\"\n      state_topic: \"tele/R3mn8U/deviceId/properties/report\"\n      value_template: \"{{ (value_json.packData[0].maxTemp / 10) - 273.15 | round(1) }}\"\n      unique_id: \"solarflow800pro1-packdata0-maxtemp\"\n      device_class: \"temperature\"\n      unit_of_measurement: \"°C\"\n      state_class: \"measurement\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fixtalo%2Fsf800pro2mqtt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fixtalo%2Fsf800pro2mqtt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fixtalo%2Fsf800pro2mqtt/lists"}