Read what the repository holds
sigenergy-nem-arb is an agent that plans when a home battery in the National Electricity Market should charge and discharge. Immanuel Lam wrote it for the 'Built with Opus 4.7' hackathon and publishes it under the MIT licence; the repository was created on 22 April 2026, took its last commit two days later, carries 19 commits co-authored by Claude Opus 4.7, and had no stars and no forks on 17 October 2026. The README is candid about its scope: it runs on "exactly one house", a Sydney home with a 64 kWh Sigenergy pack, two inverters and 24 kWp of solar, and it ends with "Owner: Immanuel. Sole user, sole house." It is a Python 3.12 backend with a Next.js dashboard, and the README reports 146 passing tests, which I did not run.
The pipeline is short. Two functions in arb/ingest/aemo.py pull NEMweb zip files for five-minute predispatch and for dispatch prices, NSW1 only; a third module calls Amber's price API when the owner has a key. A greedy scheduler pairs cheap intervals with dear ones, scores each pair by spread times round-trip efficiency less a 2 c/kWh cycle penalty, and fills the plan from the top. Opus 4.7 then writes a two-sentence rationale and never touches the schedule, which is the right way round.
Correct three easy assumptions
The weather comes from Open-Meteo, not the Bureau of Meteorology, even though the file is named bom.py, and the solar forecast is a clear-sky curve derated by cloud cover with a fixed factor of 0.75 and a fixed 24 kWp array, not a commercial irradiance product. The 30 in the code is how often the loop wakes, not a price resolution; the repository fetches no 30-minute prices, and since five-minute settlement began on 1 October 2021 the five-minute dispatch price is the one a battery is paid. The NEMweb paths still answer, and at 7.40 am on 17 October 2026 the dispatch file gave NSW1 a regional price of $69.90/MWh while the predispatch run of the same minute forecast $6.06 for 8.20 am.
The backtest needs the most care. Over seven days in April 2026 the agent cost $0.17 against $41.52 for Amber's own SmartShift, but the author ran it with perfect foresight and says real forecasting error "would reduce the headline numbers somewhat". The agent's row is also identical to plain self-consumption, to the cent and the kilowatt-hour, because the export price sat at or below zero all week and the agent declined to trade. The saving came from not playing.
Fix the kill switch first
The actuator, arb/actuator/ha_control.py, writes to the inverter through Home Assistant using the community Sigenergy-Local-Modbus integration. Its limits are real. It refuses to discharge within one point of the 10% floor or to charge within one point of the 95% ceiling, caps writes at ten an hour, honours ARB_KILL=1, defaults to dry-run and logs every attempt. In each of the three write functions, however, the dry-run branch returns success before the code reads the kill switch, so a dry-run log cannot show whether the switch would have held. The write counter also lives in process memory, so every run started with --once begins with a clean slate. None of this has met a live inverter yet; the README says no live writes happened during the hackathon.
Add what a fleet needs
The solution I would build on this keeps the agent's shape and adds the parts an installer answers for. The Modbus map already defines registers for cell temperature and state of health, and nothing reads them; the design puts both in front of every write, so a hot or ageing pack stops trading before the optimiser asks. It counts cycles against the warranty rather than pricing them at 2 cents and moving on, moves the kill-switch check ahead of the dry-run branch, and keeps the write counter on disk, where a restart cannot clear it.
Keep the owner at the gate
Go-live comes in stages: a fortnight or more of dry-run against live prices with the audit log read by a person, then supervised writes that the owner confirms one at a time, then unattended writes inside the limits, with the owner or installer approving each step and the agent approving none of them. Nobody skips a stage. See the design, its diagram and the demo at the solution.
A good scheduler earns its keep mostly by refusing bad trades.