Hi Mats,
Sorry for the late reply (I was on a business trip).
Good news — it’s already there, on the Solis Grid device rather than the inverter. It keeps two running totals: Imported energy and Exported energy, both in kWh and both surviving restarts. Open that device and tap Insights and you can chart either one per day, week, month or year. The device also registers itself as your grid meter in Homey’s Energy tab, so any price app (Tibber, Frank, Zonneplan…) can put amounts against it.
I keep them separate on purpose, since what you pay for a kWh and what you get for one are rarely the same — subtract them if you want the net figure.
Two things to be aware of before you base money on it. These totals are built up by the app itself, by measuring power every few seconds from the moment you added the device, so they start at zero and will drift a little from your utility meter over months your supplier settles on your P1 meter, not on this. And if you don’t have a CT or meter fitted to the inverter, the figures cover only the inverter’s own grid connection, not loads on other circuits in the house.
I’ve written all of this up in the manual: Solis Local Hybrid Inverter for Homey — User Manual
best regards,
Remco Bosshard
Thanks for writing, and sorry for the disappointing result.
The short answer is that your S6-GR1P2.5K-M won’t work with this app, and that isn’t something I can fix with a setting. Your inverter is a grid-tied (string) model, and this app is built specifically for the hybrid S6 range with a battery — it reads the energy-storage registers for battery charge, battery power and the grid port, and drives charging and discharging. A grid-tied inverter uses a completely different register map and has none of those registers, so the app fails on its very first read. That is the “modbus exception 2” you would have seen.
Your data logger isn’t the problem, for what it’s worth. The S2-WL-ST does speak Modbus locally, and this app was originally built against that exact stick, so the local route you’re hoping for does exist in principle. What’s missing is support for the grid-tied register map, and that would mean a different app rather than an addition to this one. It’s not something I’m planning to build, since I have no grid-tied hardware to develop or test against, and I’d rather not ship something I can’t verify.
One small improvement is on the way: in the next update, pairing will tell you plainly that the inverter looks like a grid-tied model and isn’t supported, instead of leaving you with a cryptic Modbus error. That won’t give you your data, but at least it won’t waste your time.
If local monitoring is what you’re after, it’s worth looking for a Solis grid-tied Modbus integration outside Homey — the register map for those models is documented and others have worked with it. I’m sorry I can’t be more help than that.
Kind regards,
Remco Bosshard
I can’t speak for Zonneplan setups — I don’t have one and nobody has reported back with one yet, so you’d be the first I know of.
The limits are structural rather than a matter of app support. A Solis serves only one Modbus master at a time, so it matters what is already sitting on the inverter’s COM / data-logger port. And Zonneplan’s trading works by their software dispatching your battery continuously; this app’s control side does the same thing. Two controllers steering one battery just fight each other, so it is either/or: either Zonneplan trades, or you take local control and give up what you’re paying them for.
Monitoring is a different story. If you can reach the inverter over Modbus without displacing Zonneplan’s connection, reading solar production, battery level and grid power interferes with nothing — and that may be all you want.
One caveat: the app is built for the hybrid S6 energy-storage range. If the battery uses a different inverter, it won’t pair at all.
Thanks — this is one of the most useful reports I’ve had, and you had already diagnosed most of it correctly. Taking your questions in order.
-
No. “Report grid power” never reaches the inverter. It stores the value inside the app, where the app’s own logic uses it. The inverter’s Self-use loop follows its own CT/meter, and since yours is configured as No meter, it has nothing to follow — which is exactly why the battery sits at 0 W while you import. I’m not aware of a register that injects an external meter reading into that loop; if your firmware has one, I’d gladly test it with you.
-
Your reading is right. Until now the grid feed drove charge-side logic only: deriving house load, trimming a solar-surplus charge, the grid-import breaker guard, the self-consumption charge limiter, follow-the-sun charging, and telemetry to the optimiser. Nothing closed a loop on discharge. The self-consumption controller only ever raises or lowers the charge limit and floors at zero — on your system, with no PV on the Solis, it has nothing to work with at all.
-
Effectively yes. Your reads and your successful control prove the energy-storage register map matches. Be aware, though, that several features are PV-dependent and will never engage for you: follow-the-sun charging, solar-surplus trimming and the self-consumption charge limiter all need PV on the Solis itself. I develop against an S6-EH3P10K2-H hybrid, so yours is the first AC-coupled unit I’ve had data from.
-
It didn’t exist — forced discharge in amps, held flat, was the only discharge control, which is why you saw 9.5 kW going out to the grid. Internally the dispatch path was already watt-based and re-poked on a timer, so the plumbing was there; the closed loop on top was not.
-
It is now built, and it’s in the next release.
There’s a new Flow action, “Cover the house from the battery, up to W”. It reads your whole-home meter, compares it to a target, and walks the discharge setpoint until the grid sits there — supplying the deficit and nothing more. It never drives past zero, so it can’t turn into a forced export the way a fixed discharge does. It re-evaluates every 8 seconds, which is roughly what your own script does at 10. Stop it with “Stop forced charge or discharge”.
Keep your existing Flow feeding “Report grid power” from the P1 dongle — that’s the signal it follows. Under Load following in the device settings you can set the maximum discharge power, the grid target (0 = neither importing nor exporting; negative keeps a deliberate export margin) and the deadband (how far the grid may drift before it corrects — raise it if you see it hunting). It refuses to start, with an explanation rather than a silent no-op, if there’s no fresh grid reading or if the battery is at its minimum SOC.
Your screenshots turned up two other things worth knowing.
“Home consumption 0 W” in your first and third shots is the app being wrong, not your system. It derives house load as PV − battery + grid, which assumes all your panels hang off the Solis. Yours are on the SMA, so the derivation is short by exactly the SMA’s output and clamps at zero — in your second screenshot it shows 2699 W while the real figure was about 3.4 kW. Fixed in the same release: if you send the true figure in with the “Report house load” Flow action (from the Energy Dongle), the device now uses it instead of the derivation.
And treat “Grid power” on the Solis device with suspicion on your setup. With no meter fitted, that register falls back to the inverter’s own AC port rather than your grid connection. Your third screenshot shows it plainly: the app reads 1400 W while the Energy Dongle reads −16 W. Your dongle is the truth; the Solis figure is the inverter’s own exchange. The same applies to the separate Solis Grid device’s import/export totals, if you added it.
One caution: I see a Modbus device in your device list. Once you switch to the built-in controller, do stop whatever is writing to the inverter from outside the app — the Solis serves one Modbus master at a time, and two controllers writing setpoints will fight each other.
I’d genuinely appreciate hearing how it behaves on your hardware, particularly whether the deadband and the 8-second cadence are stable with a 10 kW pack, or whether it hunts. If it does, raising the deadband is the first thing to try.
Thanks for the detailed reply. Since my previous post, we have investigated the setup further and made a number of changes. Because my configuration differs quite a bit from the typical hybrid setup with PV connected directly to the Solis, I’ll describe exactly which flows/scripts I’m currently using and what they do.
1. Flow: Report grid power to solis
This Advanced Flow is triggered whenever the power reading of my Homey Energy Dongle (P1 dongle) changes.
The actual grid measurement from the Homey Energy Dongle is sent directly to:
Report grid power [P1 Power]
where:
- positive value = grid import
- negative value = grid export
So in my installation, the Homey Energy Dongle is the reliable whole-home grid meter.
The Solis itself is configured as No meter, so I do not use the Solis Grid power value as the actual grid connection reference.
Report house load is currently not actively connected. We previously calculated the external house load as:
house load ≈ P1 + SMA AC + Solis AC
but since you mentioned that the next release will make better use of Report house load for this AC-coupled situation, I would like to test that again properly after the update.
Report EV charge power is currently not active either.
2. Advanced Flow: batterij test
This is my own real-time battery controller.
The flow currently runs every 2 seconds and starts a HomeyScript.
The script reads, among other things:
- P1 grid power from the Homey Energy Dongle
- battery SOC
- current battery state
- current charge/discharge mode
It then tries to regulate the battery in small steps.
For charging I used force_charge, and for discharging force_discharge.
The idea was:
- when exporting → increase battery charging
- when importing → reduce charging or start discharging
- keep the grid exchange as close to 0 W as possible
This worked functionally, but during discharge I ran into exactly the issue you described:
force_discharge is a fixed current setpoint and does not close the loop on the P1 measurement itself.
As a result, the battery could overshoot badly, and during one test we saw roughly 9.5 kW being exported to the grid.
Your new closed-loop action “Protect house from battery up to … W” therefore looks like exactly the right replacement for the discharge part of my own script.
3. Flow: Thuisbatterij snelladen aan
I currently use this standard flow as a temporary “fast charge” mode.
When started, it does two things:
- disables
Report grid power to solis - disables
batterij test
So no explicit force_charge command is sent.
What happens next is interesting:
once both the P1 feed and my own real-time battery controller are disabled, the Solis starts charging at a very high power by itself.
During a test we observed roughly:
- battery power: ~9.4 kW charging
- Solis AC power: around -9.7 kW
- SOC: around 42%
So this at least shows that the S6-EA3P10KAA-NV-ND-H can reach close to full charge power without using force_charge.
4. Flow: Thuisbatterij snelladen uit
This does the exact opposite:
- enables
Report grid power to solisagain - enables
batterij testagain
This restores the normal external control.
5. Advanced Flow: Goedkoop bijladen
I currently use this as a simple price-based test.
The trigger is:
Electricity price changes to one of today's cheapest hours
The flow then checks the battery SOC.
The current simple logic is:
-
if SOC < 60%:
- start
Thuisbatterij snelladen aan - wait 60 minutes
- start
Thuisbatterij snelladen uit
- start
-
if SOC ≥ 60%:
- start
Thuisbatterij snelladen aan - wait 30 minutes
- start
Thuisbatterij snelladen uit
- start
This is intentionally still very basic.
The final idea is not to always charge for a fixed 30 or 60 minutes, but to determine at the start of a cheap period what SOC the battery should ideally have according to a desired day/solar curve, and only top up the missing amount.
6. What we have confirmed about the measurements
The Homey Energy Dongle is the only reliable grid reference in my installation.
The visible Solis Grid power value is not usable as the actual grid connection value without a physical Solis meter.
Home consumption is also incorrect in the current app version for my setup, because the PV production is on a separate SMA STP 10.0-3AV-40 and is therefore not measured by the Solis itself.
In Homey Insights we saw, for example, around 14:00:
Home consumption≈ 1 WBattery Power Usage≈ 5.6 kW
while there was obviously real house consumption at that time.
This matches your explanation that the current house-load calculation misses the external SMA production and then gets clipped to zero.
For an external house-load calculation we currently arrive at approximately:
house load = P1 + SMA AC + Solis AC
with:
- Homey Energy Dongle P1 positive = import
- P1 negative = export
- SMA AC positive = PV production
- Solis AC negative = battery charging
- Solis AC positive = battery discharging
One concrete example we measured was:
P1 (Homey Energy Dongle) -162 W + SMA 6501 W + Solis AC -4320 W ≈ 2019 W house load
This also matched reasonably well with the actual loads that were switched on.
7. What I would like to test after your next release
My plan would be:
- permanently feed
Report grid powerwith the actual P1 value from the Homey Energy Dongle - use your new closed-loop discharge controller instead of my own
force_dischargeloop - start with a grid target of 0 W
- start with a reasonably wide deadband
- see whether the 8-second control loop remains stable on this 10 kW AC-coupled unit
If that works well, my own 2-second discharge logic can probably be removed completely.
For strategic charging / cheap-grid charging, I would then only keep a separate planner that decides:
- when additional charging is needed
- what SOC target is desired at that moment
- how much energy still needs to be added
- whether that should happen during a cheap electricity period
8. Idea for AC-coupled installations: Report external PV power
Because my PV is not connected to the Solis itself but to a separate SMA STP 10.0-3AV-40, the Solis app currently sees no actual PV power.
Would it be possible to add an extra Flow action such as:
Report external PV power [power] W
In my case I could feed the actual AC power from the SMA directly into that action.
I think this could be useful for installations where:
- the battery is AC-coupled
- the PV is connected to a separate inverter
- the Solis therefore sees 0 W PV
If some of your internal functions currently depend on “PV power on the Solis”, an external PV feed could perhaps be used as a substitute PV source for things like solar following, solar surplus calculations and possibly self-consumption charging logic.
In my setup the main external signals would then become:
Report grid power← Homey Energy DongleReport house load← external/calculated house loadReport EV charge power← EV chargerReport external PV power← SMA AC power
That would effectively give the app all relevant energy flows, even though there are no PV strings physically connected to the Solis.
9. EMS / further automation
Apart from the low-level Solis control, I am also still looking for a good EMS that can coordinate everything together:
- battery charging and discharging
- dynamic electricity prices
- solar forecast
- house consumption
- EV charging
- desired SOC at different times of the day
At the moment I am experimenting with SlimLaden within Homey, but I may ultimately build my own EMS/planner on top of Homey and your Solis app.
My installation is somewhat unusual because of the separate SMA PV inverter combined with an AC-coupled Solis battery inverter, so a generic EMS may not cover everything properly.
My current idea is to leave the fast real-time power control as much as possible to your app, and place a strategic planner above it that decides things like:
- what SOC the battery should ideally have at a certain time
- how much solar energy is still expected that day
- whether there is an expected energy shortfall
- whether that shortfall should be topped up during one of the cheapest electricity periods
I’m also curious how you handle this in your own installation.
Do you use a separate EMS, Homey logic, your own software/scripts, or do you mainly rely on the control logic built into the Solis itself?
I’m especially interested in the strategic layer: not only real-time charging/discharging, but also decisions based on dynamic prices, expected solar production and desired SOC later in the day.
If useful, I can also provide logs after the next release containing:
- P1 power from the Homey Energy Dongle
- SMA power
- Solis AC power
- battery power
- SOC
- target
- deadband
- selected charge/discharge mode
That should make it possible to see quite clearly how the controller behaves on this AC-coupled S6-EA3P10KAA-NV-ND-H.
Hi, Could you add register 33249 – EPM real-time backflow power?
The current grid power reading is sometimes off by about 100–200 W. Having the EPM real-time backflow power as a separate value would make the grid/export figure more accurate.
Thanks for the suggestion — I checked 33249 on my own S6 before answering, and unfortunately it won’t help.
It returns exactly the same value as 33130, the register the app already reads. I sampled both together for 30 seconds while the house load moved around, and the difference was 0 W on every sample except one, where it was 1 W — and that was just the two reads landing a fraction of a second apart.
Two details in case they’re useful:
- 33249 is a signed 16-bit value in watts, with the same sign convention as 33130. 33250 reads a constant 0, so it is not the low word of a 32-bit value. Reading the two as a pair gives about −8,192,000 W, which is how this register usually gets mis-decoded.
- Being 16-bit, it actually clips beyond ±32.767 kW, where 33130 is a proper 32-bit value. So for this purpose it’s a slightly worse version of what the app already uses.
Both come from the same CT — one measurement exposed twice, not a second sensor.
Where the 100–200 W really comes from
Three things stacked up, and none are fixable by reading a different register:
- Different measurement points. The Solis measures at wherever its CT is clamped; your P1 measures at the revenue meter. Anything wired between the two is invisible to one of them.
- Different sampling rates. The app polls the inverter every 10 seconds; a P1 dongle updates roughly once a second. Two snapshots of a moving house load differ by exactly this order of magnitude — which is also why it’s “sometimes”, since the gap is biggest when the load is changing.
- Instrument class. A CT clamp is typically a 1–2% device. At 10 kW that is 100–200 W. Your P1 reads a revenue-grade meter. The two will never fully agree.
What I’ve done instead
Version 0.1.80 is going to Test now, and it changes where the grid figure comes from. If you feed your P1 reading into the app with the Report grid power Flow action, the grid power shown on the device — and used for the Energy tab totals — now follows your meter instead of the inverter’s own reading. Previously only the internal controllers used the value you fed in, while the displayed number still came from the inverter, which is a bit of a trap.
That should make the displayed figure match your P1 directly, which I think is what you were actually after. It also fixes a worse version of the same problem for anyone running the inverter without a meter fitted, where that register reports the inverter’s own AC connection rather than the grid connection and can be off by kilowatts rather than watts.
I’ve also added the inverter’s own reading to the app’s internal diagnostics alongside the reported one, so if the two ever diverge in a way that matters it’s visible rather than something you have to spot by eye.
If you’re on the Test version, I’d be glad to hear whether the displayed value now lines up with your P1.
One question
Is the 100–200 W causing something to behave incorrectly, or is it mainly that the two numbers don’t agree? If something is actually mis-controlling because of it I’d much rather chase that — a small mismatch between two different meters is expected, but a controller hunting on it is not.
Thanks @Anders_Gunnarsson — that’s a fair correction, and genuinely useful to hear. My write-up overstates it, and I’ve updated the first post accordingly.
What I actually measured was narrow: on my own stick and its firmware, local writes wedged after about 13 minutes under a sustained dispatch — the inverter would quietly drift back to self-use mid-command. For monitoring it was completely fine. I wired a gateway to get past that, and then wrote it up as though it were the general answer rather than my result on one unit. That was the mistake.
Worth saying that the app doesn’t require the gateway either. It pairs by IP, port and unit ID, so it’ll talk to any Modbus TCP endpoint — the stock data logger included. That was my original setup before I switched, and it still works if you point it there.
If you’re ever able to say anything about which logger models and firmware hold up, or how you keep a control session alive past that point, I’d be glad to hear it and to update the manual so people aren’t buying hardware they don’t need. No expectation at all — I understand it’s part of a commercial product.
That’s strange; on my S6 connected via RS485 to an AMX-FX3U PLC, 33249 register displays correctly. See for yourself https://drive.google.com/file/d/1NsrfC9XobZKYl0E5SJmhma-TJkV8L_XP/view?usp=sharing
I want to use the Grid Power parameter to turn on the air conditioning when the inverter is feeding energy into the grid. So far, it hasn’t been working very well, there are spikes that trigger the AC for a moment and then switch it off again, and And, the data offset.
By the way, I connected your app via IP to the S2-WL-ST data logger, and it works quite well.
This might be a stupid question, but do you use Modbus Poll to compare the raw data from the data logger with what you have on your end?
Hi.
Hardware:
Inverter: S6-EH3P10K-H
Battery: PYLON_HV 25.6kWh
I’m using your app in combination with the S2-WL-ST datalogger (Ethernet connection, no wifi).
And it works for the most part. I think the latest firmware (100141e1) is allowing multiple TCP Modbus connections. Solis Cloud is still active as well.
However, while reading works like a charm (set refresh even to 4s, no problem), writing is problematic for some commands.
For some reason, I can’t use the “Force Discharge Battery” card. Seems to do nothing. When I start a Force Discharge via Solis Cloud, I can stop it via your app by using the “Stop forced charge or discharge” card. So writing is not completely broken for my setup.
Any idea why, or how I can debug this to find the cause?
Thanks!
Regards,
Gunter
Hi Remco,
Thanks for reaching out ![]()
I’m not actually one of the developers in our company, I’m the CEO, but I work very closely with the development team.
I also run a Solis S6 myself at home with Dyness batteries, together with a few other inverter and battery brands, so I’m fairly close to the technical side as well.
What we’ve seen with our Modbus implementation is that it’s essentially independent of both datalogger firmware and inverter model. We also keep the Modbus connection permanently open, while still allowing external services such as Solis Cloud to access and use the data in parallel.
The only catch is that, since the Solis Modbus app is part of our commercial product, it requires an API key in order to operate.
Since you’re already developing apps for Homey, I think you’d probably find the product pretty interesting — especially if you’re also into solar, batteries and EVs. The whole idea is to bring all of these systems together, regardless of brand, and make different manufacturers work together seamlessly — very much like Homey itself does, but with a strong focus on intelligent energy management.
We’re also preparing to launch in the Netherlands, and you’re more than welcome to test it if you’re interested ![]()
And maybe be part of the Benelux release![]()
According to our developers, support for Dutch electricity prices should be ready during the weekend.
If you have more detailed questions I can forward them to the team.
Kind regards
Anders Gunnarsson
Powergravio AB
When I don’t use my phone’s Homey app, but via PC Chrome browser and I test the flow (Force Discharge Battery), I get a red popup “modbus exception 2”.
Edit: I’m using version 1.81
Hi Gunter,
Thanks for both reports — and the browser test is the piece that cracked it.
First, the datalogger detail is genuinely useful to me. If firmware 100141e1
allows multiple Modbus TCP connections, that’s good to know, and it matches what
another user mentioned earlier in this thread about the logger path working
without an RS485 gateway. A 4-second refresh is better than I’d have expected.
Now the actual problem. Modbus exception 2 means “illegal data address”: the
inverter is actively rejecting the write because one of the registers doesn’t
exist on your model. So this isn’t a timing or permissions issue, and it isn’t
SolisCloud getting in the way — it’s a register map difference between your
S6-EH3P10K-H and the S6-EH3P10K2-H I developed against. Close model names,
different map.
That error was almost certainly happening all along. The phone app doesn’t
surface flow-test failures the way the browser does, which is exactly why it
looked like the card silently did nothing.
Force discharge writes four registers in order, and stops at the first one the
inverter refuses:
43131 lift the discharge limit off its 1500 W default
43129 discharge power
43282 remote-control timeout
43135 arm
One of those isn’t mapped on your firmware. And this also explains why stopping
appeared to work: “Stop forced charge or discharge” fires three separate
releases (the dispatch block, the timed-charge window, and the arm register) and
doesn’t report an error if one of them fails. So the stop that cancelled your
SolisCloud discharge may well have come from one of the other two, not from the
register the discharge card needs. That silent failure is my bug and I’ll fix
it — a card shouldn’t report success when its write was refused.
There’s a neat way to narrow down which register is the culprit, because the
force-CHARGE path writes 43136, 43282 and 43135. It shares the timeout and the
arm, but not the two discharge registers:
- In the Solis Inverter device settings, open the “Price optimizer” group and
switch on “Grid-charge without PV curtailment”. That makes force charge use
the same remote-control block. - Run “Force charge battery” from the browser and watch for the same popup.
- If force charge ALSO throws exception 2, then 43282 or 43135 is unmapped and
your firmware uses a different remote-control block altogether. - If force charge WORKS, then it’s 43131 or 43129 — most likely 43131, since
that’s the first write.
Either answer tells me exactly what to change. Please switch that setting back
off afterwards if you don’t otherwise use it.
One thing that would help me: which firmware version is the INVERTER on (not the
logger)? I’d like to know whether this is model-specific or firmware-specific
before I change anything.
Good to hear you’re already on 0.1.81, so we’re looking at current code.
Thanks for digging into this properly — this is exactly the kind of report that
gets the app working on more than just my own unit.
Regards,
Remco
Quick follow-up — I’ve just pushed v0.1.82, which makes this much easier to
diagnose than the test I described.
Until now the app showed you the bare exception code. From 0.1.82 it names the
register that was refused and what the code means:
modbus exception 2: illegal data address — this register is not supported by
your inverter model or firmware (register 43131, function 6)
One thing to note: 0.1.82 is on the TEST track, not the public release. You’re on
0.1.81, which is the live version, so you won’t get it automatically. You can
install the test version here:
Solis Local Hybrid Inverter | Homey
Once you’re on it, run Force discharge from the browser again and paste me the
full message. That identifies the exact register your firmware doesn’t implement,
and you can skip the force-charge test I suggested. If you’ve already run that
test, the result is still useful — send it along.
I have a suspicion about which register it will be. 43131 is the first one the
card writes: I use it to lift the discharge power limit off its 1500 W default.
But other Solis owners report that on their units 43131 behaves differently —
it’s a limit register that has to stay at zero, or it overrides the force
entirely. If your firmware doesn’t implement it at all, the fix is simple: I skip
that write for models that reject it.
Also in 0.1.82, as promised: “Stop forced charge or discharge” no longer reports
success when part of it was refused by the inverter. It now tells you what
failed. That was the thing hiding the real behaviour from both of us.
Happy to move you back to the live version once we’ve sorted this out.
Regards,
Remco


