Source-available, read-only monitoring for the undocumented Pylontech RS232 debug console.
Pylontech Console is a read-only monitoring service for Pylontech battery systems.
Version 0.1 focuses on:
- automatic discovery of installed modules;
- stable module identification by barcode;
- protocol documentation;
- parser implementation based on recorded captures;
- REST API;
- MQTT;
- read-only Web UI including cell heat maps;
- runtime inventory based on the battery system's current state.
No write commands are implemented in Version 0.1.
- Contract first
- Read-only
- Barcode = physical identity
- Position = current rack topology
- Automatic discovery
- One internal data model
- Multiple output interfaces (REST, MQTT, Web)
Pylontech → TCP Transport → Response Framing → Parsers → Domain Model → Discovery/Runtime Inventory → REST / MQTT / Web
- docs/architecture - ADRs
- docs/contracts - Version contracts
- docs/development - Implementation plan
- docs/testing - Test strategy
- protocol/ - Protocol specification
- captures/ - Recorded console responses
- src/ - Python implementation
- tests/ - Unit and integration tests
Development starts with:
- implementation-plan-v0.1.md
- ADRs
- Version contract
- Protocol documentation
- Captures
- docs/contracts/version-0.1.md
- docs/architecture/
- docs/development/implementation-plan-v0.1.md
- docs/testing/test-strategy-v0.1.md
- CONTRIBUTING.md
- Reverse engineering completed.
- Core protocol documented.
- Architecture defined.
- Production service implemented with REST, Web UI and MQTT.
- Running on a five-module mixed Pylontech US2000/US2000C rack.
- Published
linux/amd64Docker images available from Docker Hub.
The verified reference installation uses:
- two Pylontech US2000 modules;
- three Pylontech US2000C modules;
- 15 cells per module and 75 cells in total;
- a Waveshare RS232/485/422 TO POE ETH (B) serial device server;
- Docker on a Proxmox-hosted
linux/amd64server; - optional MQTT publishing to ioBroker.
Other Pylontech models, serial adapters and container architectures are not yet
verified. See docs/hardware.md for the exact compatibility
statement and docs/wiring.md for the tested cable.
The Web UI compares every cell with the average of its own module. Blue cells are below that reference, red cells are above it, and the neutral zone is white. Independent absolute-voltage markers distinguish imbalance from a cell approaching a configured safety threshold.
The following screenshot shows live data from the verified five-module mixed US2000/US2000C rack in the upper charging range:
The following real capture shows why relative deviation and absolute voltage
state are displayed together. Cell 8 of module 5 reached 3552 mV while the
module average was 3384.53 mV, a deviation of +167.47 mV. The BMS also reported
the cell as critically overvoltage (BMS CRITICAL: OV), so the tile is marked
as an absolute-voltage fault rather than only as a red relative deviation.
The console exposes read and write commands. Version 0.1 intentionally implements read-only functionality only.
The required pwrsys rack command is available only after the console enters
its authenticated debug mode. Configure exactly one credential source:
export PYLONTECH_CONSOLE_LOGIN_PASSWORD='<console-password>'For production Docker deployments, a password file or Docker Secret is preferred:
export PYLONTECH_CONSOLE_LOGIN_PASSWORD_FILE=/run/secrets/pylontech_console_passwordExample Compose override:
services:
pylontech-console:
secrets:
- pylontech_console_password
secrets:
pylontech_console_password:
file: ./secrets/pylontech-console-password.txtKeep PYLONTECH_CONSOLE_LOGIN_PASSWORD unset when the password-file setting is
used. The two credential sources are mutually exclusive.
The service verifies pylon_debug> before polling, re-verifies the session
after every reconnect and attempts logout during controlled shutdown. The
credential is never returned by REST, Web, MQTT or health output and is
redacted from application diagnostics.
The Waveshare console connection is unencrypted raw TCP. Place it in a
dedicated technical network/VLAN and permit port 4196 only from the Docker
host running Pylontech Console. The Pylontech login changes console mode; it is
not a substitute for network isolation.
MQTT is disabled by default. To publish the read-only current state, provide at least:
export PYLONTECH_MQTT_ENABLED=true
export PYLONTECH_MQTT_HOST=192.168.1.10
docker compose up -dThe default port is 1883, client ID is pylontech-console, topic prefix is
pylontech, and all current-state publications use QoS 1 with retained
payloads. Optional deployment variables configure username/password, TLS,
keepalive, connection timeout, and reconnect limits. Docker Compose passes the
complete PYLONTECH_MQTT_* configuration through to the service; the exact
variables and validation rules are defined in
docs/contracts/mqtt-v0.1.md.
The rack page and GET /api/v1/health show MQTT connection state. MQTT remains
publish-only: it subscribes to no command topics and cannot change battery
state.
Published images use:
docker.io/hrabovszki/pylontech-console
The current main build can be pulled with:
docker pull hrabovszki/pylontech-console:mainEvery main image also has a commit-specific sha-* tag. Version tags such
as v0.1.0-beta.1 publish 0.1.0-beta.1; prereleases do not move latest.
The latest tag is reserved for stable semantic-version releases.
The application exposes its exact build identity at:
GET /api/v1/version
REST, Web, OpenAPI and OCI labels report the same public product version.
CI-built containers also report their exact source commit. A versioned image
is published only when a deliberately created Git tag such as
v0.1.0-beta.1 matches the public version declared by the application.
The published container is configured with the same validated
PYLONTECH_WAVESHARE_*, PYLONTECH_CONSOLE_*, PYLONTECH_HTTP_*,
PYLONTECH_WEB_* and
PYLONTECH_MQTT_* environment variables used by Docker Compose. Images
currently target linux/amd64.
The public Compose setup pulls the published image; it does not require a local
Python installation or image build. Docker Engine with the Compose plugin is
required on a linux/amd64 host.
git clone https://github.com/Hrabovszki1023/pylontech-console.git
cd pylontech-console
cp .env.example .env
mkdir -p secrets
printf '%s\n' '<console-password>' > secrets/pylontech-console-password.txtEdit .env and set at least the address of the Waveshare gateway:
PYLONTECH_WAVESHARE_HOST=192.168.20.211
PYLONTECH_HTTP_PUBLISHED_PORT=8001
PYLONTECH_IMAGE_TAG=mainThe password file must contain only the password accepted by the Pylontech
login command. Do not commit .env or anything below secrets/; both are
ignored by Git.
Pull and start the container:
docker compose pull
docker compose up -d
docker compose psOpen the Web UI at http://<docker-host>:8001/. Verify the REST API and inspect
startup logs with:
curl -fsS http://127.0.0.1:8001/api/v1/health | python3 -m json.tool
curl -fsS http://127.0.0.1:8001/api/v1/version | python3 -m json.tool
docker compose logs --tail=100Docker health means that the local HTTP service responds. A disconnected battery, Waveshare gateway or MQTT broker is reported by the application as degraded/offline but intentionally does not cause a Docker restart loop.
Set the broker values in .env, then recreate the container:
PYLONTECH_MQTT_ENABLED=true
PYLONTECH_MQTT_HOST=192.168.20.196
PYLONTECH_MQTT_PORT=1883
PYLONTECH_MQTT_USERNAME=mqtt_admin
PYLONTECH_MQTT_PASSWORD=<mqtt-password>
PYLONTECH_MQTT_TOPIC_PREFIX=pylontechdocker compose up -dTo update the selected tag and recreate the service:
docker compose pull
docker compose up -dTo stop and remove only the application container and Compose network:
docker compose downNo database or persistent inventory volume is created. The service rediscovers the currently connected modules after every restart.
Developers can replace the published image with a build from the current source tree:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build -dPylontech Console is source-available software. Private, academic and other non-commercial use is permitted under the Pylontech Console Community License. Commercial products, services, installations, support, internal business use, forks and derived works require a separate commercial license from the rights holder.

