### Start Development Server Source: https://opendtu-onbattery.net/firmware/compile_webapp Execute this command to start the local development server. ```bash yarn dev ``` -------------------------------- ### Example Device Profile JSON Configurations Source: https://opendtu-onbattery.net/firmware/device_profiles A collection of example JSON profiles for various hardware setups, including NodeMCU, Olimex ESP32-POE, and OpenDTU FUSION v2 configurations. ```json [ { "name": "Generic NodeMCU 38 pin with SSD1306 display", "nrf24": { "miso": 19, "mosi": 23, "clk": 18, "irq": 16, "en": 4, "cs": 5 }, "victron": { "rx": 22, "tx": -1 }, "battery": { "rx": 27, "tx": 14 }, "huawei": { "miso": 12, "mosi": 13, "clk": 26, "irq": 25, "power": 33, "cs": 15 }, "display": { "type": 2, "data": 21, "clk": 22 }, "eth": { "enabled": false } }, { "name": "Generic NodeMCU 38 pin with SSD1306", "nrf24": { "miso": 19, "mosi": 23, "clk": 18, "irq": 16, "en": 4, "cs": 5 }, "eth": { "enabled": false }, "display": { "type": 2, "data": 21, "clk": 22 }, "powermeter": { "rx": 25, "tx": 26, "dere": 27 } }, { "name": "Olimex ESP32-POE", "nrf24": { "miso": 15, "mosi": 2, "clk": 14, "irq": 13, "en": 16, "cs": 5 }, "eth": { "enabled": true, "phy_addr": 0, "power": 12, "mdc": 23, "mdio": 18, "type": 0, "clk_mode": 3 } }, { "name": "OpenDTU FUSION v2 + JK BMS on RS485 Transceiver", "battery": { "rx": 16, "rxen": 15, "tx": 45, "txen": 46 } }, { "name": "OpenDTU FUSION v2 + 2xVictron MPPT + Victron SmartShunt", "nrf24": { "miso": 48, "mosi": 35, "clk": 36, "irq": 47, "en": 38, "cs": 37 }, "cmt": { "clk": 6, "cs": 4, "fcs": 21, "sdio": 5, "gpio2": 3, "gpio3": 8 }, "led": { "led0": 17, "led1": 18 }, "battery": { "rx": 16, "tx": -1 }, "victron": { "rx": 22, "tx": -1, "rx2": 23, "tx2": -1 } }, { "name": "OpenDTU Fusion v2 with NRF24, MPPT, SDM72", "nrf24": { "miso": 48, "mosi": 35, "clk": 36, "irq": 47, "en": 38, "cs": 37 }, "victron": { "rx": 22, "tx": -1 }, "powermeter": { "rx": 16, "tx": 45, "rxen": 15, "txen": 46 } } ] ``` -------------------------------- ### Install esptool via pip Source: https://opendtu-onbattery.net/firmware/flash_esp Commands to set up a virtual environment and install the esptool utility for flashing. ```bash python3 -m venv /path/to/your/venv source /path/to/your/venv/bin/activate # on Linux /path/to/your/venv/bin/Activate.ps1 # on Windows pip install esptool esptool version # should show esptool version ``` -------------------------------- ### Build the WebApp Source: https://opendtu-onbattery.net/firmware/compile_webapp Commands to install dependencies and build the WebApp, placing the output in the webapp_dist directory. ```bash cd webapp yarn install yarn build ``` -------------------------------- ### Language pack JSON example Source: https://opendtu-onbattery.net/firmware/language_pack Example structure of a language pack JSON file with meta, display, and webapp sections. The meta section requires name and code, display includes date_format and translation keys with format specifiers, and webapp contains web interface translations. ```json { "meta": { "name": "Italiano", "code": "it" }, "display": { "date_format": "%d/%m/%Y %H:%M", ... }, "webapp": { "menu": { ... }, ... } } ``` -------------------------------- ### Get authenticated configuration data Source: https://opendtu-onbattery.net/firmware/web_api Access protected configuration endpoints by providing the default admin credentials. ```bash $ curl --u admin:openDTU42 http://192.168.10.10/api/ntp/config {"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"} ``` -------------------------------- ### Interactive program startup notice Source: https://opendtu-onbattery.net/license Output this short notice when an interactive program starts. The hypothetical commands `show w' and `show c' should display the appropriate parts of the General Public License; they may be replaced with other commands or UI elements. ```text Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. ``` -------------------------------- ### GPL notice for source files Source: https://opendtu-onbattery.net/license Attach this notice to the start of each source file to convey the exclusion of warranty and provide a pointer to the full license. Replace the placeholders for program name, year, and author name. ```text Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. ``` -------------------------------- ### GET /api/ntp/config Source: https://opendtu-onbattery.net/firmware/web_api Fetches the current NTP configuration from the OpenDTU-OnBattery device. This endpoint returns the NTP server, timezone, and timezone description. ```APIDOC ## [GET] /api/ntp/config ### Description Fetches the current NTP configuration including the NTP server, timezone, and timezone description. ### Method GET ### Endpoint /api/ntp/config ### Parameters #### Authentication - Basic authentication required (username and password). ### Response #### Success Response (200) - **ntp_server** (string) - The NTP server address. - **ntp_timezone** (string) - The timezone string. - **ntp_timezone_descr** (string) - The timezone description. #### Response Example { "ntp_server": "pool.ntp.org", "ntp_timezone": "CET-1CEST,M3.5.0,M10.5.0/3", "ntp_timezone_descr": "Europe/Berlin" } ``` -------------------------------- ### GET /api/ntp/config Source: https://opendtu-onbattery.net/firmware/web_api Retrieves the NTP configuration. This endpoint requires authentication with username `admin` and the configured password (default `openDTU42`). ```APIDOC ## GET /api/ntp/config ### Description Retrieves the NTP configuration. This endpoint requires authentication with username `admin` and the configured password (default `openDTU42`). ### Method GET ### Endpoint /api/ntp/config ### Authentication Basic authentication required. Username: `admin`, password: default `openDTU42`. ### Request Example ``` curl --u admin:openDTU42 http://192.168.10.10/api/ntp/config ``` ### Response #### Success Response (200) - **ntp_server** (string) - NTP server address. - **ntp_timezone** (string) - Timezone string. - **ntp_timezone_descr** (string) - Human-readable timezone description. #### Response Example ``` {"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"} ``` ``` -------------------------------- ### Get inverter eventlog Source: https://opendtu-onbattery.net/firmware/web_api Fetch the event log for a specific inverter serial number, piped through jq for formatting. ```bash $ curl --no-progress-meter http://192.168.10.10/api/eventlog/status?inv=11418186xxxx | jq { "11418186xxxx": { "count": 4, "events": [ { "message_id": 1, "message": "Inverter start", "start_time": 28028, "end_time": 28028 }, { "message_id": 209, "message": "PV-1: No input", "start_time": 28036, "end_time": 0 }, { "message_id": 2, "message": "DTU command failed", "start_time": 28092, "end_time": 28092 }, { "message_id": 207, "message": "MPPT-A: Input undervoltage", "start_time": 28336, "end_time": 0 } ] } } ``` -------------------------------- ### Get common live data with curl and jq Source: https://opendtu-onbattery.net/firmware/web_api Fetches live data and pipes it through jq for pretty-printed, human-readable JSON. The output is formatted with indentation and line breaks. ```bash $ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq { "inverters": [ { "serial": "1161716xxxxx", "name": "Meine Solaranlage", "order": 0, "data_age": 30687, "poll_enabled": true, "reachable": false, "producing": false, "limit_relative": 100, "limit_absolute": 1500 }, { "serial": "1141716xxxxx", "name": "Inverter 2", "order": 0, "data_age": 108400, "poll_enabled": false, "reachable": false, "producing": false, "limit_relative": 0, "limit_absolute": -1 }, { "serial": "1141716xxxxx", "name": "Inverter 3", "order": 0, "data_age": 108400, "poll_enabled": false, "reachable": false, "producing": false, "limit_relative": 0, "limit_absolute": -1 } ], "total": { "Power": { "v": 0, "u": "W", "d": 1 }, "YieldDay": { "v": 0, "u": "Wh", "d": 0 }, "YieldTotal": { "v": 2515.605957, "u": "kWh", "d": 3 } }, "hints": { "time_sync": false, "radio_problem": false, "default_password": false } } ``` -------------------------------- ### Prometheus scrape configuration for OpenDTU Source: https://opendtu-onbattery.net/3rd_party/prometheus_database Configuration for /etc/prometheus/prometheus.yml to scrape metrics from OpenDTU devices. Set scrape_interval to at least the inverter scrape interval (5s in example) and replace targets with actual IP addresses. The metrics_path is /api/prometheus/metrics. ```yaml # /etc/prometheus/prometheus.yml scrape_configs: - job_name: 'opendtu' scrape_interval: 5s # >= Inverter scrape interval static_configs: - targets: ['', ''] metrics_path: /api/prometheus/metrics ``` -------------------------------- ### Get common live data with curl Source: https://opendtu-onbattery.net/firmware/web_api Fetches live data from the OpenDTU-OnBattery device. The output is plain JSON without linefeeds. Replace the IP address with your device's IP. ```bash $ curl http://192.168.10.10/api/livedata/status {"inverters":[{"serial":"1161716xxxxx","name":"Meine Solaranlage","order":0,"data_age":30636,"poll_enabled":true,"reachable":false,"producing":false,"limit_relative":100,"limit_absolute":1500},{"serial":"1141716xxxxx","name":"Inverter 2","order":0,"data_age":108349,"poll_enabled":false,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1},{"serial":"1141716xxxxx","name":"Inverter 3","order":0,"data_age":108349,"poll_enabled":false,"reachable":false,"producing":false,"limit_relative":0,"limit_absolute":-1}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":2515.605957,"u":"kWh","d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}} ``` -------------------------------- ### Get inverter detail livedata Source: https://opendtu-onbattery.net/firmware/web_api Retrieve the current status and data for a specific inverter using its serial number. ```bash $ curl http://192.168.10.10/api/livedata/status?inv=1161716xxxxx {"inverters":[{"serial":"1161716xxxxx","name":"Meine Solaranlage","order":0,"data_age":30824,"poll_enabled":true,"reachable":false,"producing":false,"limit_relative":100,"limit_absolute":1500,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1}}},"DC":{"0":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":834.2609863,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"1":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":832.7069702,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"2":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":843.7299805,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"3":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":4.907999992,"u":"kWh","d":3}}},"INV":{"0":{"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":2515.605957,"u":"kWh","d":3},"Temperature":{"v":0,"u":"°C","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"events":2}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":2515.605957,"u":"kWh","d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}} ``` -------------------------------- ### GET /api/eventlog/status Source: https://opendtu-onbattery.net/firmware/web_api Fetches the event log for a specific inverter. The response includes a count of events and an array of event objects with message details and timestamps. ```APIDOC ## GET /api/eventlog/status ### Description Fetches the event log for a specific inverter identified by its serial number. The response contains a count of events and an array of event objects with message details and timestamps. ### Method GET ### Endpoint /api/eventlog/status ### Parameters #### Query Parameters - **inv** (string) - Required - The serial number of the inverter to retrieve the event log for. ### Request Example ``` curl --no-progress-meter http://192.168.10.10/api/eventlog/status?inv=11418186xxxx | jq ``` ### Response #### Success Response (200) - **** (object) - Object containing `count` (number) and `events` (array). - **count** (number) - Number of events. - **events** (array) - List of event objects with `message_id`, `message`, `start_time`, and `end_time`. #### Response Example ``` { "11418186xxxx": { "count": 4, "events": [ { "message_id": 1, "message": "Inverter start", "start_time": 28028, "end_time": 28028 }, { "message_id": 209, "message": "PV-1: No input", "start_time": 28036, "end_time": 0 }, { "message_id": 2, "message": "DTU command failed", "start_time": 28092, "end_time": 28092 }, { "message_id": 207, "message": "MPPT-A: Input undervoltage", "start_time": 28336, "end_time": 0 } ] } } ``` ``` -------------------------------- ### GET /api/limit/status Source: https://opendtu-onbattery.net/firmware/web_api Fetches the current power limit status for all configured inverters. The response contains the relative limit, maximum power, and the limit set status for each inverter. ```APIDOC ## [GET] /api/limit/status ### Description Fetches the current power limit status for all configured inverters. The response contains the relative limit, maximum power, and the limit set status for each inverter. ### Method GET ### Endpoint /api/limit/status ### Parameters #### Authentication - No authentication required (as shown in the example). ### Response #### Success Response (200) - **** (object) - An object keyed by inverter serial number containing: - **limit_relative** (number) - The relative power limit in percent. - **max_power** (number) - The maximum power of the inverter. - **limit_set_status** (string) - The status of the limit setting, e.g., "Ok" or "Pending". #### Response Example { "11418186xxxx": { "limit_relative": 100, "max_power": 600, "limit_set_status": "Ok" }, "11418180xxxx": { "limit_relative": 100, "max_power": 800, "limit_set_status": "Ok" } } ``` -------------------------------- ### GET /api/livedata/status Source: https://opendtu-onbattery.net/firmware/web_api Retrieves live data for all inverters or a specific inverter. The response includes detailed AC/DC measurements, inverter-level statistics, and aggregated totals. ```APIDOC ## GET /api/livedata/status ### Description Retrieves the current live data for all inverters or a specific inverter when the `inv` parameter is provided. The response includes AC/DC channel measurements, inverter-level data, and totals. ### Method GET ### Endpoint /api/livedata/status ### Parameters #### Query Parameters - **inv** (string) - Optional - The serial number of the inverter to filter the live data for. ### Request Example ``` curl http://192.168.10.10/api/livedata/status?inv=1161716xxxxx ``` ### Response #### Success Response (200) - **inverters** (array) - List of inverter objects with serial, name, order, data_age, poll_enabled, reachable, producing, limit_relative, limit_absolute, AC, DC, INV, and events. - **total** (object) - Aggregated power and yield values. - **hints** (object) - System hints (time_sync, radio_problem, default_password). #### Response Example ``` {"inverters":[{"serial":"1161716xxxxx","name":"Meine Solaranlage","order":0,"data_age":30824,"poll_enabled":true,"reachable":false,"producing":false,"limit_relative":100,"limit_absolute":1500,"AC":{"0":{"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"Frequency":{"v":0,"u":"Hz","d":2},"PowerFactor":{"v":0,"u":"","d":3},"ReactivePower":{"v":0,"u":"var","d":1}}},"DC":{"0":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":834.2609863,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"1":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":832.7069702,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"2":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":843.7299805,"u":"kWh","d":3},"Irradiation":{"v":0,"u":"%","d":3,"max":385}},"3":{"name":{"u":""},"Power":{"v":0,"u":"W","d":1},"Voltage":{"v":0,"u":"V","d":1},"Current":{"v":0,"u":"A","d":2},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":4.907999992,"u":"kWh","d":3}}},"INV":{"0":{"Power DC":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":2515.605957,"u":"kWh","d":3},"Temperature":{"v":0,"u":"°C","d":1},"Efficiency":{"v":0,"u":"%","d":3}}},"events":2}],"total":{"Power":{"v":0,"u":"W","d":1},"YieldDay":{"v":0,"u":"Wh","d":0},"YieldTotal":{"v":2515.605957,"u":"kWh","d":3}},"hints":{"time_sync":false,"radio_problem":false,"default_password":false}} ``` ``` -------------------------------- ### GET /api/livedata/status Source: https://opendtu-onbattery.net/firmware/web_api Retrieves common live data from the OpenDTU-OnBattery system, including inverter status, total power, yield, and system hints. The response is in JSON format. ```APIDOC ## GET /api/livedata/status ### Description Retrieves common live data from the OpenDTU-OnBattery system, including inverter status, total power, yield, and system hints. ### Method GET ### Endpoint /api/livedata/status ### Parameters None ### Request Example ``` curl http://192.168.10.10/api/livedata/status ``` ### Response #### Success Response (200) - **inverters** (array) - List of inverter objects with serial, name, order, data_age, poll_enabled, reachable, producing, limit_relative, limit_absolute. - **total** (object) - Contains Power, YieldDay, YieldTotal objects with value (v), unit (u), and decimals (d). - **hints** (object) - Contains time_sync, radio_problem, default_password booleans. #### Response Example ```json { "inverters": [ { "serial": "1161716xxxxx", "name": "Meine Solaranlage", "order": 0, "data_age": 30636, "poll_enabled": true, "reachable": false, "producing": false, "limit_relative": 100, "limit_absolute": 1500 } ], "total": { "Power": { "v": 0, "u": "W", "d": 1 }, "YieldDay": { "v": 0, "u": "Wh", "d": 0 }, "YieldTotal": { "v": 2515.605957, "u": "kWh", "d": 3 } }, "hints": { "time_sync": false, "radio_problem": false, "default_password": false } } ``` ``` -------------------------------- ### MQTT Topic: [serial]/cmd/restart Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to restart the inverters, which also resets YieldDay. ```APIDOC ## MQTT Topic: [serial]/cmd/restart ### Description Write-only topic to restart the inverters, which also resets YieldDay. ### Topic [serial]/cmd/restart ### Access Write (W) ### Value / Unit 1 ### Request Example { "value": 1 } ``` -------------------------------- ### Configure NTP settings via Web API Source: https://opendtu-onbattery.net/firmware/web_api Fetch current NTP configuration and then update it by sending a POST request with the modified JSON data. ```bash $ curl -u "admin:password" http://192.168.10.10/api/ntp/config {"ntp_server":"pool.ntp.org","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"} ``` ```bash $ curl -u "admin:password" http://192.168.10.10/api/ntp/config -d 'data={"ntp_server":"my.own.ntp.server.home","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}' {"type":"success","message":"Settings saved!"} ``` -------------------------------- ### MQTT Topic: [serial]/cmd/power Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to turn the inverter on (1) or off (0). ```APIDOC ## MQTT Topic: [serial]/cmd/power ### Description Write-only topic to turn the inverter on (1) or off (0). ### Topic [serial]/cmd/power ### Access Write (W) ### Value / Unit 0 or 1 ### Request Example { "value": 1 } ``` -------------------------------- ### Flash firmware using esptool Source: https://opendtu-onbattery.net/firmware/flash_esp Commands to erase flash memory and write a firmware binary to the ESP32 using esptool. ```bash # erase flash only if you want or need to # start from scratch (settings are lost): esptool --port COM1 erase_flash esptool --baud 921600 --port COM1 --chip esp32 \ --before default-reset --after hard-reset \ write-flash 0x0 opendtu-generic*.factory.bin ``` -------------------------------- ### Format Source Code Source: https://opendtu-onbattery.net/firmware/compile_webapp Automatically format source code files to ensure a consistent style. ```bash yarn format ``` -------------------------------- ### Configure Development Server Proxy Source: https://opendtu-onbattery.net/firmware/compile_webapp Create the vite.user.ts file in the webapp directory to set the proxy target to your ESP32 IP address. ```typescript export const proxy_target = '192.168.20.110' ``` -------------------------------- ### Lint Source Code Source: https://opendtu-onbattery.net/firmware/compile_webapp Run ESLint to check the source code for issues. ```bash yarn lint ``` -------------------------------- ### MQTT Topic: [serial]/cmd/limit_persistent_relative Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to set the inverter limit as a percentage of total production capability. The value persists through power loss and updates the GUI and limit_relative topic immediately. ```APIDOC ## MQTT Topic: [serial]/cmd/limit_persistent_relative ### Description Write-only topic to set the inverter limit as a percentage of total production capability. The value persists through power loss and updates the GUI and limit_relative topic immediately. ### Topic [serial]/cmd/limit_persistent_relative ### Access Write (W) ### Value / Unit % ### Request Example { "value": 80 } ``` -------------------------------- ### Connect to serial console with minicom on Linux Source: https://opendtu-onbattery.net/firmware/howto/serial_console Connect to the ESP32 serial console on Linux using minicom. Replace /dev/ttyUSB0 with the detected device (e.g., /dev/ttyACM0) and adjust the baud rate if needed. The -C option writes captured output to /tmp/capture.txt. ```bash minicom -D /dev/ttyUSB0 -C /tmp/capture.txt -b 115200 ``` -------------------------------- ### MQTT Topic: [serial]/status/limit_absolute Source: https://opendtu-onbattery.net/firmware/mqtt_topics Read-only topic that reports the current applied production limit of the inverter in watts. ```APIDOC ## MQTT Topic: [serial]/status/limit_absolute ### Description Read-only topic that reports the current applied production limit of the inverter in watts. ### Topic [serial]/status/limit_absolute ### Access Read (R) ### Value / Unit Watt (W) ### Response #### Success Response - **value** (number) - Current production limit in watts. ``` -------------------------------- ### MQTT Topic: [serial]/status/limit_relative Source: https://opendtu-onbattery.net/firmware/mqtt_topics Read-only topic that reports the current applied production limit of the inverter as a percentage of total possible output. ```APIDOC ## MQTT Topic: [serial]/status/limit_relative ### Description Read-only topic that reports the current applied production limit of the inverter as a percentage of total possible output. ### Topic [serial]/status/limit_relative ### Access Read (R) ### Value / Unit % of total possible output ### Response #### Success Response - **value** (number) - Current production limit in percent. ``` -------------------------------- ### MQTT Topic: [serial]/cmd/limit_nonpersistent_relative Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to set the inverter limit as a percentage of total production capability. The value resets to the last persistent value at night without power. Must be published non-retained. ```APIDOC ## MQTT Topic: [serial]/cmd/limit_nonpersistent_relative ### Description Write-only topic to set the inverter limit as a percentage of total production capability. The value resets to the last persistent value at night without power. Must be published non-retained. ### Topic [serial]/cmd/limit_nonpersistent_relative ### Access Write (W) ### Value / Unit % ### Request Example { "value": 80 } ### Notes - The value must be published non-retained, otherwise it will be ignored. ``` -------------------------------- ### MQTT Topic: [serial]/cmd/limit_persistent_absolute Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to set the inverter limit as an absolute value in watts. The value persists through power loss and updates the GUI and limit_absolute topic after a delay (around 4 minutes, or a few seconds for known inverters). ```APIDOC ## MQTT Topic: [serial]/cmd/limit_persistent_absolute ### Description Write-only topic to set the inverter limit as an absolute value in watts. The value persists through power loss and updates the GUI and limit_absolute topic after a delay (around 4 minutes, or a few seconds for known inverters). ### Topic [serial]/cmd/limit_persistent_absolute ### Access Write (W) ### Value / Unit Watt (W) ### Request Example { "value": 3000 } ``` -------------------------------- ### POST /api/ntp/config Source: https://opendtu-onbattery.net/firmware/web_api Updates the NTP configuration on the OpenDTU-OnBattery device. The request body must contain the new settings in a JSON object wrapped in a `data` parameter. ```APIDOC ## [POST] /api/ntp/config ### Description Updates the NTP configuration on the OpenDTU-OnBattery device. The request body must contain the new settings in a JSON object wrapped in a `data` parameter. ### Method POST ### Endpoint /api/ntp/config ### Parameters #### Authentication - Basic authentication required (username and password). #### Request Body - **data** (string) - Required - A URL-encoded JSON string containing the new NTP settings. The JSON object must include the fields `ntp_server`, `ntp_timezone`, and `ntp_timezone_descr`. ### Request Example curl -u "admin:password" http://192.168.10.10/api/ntp/config -d 'data={"ntp_server":"my.own.ntp.server.home","ntp_timezone":"CET-1CEST,M3.5.0,M10.5.0/3","ntp_timezone_descr":"Europe/Berlin"}' ### Response #### Success Response (200) - **type** (string) - The type of response, e.g., "success". - **message** (string) - A message indicating the result, e.g., "Settings saved!". #### Response Example { "type": "success", "message": "Settings saved!" } ``` -------------------------------- ### MQTT Topic: [serial]/cmd/limit_nonpersistent_absolute Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to set the inverter limit as an absolute value in watts. The value resets to the last persistent value at night without power. Must be published non-retained. ```APIDOC ## MQTT Topic: [serial]/cmd/limit_nonpersistent_absolute ### Description Write-only topic to set the inverter limit as an absolute value in watts. The value resets to the last persistent value at night without power. Must be published non-retained. ### Topic [serial]/cmd/limit_nonpersistent_absolute ### Access Write (W) ### Value / Unit Watt (W) ### Request Example { "value": 3000 } ### Notes - The value must be published non-retained, otherwise it will be ignored. ``` -------------------------------- ### MQTT Topic: [serial]/cmd/reset_rf_stats Source: https://opendtu-onbattery.net/firmware/mqtt_topics Write-only topic to reset the radio statistics. ```APIDOC ## MQTT Topic: [serial]/cmd/reset_rf_stats ### Description Write-only topic to reset the radio statistics. ### Topic [serial]/cmd/reset_rf_stats ### Access Write (W) ### Value / Unit 1 ### Request Example { "value": 1 } ``` -------------------------------- ### Change inverter power limit Source: https://opendtu-onbattery.net/firmware/web_api Fetch the current power limit status, update the relative power limit for a specific inverter, and verify the status change. ```bash $ curl http://192.168.10.10/api/limit/status {"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Ok"}} ``` ```bash $ curl -u "admin:password" http://192.168.10.10/api/limit/config -d 'data={"serial":"11418180xxxx", "limit_type":1, "limit_value":50}' {"type":"success","message":"Settings saved!"} ``` ```bash $ curl http://192.168.10.10/api/limit/status {"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":100,"max_power":800,"limit_set_status":"Pending"}} ... $ curl http://192.168.10.10/api/limit/status {"11418186xxxx":{"limit_relative":100,"max_power":600,"limit_set_status":"Ok"},"11418180xxxx":{"limit_relative":50,"max_power":800,"limit_set_status":"Ok"}} ``` -------------------------------- ### POST /api/limit/config Source: https://opendtu-onbattery.net/firmware/web_api Sets the power limit for a specific inverter. The request body must contain the inverter serial number, the limit type, and the limit value. ```APIDOC ## [POST] /api/limit/config ### Description Sets the power limit for a specific inverter. The request body must contain the inverter serial number, the limit type, and the limit value. ### Method POST ### Endpoint /api/limit/config ### Parameters #### Authentication - Basic authentication required (username and password). #### Request Body - **data** (string) - Required - A URL-encoded JSON string containing the new limit settings. The JSON object must include the fields `serial`, `limit_type`, and `limit_value`. ### Request Example curl -u "admin:password" http://192.168.10.10/api/limit/config -d 'data={"serial":"11418180xxxx", "limit_type":1, "limit_value":50}' ### Response #### Success Response (200) - **type** (string) - The type of response, e.g., "success". - **message** (string) - A message indicating the result, e.g., "Settings saved!". #### Response Example { "type": "success", "message": "Settings saved!" } ``` -------------------------------- ### Copyright disclaimer sample Source: https://opendtu-onbattery.net/license Use this sample copyright disclaimer when an employer or school needs to sign one. Alter the names and signature as appropriate. ```text Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice ``` -------------------------------- ### RS485 with Transceiver Wiring Diagram Source: https://opendtu-onbattery.net/hardware/jkbms/models_b Wiring diagram for connecting a JK-B* BMS to an ESP32 via an RS485 transceiver (e.g., ISL3178E on OpenDTU Fusion board or MAX485 module). Requires four ESP32 pins: two data, one receiver control, one transmitter control. Use the 'RS485-Transceiver on MCU' interface type in OpenDTU-OnBattery settings. ```text RS485-TTL RS485 ┌──────────────────────────────┐ ┌────────┐ ┌───────────┐ │ ┌───────────┐ ┌───────┐ │ │ │<--TX--->│Y JK Y││A RXEN│<->│15 │ │ │ JK-BMS │<--RX--->│W RS485 W││B RX│<->│16 ESP │ │ │ │<--GND-->│B Adaptor │ │ │ TXEN│<->│46 32 │ │ │ │<-Bat V->│R B│<-->│GND │ISL3178E EN│<->│45 │ │ └────────┘ └───────────┘ │ └───────────┘ └───────┘ │ │ OpenDTU Fusion v2 │ └──────────────────────────────┘ ``` -------------------------------- ### Filter livedata with jq Source: https://opendtu-onbattery.net/firmware/web_api Use jq to extract specific fields from the JSON output, such as the current total power. ```bash $ curl --no-progress-meter http://192.168.10.10/api/livedata/status | jq '.total | .Power.v' 140.7999878 ``` -------------------------------- ### JK-B* Supported Models List Source: https://opendtu-onbattery.net/hardware/jkbms/models_b List of JK BMS models that are assumed to implement the same UART protocol as the tested JK-B1A24S15P. Buying the BMS with CAN interface or GPS feature might conflict with the UART interface. ```text JK-BD6AxxS-6P / JK-BD6AxxS-8P JK-BD6AxxS-10P / JK-BD6AxxS-15P JK-BD6AxxS-20P / JK-B1AxxS-15P JK-B2AxxS-15P / JK-B2AxxS-20P ``` -------------------------------- ### RS485 with Converter Wiring Diagram Source: https://opendtu-onbattery.net/hardware/jkbms/models_b Wiring diagram for connecting a JK-B* BMS to an ESP32 via an RS485 to UART-TTL converter board (e.g., DEBO TTL-RS485). Works over long distances. Use the 'TTL-UART on MCU' interface type in OpenDTU-OnBattery settings. The ESP32 may read its own data with bad converter boards. ```text UART-TTL RS485 RS485-TTL ┌────────┐ ┌───────────┐ ┌────────┐ ┌───────┐ │ │<--TX--->│Y JK Y││ ││ │ │ JK-BMS │<--RX--->│W RS485 W││ RS485 ││ ESP32 │ │ │<--GND-->│B Adaptor B│<-GND->│ to 3V3 │<--GND-->│ │ │ │<-Bat V->│R │ │ │<--3V3-->│ │ └────────┘ └───────────┘ └────────┘ └───────┘ ``` -------------------------------- ### UART-TTL Direct Wiring Diagram Source: https://opendtu-onbattery.net/hardware/jkbms/models_b Wiring diagram for direct UART-TTL connection between a JK-B* BMS and an ESP32 using two pins. Do NOT connect the VBAT pin (full battery voltage). Use only over short distances due to interference. Use the 'TTL-UART on MCU' interface type in OpenDTU-OnBattery settings. ```text UART-TTL ┌────────┐ ┌───────┐ │ ││ │ │ JK-BMS ││ ESP32 │ │ │<--GND-->│ │ │ │ 3V3-->│ │ └────────┘ └───────┘ ```