Skip to content

docs & features: The Pill MODBUS expansion — Wirenboard, Davis, scanner, stock monitor (March 2026)#197

Merged
orlin369 merged 93 commits intoALLTERCO:mainfrom
orlin369:main
Mar 25, 2026
Merged

docs & features: The Pill MODBUS expansion — Wirenboard, Davis, scanner, stock monitor (March 2026)#197
orlin369 merged 93 commits intoALLTERCO:mainfrom
orlin369:main

Conversation

@orlin369
Copy link
Copy Markdown
Contributor

🔧 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.

Orlin Dimitrov and others added 30 commits February 27, 2026 08:58
- 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>
orlin369 and others added 29 commits March 17, 2026 22:59
- 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>
@orlin369 orlin369 merged commit 82c8bf4 into ALLTERCO:main Mar 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant