Add an offline add-on mode that runs grottserver (works without internet) - #12
Open
FezVrasta wants to merge 1 commit into
Open
Add an offline add-on mode that runs grottserver (works without internet)#12FezVrasta wants to merge 1 commit into
FezVrasta wants to merge 1 commit into
Conversation
Proxy mode cannot run without internet access. `on_accept()` opens the
connection to Growatt before accepting the datalogger and closes the
datalogger's socket when that fails:
forward = Forward().start(self.forward_to[0], self.forward_to[1])
clientsock, clientaddr = self.server.accept()
if forward:
...
else:
clientsock.close()
Keeping that socket open is not sufficient either, because the proxy never
replies to the datalogger: acknowledgements come from the real Growatt
server. With nothing upstream the datalogger is never acknowledged, retries,
and its records arrive mis-framed and fail validation.
grottserver already solves this - it is a local stand-in for the Growatt
server and acknowledges data records itself - but it has no MQTT output at
all, so it cannot feed Home Assistant.
Wire grottserver into Grott's existing publishing pipeline: build a Conf at
startup, take the listen port from it, and call procdata() for each data
record. Because procdata() also runs extensions, the Home Assistant discovery
plugin works unchanged, and MQTT output is identical to proxy mode.
Publishing is wrapped so a failure can never prevent the acknowledgement;
otherwise the datalogger would retry the same record indefinitely.
Expose this as a new add-on mode `offline` alongside `proxy`. Grott's own
configuration only accepts proxy/sniff, so run.sh presents "proxy" to it and
selects the grottserver entry point. The listen port is unchanged, so
switching modes needs no datalogger reconfiguration.
In offline mode the inverter no longer reports to Growatt, so ShinePhone and
ShineServer stop updating. That is inherent to running without the cloud;
proxy remains the default.
The add-on version is deliberately not bumped, and the changelog entry is
filed under Unreleased, so the change fits the existing release process.
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.
Adds an
offlineadd-on mode that runsgrottserverinstead of the proxy, so the add-on keeps producing data with no internet connection and without contacting Growatt at all.proxyremains the default and is unchanged.Why proxy mode cannot do this
grottproxy.on_accept()connects to Growatt before accepting the datalogger, and drops the datalogger if that connection fails:Keeping that socket open isn't sufficient either — I tried that first. The proxy never replies to the datalogger; acknowledgements come from the real Growatt server. With nothing upstream the datalogger is never acknowledged, retries, and its records arrive mis-framed:
So a patched proxy can't stand in for a server.
grottserveralready is one — it ACKs data records (rectype 03/04/50/1b/20), answers pings and handles time sync. Its only gap is that it has no MQTT output at all, so it can't feed Home Assistant.What this does
Wires
grottserverinto Grott's existing publishing pipeline rather than giving it a parallel one:Confat startup (so MQTT settings, extensions and the listen port come from the same configuration as the rest of Grott)procdata(conf, data)for each data recordBecause
procdata()also runs extensions,grottext.hadiscovery works unchanged — MQTT output and Home Assistant entities are identical in both modes. That's the main reason for routing throughprocdata()instead of publishing directly.Publishing is wrapped in
try/exceptso a failure can never prevent the acknowledgement below it; otherwise the datalogger would retry the same record indefinitely.On the add-on side,
modebecomeslist(offline|proxy). Grott's own config only acceptsproxy/sniff, sorun.shpresentsproxyto it and selects thegrottserverentry point. The listen port is unchanged, so switching modes needs no datalogger reconfiguration.Tradeoff
In
offlinemode the inverter no longer reports to Growatt, so ShinePhone and ShineServer stop updating. That's inherent to running without the cloud, not a defect — it's documented in DOCS.md, andproxyremains the default for anyone who wants the app.Testing
Honest summary of what is and isn't covered:
Verified on real hardware — a Growatt
SML0CGU03K(single string on MPPT2, single phase, no battery) behind a ShineLan-X datalogger, Home Assistant OS 18.2 on aarch64, Mosquitto add-on:grottserveracknowledges records andprocdata()publishes them; sensors update continuouslygrowatt_servercloud integration while both were running: local2152.6 Wvs cloud2144.9 W(cloud lags by a poll)Caveat: I validated the
grottserver+procdata()change on my own build of this code, not by building this repository's exact add-on image — I don't have your release/UAT pipeline. The add-on plumbing here is verified only by simulatingrun.sh(mode=proxy→/app/grott.py,mode=offline→/app/grottserver.py,gmode=proxyin both), pluspy_compileand a config schema check. It deserves a run through your normal gates before release.libscrcis already inrequirements.lockandgrottserver.pyis already copied into the image, so no packaging changes were needed.I deliberately did not bump the add-on version, and filed the changelog entry under
Unreleased, so this fits your existing release process rather than pre-empting it.Note
Thanks for maintaining this fork, and for sorting out the redistribution permission with Johan — that's why I brought this here rather than publishing my own derivative. Happy to adjust naming, defaults or docs to fit your conventions.