docs & features: The Pill MODBUS expansion — Wirenboard, Davis, scanner, stock monitor (March 2026)#197
Merged
orlin369 merged 93 commits intoALLTERCO:mainfrom Mar 25, 2026
Merged
Conversation
- Reorganize JK200 BMS script under JKESS brand subdirectory - No code changes; path rename only Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Implement Modbus RTU master for LinkedGo ST802 Youth Smart Thermostat - Support FC03 (read), FC06 (write single), CRC-16 table-based framing - Cover control registers 0x1001-0x1019 and read-only 0x2101-0x211A - Add 8 BMS simulation scenarios (morning heat, cooling, economy, etc.) - Add ENABLE flag object for individually toggling poll actions and scenarios - Status: under construction; tested on live device at 9600/8N1 RS485 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Document upload workflow: non-ASCII sanitization, 4000-char chunking, stored-length verification, and log streaming pattern - Include error table for HTTP 413 and 500 with root causes and fixes - Include full Python deploy+monitor reference script Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add entry for LinkedGo ST802 Modbus RTU BMS client - Add entry for Shelly deploy/monitor skill document - Add entry for JK200 → JKESS/JK200-MBS path rename Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove stale JK200-MBS old path from manifest - Add JKESS/JK200-MBS new path to manifest - Regenerate SHELLY_MJS.md Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- @status changed from 'under construction' to 'production' - @link added pointing to orlin369/shelly-script-examples main branch - POLL_MODE, POLL_FAN_SPEED, POLL_HUMIDITY enable flags added - readMode, readFanSpeed, readHumidity functions added - pollStatus chain extended with doMode, doFanSpeed, doHumidity steps - Manifest entry added; SHELLY_MJS.md regenerated - CHANGELOG updated Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces skills/modbus-device-template.md as the canonical reference for writing new Modbus RTU device drivers on Shelly (mJS) or plain software (Node.js). Covers: - Concepts table (addr, rtype, itype, bo/wo, scale, rights, vcId/vcHandle, handle) - JSDoc file header convention (@title, @description, @status, @link) - CONFIG block structure (UART, Modbus, poll settings) - Full ENTITIES array with nested reg: { addr, rtype, itype, bo, wo } sub-object - Runtime STATE skeleton and poll-next loop - Shelly vs software platform shim (Timer.set / setTimeout, print / console.log) - Bring-up checklist Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the flat { addr, itype, scale } per-entity shape with the canonical
nested structure from skills/modbus-device-template.md:
reg: { addr, rtype: 0x03, itype, bo: "BE", wo: "BE" }
scale, rights: "R", vcId: null, handle: null, vcHandle: null
Changes:
- Added group comments (Solar/Battery, Grid, Battery, DC Input, AC Output)
- Updated pollEntities/readNext: entity.addr -> entity.reg.addr,
entity.itype -> entity.reg.itype
- Marked @status under development (pending Monday field test)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Same structural change as the_pill_mbsa_deye.shelly.js but for the
Virtual Component variant that pushes values to Shelly virtual number slots.
Changes:
- Nested reg: { addr, rtype: 0x03, itype, bo, wo } per entity
- vcId retains real slot assignments ("number:200" .. "number:208")
- handle/vcHandle initialised to null (populated at runtime)
- rights: "R" added to all entries
- Updated pollEntities: entity.addr -> entity.reg.addr,
entity.itype -> entity.reg.itype
- init() VC handle loop unchanged (uses ent.vcId as before)
- Marked @status under development (pending Monday field test)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… map
JK200 uses bulk block reads rather than per-register polls, so the existing
REG block-coord constants (CELLS_BASE, MAIN_BASE, MAIN_QTY) are preserved
unchanged for the actual UART transactions.
A new ENTITIES array is added purely as a documentation / metadata layer
for the 9 logical values extracted from Block B (0x128A-0x1298):
- MOSFET Temperature (0x128A, i16, *0.1, degC)
- Pack Voltage (0x128D, u32, *1, mV)
- Pack Power (0x128F, i32, *1, mW)
- Pack Current (0x1291, i32, *1, mA)
- Temperature 1/2 (0x1293/4, i16, *0.1, degC)
- Alarm Bitmask (0x1295, u32, *1, -)
- Balance Current (0x1297, i16, *1, mA)
- State of Charge (0x1298, u16, *1, %)
Each entry follows the canonical template shape:
reg: { addr, rtype: 0x04, itype, bo: "BE", wo: "BE" }
scale, rights: "R", vcId: null, handle: null, vcHandle: null
The long register-layout comment before parseMainBlock is replaced with
a concise cross-reference to ENTITIES with block offsets.
parseCellBlock / parseMainBlock logic is unchanged.
Marked @status under development (pending Monday field test).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The old MB308V = { DI_COUNT, DO_COUNT, AI_COUNT, AO_COUNT, AI_MAX_VALUE,
AO_MAX_VALUE } object is removed and replaced with:
1. Standalone calibration constants:
var AI_MAX_VALUE = 10216;
var AO_MAX_VALUE = 24000;
2. A 32-entry ENTITIES array covering all four I/O types, each with the
canonical template shape (reg.rtype encodes the Modbus FC):
DI 0-7 : rtype 0x02 (Read Discrete Inputs), itype "bool", rights "R"
DO 0-11 : rtype 0x01 (Read Coils), itype "bool", rights "RW"
AI 0-7 : rtype 0x04 (Read Input Registers), itype "u16", rights "R"
AO 0-3 : rtype 0x03 (Read Holding Registers), itype "u16", rights "RW"
3. entitiesByRtype(rtype) helper — filters ENTITIES by FC code, used by all
API functions to get both the count and per-channel addresses.
API function updates (logic preserved, counts/addresses now from ENTITIES):
readDigitalInputs -> entitiesByRtype(0x02)
readDigitalOutputs -> entitiesByRtype(0x01)
writeDigitalOutput -> entitiesByRtype(0x01)[channel].reg.addr
readAnalogInputs -> entitiesByRtype(0x04)
readAnalogOutputs -> entitiesByRtype(0x03)
writeAnalogOutput -> entitiesByRtype(0x03)[channel].reg.addr
aiToMilliamps / aiToVoltage / milliampsToAo / voltageToAo
-> standalone AI_MAX_VALUE / AO_MAX_VALUE
Already @status under development — no status change needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The flat REG object (14 raw address constants) is replaced with:
1. An ENTITIES array (14 entries) each carrying a key field, full canonical
template shape, and semantic metadata:
Control registers (rights "RW"):
POWER 0x1001, SYS_TYPE 0x1003, MODE 0x1004, HC_SELECT 0x1006,
FAN_SPEED 0x1007, SETPOINT 0x1008 (scale 0.1 degC),
HUMIDITY_SP 0x1009 (scale 0.1 %), MIN_SP 0x1018, MAX_SP 0x1019
Sensor registers (rights "R"):
ROOM_TEMP 0x2101, HUMIDITY 0x2102, FLOOR_TEMP 0x2103,
RELAY_STATE 0x2110, ALARM 0x211A
2. A load-time loop that rebuilds REG from ENTITIES:
var REG = {};
for (var _ei = 0; _ei < ENTITIES.length; _ei++) {
REG[ENTITIES[_ei].key] = ENTITIES[_ei].reg.addr;
}
All 20+ API functions (setPower, setMode, readTemperatures, etc.) that
reference REG.* constants are left completely unchanged.
Marked @status under development (pending Monday field test).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces a canonical ENTITIES table structure (from skills/modbus-device-template.md) across all Modbus RTU device scripts in the_pill/MODBUS/: - skills/modbus-device-template.md — new skill file (canonical reference) - Deye/the_pill_mbsa_deye.shelly.js — flat ENTITIES -> nested reg sub-object - Deye/the_pill_mbsa_deye_vc.shelly.js — same; vcId slots preserved - JKESS/JK200-MBS/the_pill_mbsa_jk200.shelly.js — ENTITIES metadata layer added; block-read REG coords unchanged - ComWinTop/mb308v.shelly.js — MB308V object replaced with typed ENTITIES + entitiesByRtype() helper - LinkedGo/ST802/st802_bms.shelly.js — ENTITIES + load-time REG derivation; all API functions unchanged All modified device scripts marked @status under development for Monday testing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename the_pill_mbsa_deye.shelly.js -> deye.shelly.js to match the naming convention used by other device scripts in the project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename the_pill_mbsa_deye_vc.shelly.js -> deye_vc.shelly.js to match the naming convention used by other VC scripts in the project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Rename the_pill_mbsa_jk200.shelly.js -> jk200.shelly.js to match the naming convention used by other device scripts in the project. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds jk200_vc.shelly.js with 9 VCs (number:200-208) covering all BMS telemetry: MOSFET temperature, pack voltage/current/power, cell temps, alarm bitmask, balance current, and state of charge. One group:200 bundles all VCs in the Shelly web UI. VC updates are emitted from parseMainBlock() after each value is computed, using the same updateVc() pattern as the Deye VC script. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds mb308v_vc.shelly.js with a focused 9-VC demo layout in one group: button:200/201 relay toggle buttons (press to flip DO 0/1) number:200/201 DI 0/1 live displays (read-only, script writes) number:202/203 AO 0/1 sliders (persisted; user sets, script reads) number:204/205 AI 0/1 progress bars (read-only, script writes) group:200 MB308V Demo Relay toggling via Shelly.addEventHandler (button push events). AO slider writes are debounced: hardware is only written when the slider value changes from the previous poll cycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds st802_bms_vc.shelly.js with 9 VCs (number:200-208) covering key thermostat state and controls: room temperature, humidity, floor temperature, relay state, alarm, mode, fan speed, setpoint, and power. One group:200 bundles all VCs in the Shelly web UI. VCs are updated from each read callback (readTemperatures, readRelayStatus, readAlarm, readMode, readFanSpeed) and from write functions after a successful register write. Two new poll stages (doSetpoint / doPower) extend the poll chain to keep setpoint and power state current. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds skills/modbus-vc-deploy.md describing the complete workflow for
deploying any *_vc.shelly.js MODBUS script:
1. Read VC requirements from the JS file (vcId fields + header comment)
2. Verify device reachability (gen-3, firmware >= 1.3.0)
3. Create VCs via curl — per-device tables for Deye, JK200, MB308V, ST802
including the mixed button+number layout used by the MB308V demo
4. Upload script via tools/put_script.py (falls back to chunked curl)
5. Monitor logs; expected output patterns for each device
6. Verify VC values via Virtual.GetStatus HTTP call
Also includes an automated Python helper (modbus_vc_setup.py) that
parses vcId values from the JS file, provisions all VCs, and calls
put_script.py to upload and start the script.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Virtual Component variants for all MODBUS device scripts and a deployment skill: - Rename Deye/JK200 scripts to shorter filenames (deye.shelly.js, deye_vc.shelly.js, jk200.shelly.js) - jk200_vc.shelly.js: 9 VCs (number:200-208), all BMS telemetry - mb308v_vc.shelly.js: mixed layout — 2 relay buttons, 2 DI displays, 2 AO sliders, 2 AI progress bars, 1 group (group:200) - st802_bms_vc.shelly.js: 9 VCs covering thermostat sensors + controls - skills/modbus-vc-deploy.md: step-by-step VC provisioning guide with per-device curl tables and a Python automation helper Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace generic RS485 module references with The Pill 5-Terminal Add-on pin mapping: IO1 (TX) → B (D-), IO2 (RX) → A (D+), IO3 → DE/RE direction control (handled automatically by the hardware). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add the_pill/MODBUS/utils/modbus_scan.shelly.js: two-phase scanner that sweeps all baud/mode/slaveID combos (ping phase) then reads configurable PROBE_REGS to identify each found device; includes vendor-specific probes for Wirenboard, JK BMS, Deye, CWT, LinkedGo - Remove wb_m1w2_scan.shelly.js (device-specific, replaced by above) - Add utils/README.md with usage guide and sample output - Update WB-M1W2-v3 README to reference new shared scanner - Update MODBUS root README to index utils/ folder - Update CHANGELOG.md with 2026-03 entry Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds production-ready script for reading solar irradiance (W/m2) from a Davis-compatible RS-485 pyranometer via MODBUS-RTU on The Pill. Discovered parameters: slave=1, 9600 baud, 8N1, FC04 addr 0x0000. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds pyranometer_vc.shelly.js alongside the plain reader, pushing solar irradiance (W/m2) to virtual number:200 after each poll cycle. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix exception code: use rxBuffer[2] instead of fc & 0x7F (plain script) - Fix processResponse min-length guard: < 5 instead of < 3 (plain script) - Remove unreachable length < 3 guard after >= 5 check (vc script) - Remove unused handle field from ENTITIES (vc script) - Rename clearResponseTimeout -> clearResponseTimer for consistency (vc script) - Fix @link path: lowercase davis -> Davis (plain script) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- modbus-scan-discover.md: how to use modbus_scan.shelly.js to find unknown MODBUS-RTU devices (wiring, upload, log interpretation, parameter recording) - shelly-vc-manage.md: create/delete/group Virtual Components via RPC, home screen visibility rules, VC init order for scripts - modbus-sensor-integrate.md: end-to-end workflow from scan to commit (discovery -> plain script -> VC script -> README -> simplify -> push) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add Davis pyranometer MODBUS-RTU reader and Virtual Components scripts - Add README for Davis Pyranometer examples - Mark modbus_scan.shelly.js as production - Add screenshot of Virtual Components dashboard - Add skills: modbus-scan-discover, shelly-vc-manage, modbus-sensor-integrate Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ction) - examples-manifest.json: +3 entries (pyranometer, pyranometer_vc, modbus_scan) - SHELLY_MJS.md: regenerated index, 111 production entries total Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…production - Add wb_m1w2_v3_vc.shelly.js: MODBUS-RTU reader with Virtual Component updates (temperatures, inputs, sensor presence, supply voltage in V, pulse counters) - Add configureVcMetadata() to push units to number VCs on startup - Promote wb_m1w2_v3.shelly.js to production - Register both scripts in examples-manifest.json - Add Shelly UI screenshot (image.png) - Regenerate SHELLY_MJS.md index Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- promote WB-MIR v3 reader, VC, and reconfiguration scripts to production - update WB-MIR v3 VC behavior, docs, manifest, and generated index Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- add dedicated WB-MIR v3 IR learn, play, dump, and erase script - document the IR utility in the WB-MIR README and changelog Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- replace the WB-M1W2 v3 image asset with updated screenshots - add a WB-MIR v3 screenshot asset Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- add screenshot sections to the Wirenboard root README - add device screenshot references to WB-M1W2 v3 and WB-MIR v3 READMEs Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Rename stock-monitor.shelly.js -> stock-monitor_vc.shelly.js - Fix mJS compat: Number.isFinite -> isFinite, padStart -> pad2 - Set @status production and correct @link in script header - Update finance-yahoo README: file ref, screenshot section, drop dev note - Update http-integrations README: file ref - Add screenshot.png for Shelly UI Virtual Components view - Regenerate manifest and SHELLY_MJS.md (117 entries, +1) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Update the_pill/README.md: accurate production/dev statuses, expand MODBUS subtree with per-device links - Remove dev warning from UART/README.md (script is production) - Add wb_m1w2_v3_vc.shelly.js and VC mapping table to WB-M1W2-v3 README - Add wb_mir_v3_reconfig.shelly.js to WB-MIR-v-3 README; mark IR utility as under development Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
🔧 Installers
I added ready-to-run scripts for the Wirenboard WB-M1W2 v3 and WB-MIR v3 so you can walk on-site, wire The Pill to the RS485 bus, upload one script, and hand the client a working Shelly UI with live temperatures, inputs, and module status — no laptop, no vendor software.
I also included a one-shot reconfiguration utility so you can change the slave ID and baud rate of a WB-MIR v3 right from the device before you leave the job.
🏗️ Integrators
I built a universal MODBUS scanner that sweeps every baud rate, parity mode, and slave ID combination on the bus and tells you exactly what it found, so you stop guessing during commissioning.
Every new device now has a Virtual Components variant that surfaces telemetry directly in the Shelly UI, and the MODBUS HTTP Bridge I included lets any platform in your stack read or write individual registers over a plain HTTP call.
🛠️ DIY
I added full Davis pyranometer support so you can finally correlate your solar irradiance with actual PV output — all locally, with a register map and screenshot so nothing is a black box.
The WB-MIR v3 IR utility also lets you learn, store, replay, and erase IR commands from any NEC remote directly from a Shelly script — no extra hardware, no cloud.
🏠 End-users
I wired everything together so your battery, inverter, thermostat, air quality sensor, and solar panel readings all show up in the Shelly app on your phone, running entirely on your home network.
I even added a stock price monitor so your Shelly device can keep an eye on the market alongside your home.