Start properly documenting the protocol
This commit is contained in:
parent
c7e97aca84
commit
c367d642d8
5 changed files with 137 additions and 14 deletions
|
@ -11,8 +11,8 @@ charset = utf-8
|
|||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[*.{py,yaml,yml}]
|
||||
[*.{py,yaml,yml,md}]
|
||||
indent_style = space
|
||||
|
||||
[*.{yaml,yml}]
|
||||
[*.{yaml,yml,md}]
|
||||
indent_size = 2
|
||||
|
|
|
@ -26,6 +26,8 @@ repos:
|
|||
rev: 2.3.54
|
||||
hooks:
|
||||
- id: editorconfig-checker
|
||||
args:
|
||||
- "--exclude=Protocol.md"
|
||||
|
||||
- repo: https://github.com/PyCQA/flake8
|
||||
rev: 4.0.1
|
||||
|
@ -38,7 +40,7 @@ repos:
|
|||
- id: mypy
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 21.9b0
|
||||
rev: 21.10b0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
|
|
85
Protocol.md
Normal file
85
Protocol.md
Normal file
|
@ -0,0 +1,85 @@
|
|||
# Protocol
|
||||
|
||||
The protocol checksum is litle-endian CRC16-MODBUS, but the data itself seems to be big-endian (network order).
|
||||
It is structured around 16bit words (read 4 returns 8 bytes).
|
||||
|
||||
I have seen the "Transfer ID?" field containing 0xFF and 0x01, I am not yet sure of the putpose of this field. Most transactions it is set to 0xFF.
|
||||
|
||||
## Reading
|
||||
|
||||
### Read request
|
||||
|
||||
```text
|
||||
┌──────────────┐
|
||||
╔═╡ Transfer ID? │
|
||||
║ └──────────────┘
|
||||
║ ┌────────────────────┐
|
||||
║ ╔═╡ Operation (3=read) │
|
||||
║ ║ └────────────────────┘
|
||||
║ ║ ┌───────────────┐
|
||||
║ ║ ╔═╡ Start address │
|
||||
║ ║ ║ └───────────────┘
|
||||
║ ║ ║ ┌────────────────────────────────┐
|
||||
║ ║ ║ ╔═╡ Number of 2-byte words to read │
|
||||
║ ║ ║ ║ └────────────────────────────────┘
|
||||
║ ║ ║ ║ ┌─────────────────┐
|
||||
║ ║ ║ ║ ╔═╡ Transaction CRC │
|
||||
║ ║ ║ ║ ║ └─────────────────┘
|
||||
┌╨─┬╨─┬──╨──┬──╨──┬──╨──┐
|
||||
│FF│03│00 0C│00 08│91 d1│
|
||||
└──┴──┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
### Read response
|
||||
|
||||
```text
|
||||
┌──────────────┐
|
||||
╔═╡ Transfer ID? │
|
||||
║ └──────────────┘
|
||||
║ ┌────────────────────┐
|
||||
║ ╔═╡ Operation (3=read) │
|
||||
║ ║ └────────────────────┘
|
||||
║ ║ ┌──────────────────────────┐
|
||||
║ ║ ╔═╡ Number of bytes returned │
|
||||
║ ║ ║ └──────────────────────────┘
|
||||
║ ║ ║ ┌──────┐ ┌─────────────────┐
|
||||
║ ║ ║ ╔═╡ Data │ │ Transaction CRC ╞═╗
|
||||
║ ║ ║ ║ └──────┘ └─────────────────┘ ║
|
||||
┌╨─┬╨─┬╨─┬╨──────────────────────────────────────────────┬──╨──┐
|
||||
│FF│03│10│20 20 20 20 4D 4C 32 34 32 30 20 20 20 20 20 20│FD 17│
|
||||
└──┴──┴──┴───────────────────────────────────────────────┴─────┘
|
||||
```
|
||||
|
||||
This particular memory section contains the device SKU: ML2420
|
||||
|
||||
## Writing
|
||||
|
||||
### Write request
|
||||
|
||||
```text
|
||||
┌──────────────┐
|
||||
╔═╡ Transfer ID? │
|
||||
║ └──────────────┘
|
||||
║ ┌────────────────────┐
|
||||
║ ╔═╡ Operation (6=read) │
|
||||
║ ║ └────────────────────┘
|
||||
║ ║ ┌─────────┐
|
||||
║ ║ ╔═╡ Address │
|
||||
║ ║ ║ └─────────┘
|
||||
║ ║ ║ ┌──────┐
|
||||
║ ║ ║ ╔═╡ Data │
|
||||
║ ║ ║ ║ └──────┘
|
||||
║ ║ ║ ║ ┌─────────────────┐
|
||||
║ ║ ║ ║ ╔═╡ Transaction CRC │
|
||||
║ ║ ║ ║ ║ └─────────────────┘
|
||||
┌╨─┬╨─┬──╨──┬──╨──┬──╨──┐
|
||||
│FF│06│01 0A│00 01│7C 2A│
|
||||
└──┴──┴─────┴─────┴─────┘
|
||||
```
|
||||
|
||||
The data at 0x010A is a boolean controlling the load output switch.
|
||||
|
||||
### Write response
|
||||
|
||||
Seems to return exactly the same as the data written,
|
||||
presumably to allow verifying that the data did indeed get written.
|
15
Readme.md
Normal file
15
Readme.md
Normal file
|
@ -0,0 +1,15 @@
|
|||
# SolarMPPT
|
||||
|
||||
<!-- TODO: Come up with a better name -->
|
||||
|
||||
Python library for interracting with the rather generic MPPT solar charge controller I got from the hardware store.
|
||||
|
||||
- [Biltema 25-5077](https://www.biltema.no/bil---mc/elektrisk-anlegg/solcellspaneler/mppt-regulator-20-a-2000045547)
|
||||
|
||||
The Android app suggested for the bluetooth interface is
|
||||
[SolarApp](https://play.google.com/store/apps/details?id=com.shuori.gfv2.guangfu) by srne
|
||||
(I'm not currently able to find the bluetooth bridge on Biltema's website?
|
||||
It's got BT-1 printed on the front, and is basically just a RS-232 to BTLE UART GATT)
|
||||
|
||||
[![pre-commit](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
|
||||
![example workflow](https://github.com/oddstr13/SolarMPPT/actions/workflows/pre-commit/badge.svg)
|
43
solar_ble.py
43
solar_ble.py
|
@ -15,24 +15,33 @@ INTERVAL = 15
|
|||
write_device = "0000ffd1-0000-1000-8000-00805f9b34fb"
|
||||
# read_device = "0000fff1-0000-1000-8000-00805f9b34fb"
|
||||
|
||||
|
||||
# get(255, 12, 2)
|
||||
# "ff 03 00 0c 00 02"
|
||||
CMD_GET_1 = b"\xff\x03\x00\x0c\x00\x02"
|
||||
# > ff 03 04 20 20 20 20
|
||||
|
||||
# get(255, 12, 8)
|
||||
# ff 03 00 0c 00 08
|
||||
CMD_GET_MODEL = b"\xff\x03\x00\x0c\x00\x08"
|
||||
# > ff 03 10 20 20 20 20 4d 4c 32 34 32 30 20 20 20 20 20 20
|
||||
# Device SKU: ML2420
|
||||
|
||||
# get(255, 20, 4)
|
||||
# ff 03 00 14 00 04
|
||||
CMD_GET_VERSION = b"\xff\x03\x00\x14\x00\x04"
|
||||
# > ff 03 08 00 04 02 00 02 00 00 03
|
||||
# CC ?? 11 22 33 ?? 44 55 66
|
||||
# Version: 4.2.0
|
||||
|
||||
# get(255, 24, 3)
|
||||
# ff 03 00 18 00 03
|
||||
CMD_GET_SERIAL = b"\xff\x03\x00\x18\x00\x03"
|
||||
# > ff 03 06 3c 13 02 67 00 01
|
||||
# CC 11 22 33 33 ?? ??
|
||||
# SN: 60-19-0615
|
||||
|
||||
# get(255, 256, 7)
|
||||
# ff 03 01 00 00 07
|
||||
CMD_GET_BATTERY_STATE = b"\xff\x03\x01\x00\x00\x07"
|
||||
# > ff 03 0e 00 48 00 7e 00 1d 0e 0d 00 7e 00 1c 00 03
|
||||
# CC 11 11 22 22 33 33 44 55 66 66 77 77 88 88
|
||||
|
@ -45,6 +54,8 @@ CMD_GET_BATTERY_STATE = b"\xff\x03\x01\x00\x00\x07"
|
|||
# 7: Load current: 0.28 A
|
||||
# 8: Load power: 3 W
|
||||
|
||||
# get(255, 263, 4)
|
||||
# ff 03 01 07 00 04
|
||||
CMD_GET_PANEL_STATUS = b"\xff\x03\x01\x07\x00\x04"
|
||||
# > ff 03 08 00 c8 00 14 00 04 00 01
|
||||
# CC 11 11 22 22 33 33 ?? ??
|
||||
|
@ -53,6 +64,21 @@ CMD_GET_PANEL_STATUS = b"\xff\x03\x01\x07\x00\x04"
|
|||
# 3: Panel power: 4 W
|
||||
# Charging status?
|
||||
|
||||
# set(255, 266, 1 or 0)
|
||||
# ff 06 01 0a 00 01
|
||||
CMD_ENABLE_LOAD = b"\xff\x06\x01\x0a\x00\x01"
|
||||
CMD_DISABLE_LOAD = b"\xff\x06\x01\x0a\x00\x00"
|
||||
REG_LOAD_ENABLE = 0x010A
|
||||
|
||||
# get(255, 267, 21)
|
||||
# ff 03 01 0b 00 15
|
||||
CMD_GET_LOAD_PARAMETERS = b"\xff\x03\x01\x0b\x00\x15"
|
||||
# > ff 03 2a 00 7c 00 7f 00 51 00 20 00 0a 00 03 00 00 00 00 00
|
||||
# > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
# > 00 00 00 00 00
|
||||
|
||||
# get(255, 288, 3)
|
||||
# ff 03 01 20 00 03
|
||||
CMD_GET_2 = b"\xff\x03\x01\x20\x00\x03"
|
||||
# > ff 03 06 80 02 00 00 00 00
|
||||
# CC 11 22 33 33 33 33
|
||||
|
@ -60,6 +86,8 @@ CMD_GET_2 = b"\xff\x03\x01\x20\x00\x03"
|
|||
# 2: ?: 2
|
||||
# 3: ?: 0
|
||||
|
||||
# get(255, 57345, 33)
|
||||
# ff 03 e0 01 00 21
|
||||
CMD_GET_BATTERY_PARAMETERS = b"\xff\x03\xe0\x01\x00\x21"
|
||||
# > ff 03 42 07 d0 00 c8 ff 0c 00 02 00 a0 00 9b 00 92 00 90 00
|
||||
# > 8a 00 84 00 7e 00 78 00 6f 00 6a 64 32 00 05 00 78 00 78 00
|
||||
|
@ -67,13 +95,8 @@ CMD_GET_BATTERY_PARAMETERS = b"\xff\x03\xe0\x01\x00\x21"
|
|||
# > 0f 00 05 00 05 00 04 01 00
|
||||
# 33 * uint16
|
||||
|
||||
# (0xff, 267, 21)
|
||||
CMD_GET_LOAD_PARAMETERS = b"\xff\x03\x01\x0b\x00\x15"
|
||||
# > ff 03 2a 00 7c 00 7f 00 51 00 20 00 0a 00 03 00 00 00 00 00
|
||||
# > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
|
||||
# > 00 00 00 00 00
|
||||
|
||||
# 01 03 f000 000a
|
||||
# get(1, 61440, 10)
|
||||
# 01 03 f0 00 00 0a
|
||||
CMD_GET_HISTORICAL_TODAY = b"\x01\x03\xf0\x00\x00\x0a"
|
||||
CMD_GET_HISTORICAL_YESTERDAY = b"\x01\x03\xf0\x01\x00\x0a"
|
||||
CMD_GET_HISTORICAL_D2 = b"\x01\x03\xf0\x02\x00\x0a"
|
||||
|
@ -103,9 +126,7 @@ CMD_GET_HISTORICAL_D3 = b"\x01\x03\xf0\x03\x00\x0a"
|
|||
# production_power = 0 Wh
|
||||
# consumption_power = 0 Wh
|
||||
|
||||
CMD_ENABLE_LOAD = b"\xff\x06\x01\x0a\x00\x01"
|
||||
CMD_DISABLE_LOAD = b"\xff\x06\x01\x0a\x00\x00"
|
||||
|
||||
# ff 78 00 00 00 01
|
||||
CMD_ = b"\xff\x78\x00\x00\x00\x01"
|
||||
|
||||
# CMD_GET_BATTERY_STATE = b'\xff\x03\x01\x00\x00\x07'
|
||||
|
|
Loading…
Reference in a new issue