Interesting. I’ll try do some testing here. As I understand it, the ‘upgrade’ functionality should only be attempted if an existing ‘thing’, created with an older version of the binding exists.
https://smedley.id.au/tmp/org.openhab.binding.teslapowerwall-4.2.0-SNAPSHOT.jar will probably help with this. Seems in my messing around, I removed an important update to thing-types.xml - see Add missing thingTypeVersion · psmedley/openhab-addons@177886f · GitHub
Just tried, unfortunately same error :
2024-04-29 14:53:43.758 [ERROR] [internal.JSONResponseExceptionMapper] - Unexpected exception occurred while processing REST request.
java.lang.IllegalArgumentException: Duplicate channels teslapowerwall:teslapowerwall:f3d4992cae:degradation
at org.openhab.core.thing.util.ThingHelper.ensureUniqueChannels(ThingHelper.java:135) ~[?:?]
at org.openhab.core.thing.util.ThingHelper.ensureUniqueChannels(ThingHelper.java:127) ~[?:?]
at org.openhab.core.thing.util.ThingHelper.ensureUniqueChannels(ThingHelper.java:123) ~[?:?]
at org.openhab.core.thing.binding.builder.ThingBuilder.withChannel(ThingBuilder.java:123) ~[?:?]
at org.openhab.core.thing.internal.update.UpdateChannelInstructionImpl.doChannel(UpdateChannelInstructionImpl.java:140) ~[?:?]
at org.openhab.core.thing.internal.update.UpdateChannelInstructionImpl.perform(UpdateChannelInstructionImpl.java:99) ~[?:?]
at org.openhab.core.thing.internal.ThingManagerImpl.lambda$17(ThingManagerImpl.java:1095) ~[?:?]
at java.lang.Iterable.forEach(Iterable.java:75) ~[?:?]
at org.openhab.core.thing.internal.ThingManagerImpl.checkAndPerformUpdate(ThingManagerImpl.java:1095) ~[?:?]
at org.openhab.core.thing.internal.ThingManagerImpl.registerAndInitializeHandler(ThingManagerImpl.java:918) ~[?:?]
at org.openhab.core.thing.internal.ThingManagerImpl.setEnabled(ThingManagerImpl.java:1009) ~[?:?]
at org.openhab.core.io.rest.core.internal.thing.ThingResource.setEnabled(ThingResource.java:609) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:?]
at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[?:?]
at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.lang.reflect.Method.invoke(Method.java:568) ~[?:?]
at org.apache.cxf.service.invoker.AbstractInvoker.performInvocation(AbstractInvoker.java:179) ~[bundleFile:3.6.2]
at org.apache.cxf.service.invoker.AbstractInvoker.invoke(AbstractInvoker.java:96) ~[bundleFile:3.6.2]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:201) ~[bundleFile:3.6.2]
at org.apache.cxf.jaxrs.JAXRSInvoker.invoke(JAXRSInvoker.java:104) ~[bundleFile:3.6.2]
Ooops, checking the wrong thing, old one still installed.
All working now with new jar… `THANK YOU so much, I’ve been waiting for local plugin for a while, great to see it is here and working , your efforts much appreciated.
I think I found two issues with reported values:
Battery Reserve is reported as 0 when it is in fact 5 (also, note no unit, perhaps add % as the unit)
Battery degradation is reported as “0.1 one” (I suspect value correct, and “one” is the unit dimension. Not sure if battery degradation is a percentage or other value ?)
re: battery reserve - are you comparing values in the Tesla app with the binding? If so, these always differ for some reason. For example - app 10% binding 14.5%.
degradation should be a percent - and yes ‘one’ is the unit dimension. I added a state description of:
%.1f % to fix this. Not sure if I can force the units through the code…
Edit: OK I think I see what’s required. As this tweaks thing-types.xml you’ll have to recreate your thing.
https://smedley.id.au/tmp/org.openhab.binding.teslapowerwall-4.2.0-SNAPSHOT.jar is updated
I’ll try the new one now..
The reserve thing got my curiosity and I found this nugget in the pypowerwall code :
def get_reserve(self, scale=True, force=False) -> Optional[float]:
"""
Get Battery Reserve Percentage
Tesla App reserves 5% of battery => ( (batterylevel / 0.95) - (5 / 0.95) )
Args:
scale = If True (default) use Tesla's 5% reserve calculation
"""
data = self.poll('/api/operation', force=force)
if data is not None and 'backup_reserve_percent' in data:
percent = float(data['backup_reserve_percent'])
if scale:
# Get percentage based on Tesla App scale
percent = float((percent / 0.95) - (5 / 0.95))
return percent
return None
I tried the formula given in ‘if scale’ stanza above and it appears to work.
Will report back on the latest jar..
On the degradation, I now get -7.5% which means the display/unit is fixed, thank you.
This got me digging into the calculation for this, and from your code
updateState(TeslaPowerwallBindingConstants.CHANNEL_TESLAPOWERWALL_DEGRADATION,
new QuantityType<>((13500 - systemStatus.full_pack_energy) / 13500 * 100, Units.PERCENT));
My PW2 (2 years old) reports “nominal_full_pack_energy”:14518, resulting in a negative degradation of -7.5%.
YMMV as they say.
Oh, I wonder how this would work with multiple battery packs on same gateway..I’ve another battery on order, so I’m sure I’ll find out …
I’m happy to work with you on how to report battery 2. Looking at the output, I suspect it will produce an array with the additional batteries data. It will just need some code modifications - and probably an additional channel for Battery 2, Battery 3, etc.
I can look at scaling the battery capacity - going to the trouble of allowing configuration of scaling or not seems a pain though. Having two channels for battery - raw and scaled would be easier?
I suspect you are right about the multiple battery output.
I was looking at pypowerwall page again
pw.battery_blocks(jsonformat=True)
The output json there shows multiple batteries (quite a few items for each) .. of course not sure what the actual PW api would produce. Given the number of items per battery, it could get complicated quickly. (Does openhab support dynamic channels ? Not sure how variable number of batteries could be detected and implemented but I’m not an openhab dev
)
I’ll let you know when I get another battery, likely be a few months due to waiting on installer / DNO permission etc.
Scaling:
Yes, I wouldn’t go to the bother of a config item for the scaling, two channels would work at the expense of having to explain to users the difference… me being a lazy guy would modify the existing channel to be scaled and call it done (I suspect most users would expect it to be the same as the app) but that is your decision… ![]()
Multiple batteries:
Looking again at the data published for each battery there are very few items of interest, so maybe not as bad as first thought.
It may be an idea just to aggregate all the individual battery data into one singular battery dataset ( that is add together all the pertinent values for each battery and publish only one channel representing all batteries. e.g. nominal_energy_remaining = batt1_ nominal_energy_remaining + batt2_nominal_energy_remaining + battn_ nominal_energy_remaining ). That appears to be how the tesla app represents it (had a glimpse at neighbours app who has 3 batteries).
And maybe one channel “NumberOfBatteries” or some such…
I took the lazy option - and added the code to ‘scale’ the battery value. Untested and uncomitted but it should work. I’ll test it locally tonight. https://smedley.id.au/tmp/org.openhab.binding.teslapowerwall-4.2.0-SNAPSHOT.jar is updated.
Will try later on today.
Just noticed that SOE doesn’t match the app either.
I think we need to add the same scale to SOE as applying the scale formula manually to the value makes it match…
I just tested this binding.
Battery degradation -0,47 %
Battery Full Pack Energy 13,563 kWh
Seems the degradation has to be interpreted with care.
I took a look at the channels
*-Energy_Imported and *_Energy_Exported
They are all of type number:energy, but if I create and link an Item by the UI the items are generated with type number:power. One can change that manually - no problem. But shouldn’t they automatically be generated as power:energy?
Perhaps if degradation is negative I should just report 0?
The import/export channels were fixed in Add support for degradation and battery capacity · psmedley/openhab-addons@5293456 · GitHub but any existing ‘thing’ won’t get updated.
OK, so I have to delete the old thing and create a new one and afterwards the newly created Items should get the corresponding types.
Solar_Energy_imported shows only 48 kWh. I do not really know what that energy is.
Fixed batterySOE and reserve using the formula you provided…
I think the problem with degradation could be the pack theoretical capacity is not 13500 w/h but 14210 w/h. 13500 w/h being 95% of the pack capacity… Tesla hide 5% from us ? This would need more samples from the field to see what’s really going on.
Confirmed working here… thank you
I’m not sure how to interpret the import/export kWh figures… I expected ‘solar_energy_imported’ to match my inverters ‘ETODAY’ figure (daily generation) but it doesn’t… right now the plugin is showing, 50 kWh and ETODAY is 35.5 kWh (which matches the tesla app solar ‘total generated’ figure precisely)
[EDIT] If I go into the tesla app and and click Energy, look at the home/solar/grid/battery figures, and choose ‘lifetime’ as the duration, the figures given for each element match the figures in the app thus :
Home Energy Imported = App Home Total Used
Solar Energy Exported = App Solar Total Generated
Grid Energy Imported = App Grid Imported (not exactly though, 16.2MWh in app, 16.9MWh from plugin)
Home Energy Exported = 0 kWh
Solar Energy Imported = No idea
Battery Energy Imported / Exported = No idea
Grid Energy Exported = No idea