Closed RubenKelevra closed 2 years ago
Currently the database only consists of lights.
Initially when I designed the library loading code I also added support in model.json to provide fixed
or linear
configuration, so it should also be possible to add other devices to the database which don't have LUT files.
When we are going to allow addition of non lights to the DB I think we need to introduce a device type property to model.json
. Then we can also make different sections in supported_models list to keep this organized.
Which vacuum cleaner do you have? And how does the power behave? Is it a constant power when the device is actively vacuum cleaning? And another fixed value when idle?
Hey @bramstroker,
well, not sure that there's really a need to distinguish different device types. I'm at least fine with just vendor/device name. :)
Which vacuum cleaner do you have?
The device is a Roborock S6 MaxV (Roborock is just a label for Xiaomi) — a pretty popular device.
And how does the power behave? Is it a constant power when the device is actively vacuum cleaning? And another fixed value when idle?
Well the base has an idle power consumption all the time (when the device is running) and a different idle consumption when the device is docked.
If the battery status is not 100% the device is charging, when it is reporting docked
. I could provide a power consumption curve based on the state-of-charge as it is not static. :)
If the battery status is not 100% the device is charging, when it is reporting
docked
. I could provide a power consumption curve based on the state-of-charge as it is not static. :)
What do you mean by "power consumption curve based on the state-of-charge"?
First we need to figure out how to define powercalc configuration for the vacuum cleaner using the existing configuration options (linear, states_power, templates) etc. When this is figured out we can think about adding it to the library of devices somehow.
What do you mean by "power consumption curve based on the state-of-charge"?
When battery is empty enough it's charging at max current provided by power supply. Above ~80% power supply moves from "constant current" to "constant voltage" and power draw decreases expotentially. https://i.stack.imgur.com/ZNYHl.png
Is the state of charge (% battery) known to HA somehow when the device is in docked
state.
I think a new strategy (besides linear
, lut
, fixed
and wled
) needs to be developed to facilitate this use case. Because we somehow need to define constant power for a few states (idle
and cleaning
), but a variable power for another state docked
.
Or maybe a "composite" strategy which uses both fixed
and linear
(with the calibrate option) into a new strategy.
Anyway it gets rather complex.
Anyway it gets rather complex.
I’ve been giving this thought myself, and want to share those thoughts somewhere. I think an ideal implementation would be for a broad ‘charger’ class of devices. But complex is exactly right. Even more so, when there isn’t a consistent method to report the needed data across different integrations. Here’s a couple examples based on devices I own:
vacuum.[name]
, state Docked
Linear calculation (calibrated), from entity attribute battery_level
Would need to check for battery full, trickle charging use, too.sensor.[name]_battery_charge
, state below 100
Fixed calculation (according to spec, anyway)For mobile devices: considering that different chargers have different efficiency characteristics & power delivery standards, or that you might charge these devices away from home — this use case isn’t worth implementing.
Implementing calibrated measurement also implies adding an additional mode to measure.py
, to passively monitor power use during a full charge, (fully discharging the device first).
It’s a neat idea, but to implement it correctly would definitely take some work.
Is the state of charge (% battery) known to HA somehow when the device is in
docked
state.
Yes of course:
The main state is docked
and there's a battery_level
attribute which is the SoC in percent.
So it's basically just a "lookup-table" for SoC and the average consumption for the SoC necessary.
This is how the consumption while charging looks like:
So it's basically just a "lookup-table" for SoC and the average consumption for the SoC necessary.
This is how the consumption while charging looks like:
So, basically user need to discharge vacuum and run a script to watch a battery level sensor and ask for power consumption and each battery percentage. This builds a lookup table and rest seems more straightforward.
Yep. But I guess it would be more accurate if we use the energy value on each SoC change instead. So it would automatically smooth out the power consumption for each SoC.
@bramstroker ah and something specific to vacuum cleaners: They won't get empty all the way, usually. Mine stops cleaning at 20% to make sure it gets back to the dock on its own, regardless how big the home is.
So I CAN discharge it more, by manually placing it somewhere and let it try to find the dock multiple times etc. but I don't think that's really necessary for a sensible energy profile. I think it's safe to assume that any battery charging rate in W below the minimum operation percentage is the same as the last in the profile.
So I would just need a way to specify the HASS string for the SoC and the Shelly plug to make this work :)
@RubenKelevra I am not really sure how to read your chart. Could you elaborate more about at which state the vacuum cleaner was at particular points in the graph? As I see all the lines are pretty much linear, so looks there is no need to implement any advanced system using LUT tables. Which will be a huge development effort anyways. As I need to adapt the measure script to work with other attributes than bri/hue/sat, need to rework the lut strategy, update readme's. Support this long term etc. etc.
Agreed it looks more stable than I thought. I think that was like a 40% to 100% charging. The 2 W on/off is trickle charging plus standby current to keep the device running.
@bramstroker I'll take later a peek at the script. Maybe I just implement it myself - if you're fine with that.
Reason beeing that my device might be the exception in terms of linearity :)
If I understand correctly the first stable 20 watt is ~40-80% charged, than the descending linear pattern from 15-8 watt is ~80-100% charged, and the last part trickle charge on 100%?
@bramstroker I'll take later a peek at the script. Maybe I just implement it myself - if you're fine with that.
Sure, PR's are welcome as well. measure script can first ask what kind of device you are measuring. i.e. light
or vacuum
. Than when in vacuum mode the script needs to listen for state changes of the battery_level
somehow and write a row to CSV with the battery_level
and power
from the power meter, until 100% battery level is reached.
Reason beeing that my device might be the exception in terms of linearity :)
My philosofy is alway to keep things simple first KISS and actually implement something more complex when it is actually needed.
Regarding the implementation in the integration it can maybe look something like this.
With this approach we can just reuse the different available strategies, and only for the LUT strategy code needs to be altered to also read the battery_level, power
format.
strategy_enabled_condition
has to be added as well. When this is false powercalc needs to just return standby_power or 0. When it is true it uses the configured strategy (linear
, fixed
, lut
) to calculate the power.
- platform: powercalc
entity_id: vacuum.my_robot_cleaner
strategy_enabled_condition: '{{ is_state('vacuum.my_robot_cleaner', 'docked') }}'
linear:
attribute: battery_level
calibrate:
- 1 -> 20
- 79 -> 20
- 80 -> 15
- 99 -> 8
- 100 -> 1.5
Or when using LUT mode:
- platform: powercalc
entity_id: vacuum.my_robot_cleaner
strategy_enabled_condition: '{{ is_state('vacuum.my_robot_cleaner', 'docked') }}'
lut: #this can be omitted as it is the default
What do you think?
Okay, I give a PR a shot. :)
My philosofy is alway to keep things simple first KISS and actually implement something more complex when it is actually needed.
Agreed. But I don't want to make it simple for me, but for the users. They shouldn't need to do any configurations, but instead have the device autodetected. :)
That's why I wanted to make a LUT for that.
The model.json files also provide possibilities for providing linear
or fixed
config, so it's not limited to LUT files per se for the model library and auto detection logic.
I agree, LUT with SoC-vs-wattage is most intuitive for use and flexible for future expansion.
Great idea. I would love to measure state's of my sonos speaker, maybe different volumes, played vs paused, standby, and find some close map between that and watts
When it is true it uses the configured strategy (linear
, fixed
, lut
) to calculate the power.
- platform: powercalc entity_id: vacuum.my_robot_cleaner strategy_enabled_condition: '{{ is_state('vacuum.my_robot_cleaner', 'docked') }}' linear: attribute: battery_level calibrate: - 1 -> 20 - 79 -> 20 - 80 -> 15 - 99 -> 8 - 100 -> 1.5
What do you think?
I have a Roborock S7 (which is nearly the same vacuum as the OP) and it behaves in exactly the same way, modulo slightly different levels of fully charged power use. It would be great to be able to use this in exactly the way you suggest here, but it doesn't seem to be working in the released branch.
@wigster The strategy_enabled_condition
option was only a proposal, never went ahead and implement this yet. Also the attribute
option for linear mode is non existent yet.
I will implement this soon. This week or next week.
Good news, I just worked some time on this and the code has been merged into master. #789
Any of you guys able to test this:
- platform: powercalc
entity_id: vacuum.my_robot_cleaner
calculation_enabled_condition: "{{ is_state('vacuum.my_robot_cleaner', 'docked') }}"
linear:
attribute: battery_level
calibrate:
- 1 -> 20
- 79 -> 20
- 80 -> 15
- 99 -> 8
- 100 -> 1.5
This should work now. I am unable to test this fully as I don't have a robot cleaner myself. But did some testing using other attributes and entities.
@bramstroker can we share those "profiles" (or maybe better calibrations?) in the database? It would be neat to have them just as part of the auto detection, like bulbs and switches - if that's possible?
Sure, the model.json in library also supports fixed and linear mode.
So we should be able to do something like this:
{
"name": "Roborock S6 MaxV",
"supported_modes": [
"linear"
],
"measure_method": "manual",
"measure_device": ".....",
"measure_description": ".....",
"linear_config": {
"attribute": "battery_level"
"calibrate": {
"1": 20
"79": 20
"80": 15
"99": 8
"100": 1.5
}
}
}
calculation_enabled_condition
is not supported yet in model.json, I will need to add that.
Has been implemented with #792 I don't have a vacuum cleaner myself, but I was able to test with a light using the following configuration.
{
"measure_description": "Test",
"measure_device": "Test",
"measure_method": "script",
"name": "Test",
"supported_modes": [
"linear"
],
"calculation_enabled_condition": "{{ is_state('[[entity]]', 'on') }}",
"linear_config": {
"attribute": "brightness",
"calibrate": [
"1 -> 40",
"79 -> 40",
"80 -> 15",
"99 -> 8",
"100 -> 1.5"
]
}
}
Hi,
I think this works exactly as it should for my vacuum. However, once small tweak request: I would like to be able to have stand_by_power
continue to be added when the calculation conditions is false. Right now it really seems to switch the energy use to zero. Basically this would allow the user to use the calculation condition as fake on/off switch.
@wigster Just to verify, I will change it as follows:
assuming standby_power
0.25 and power
40
device_state | calc_enabled | power |
---|---|---|
OFF | OFF | 0.25 |
OFF | ON | 0.25 |
ON | OFF | 0 |
ON | ON | 40 |
Hmm, not sure that's quite when I meant. For the case of the vacuum, I think, we have the following situation.
If calc_enabled is on = 40 W (to be precise, that linear scale). If calc_enabled is off (vacuum undocked), then it should be 0.25, because there is some residual power being taken by the docking station. The state of the vacuum device itself should not impact this at all, since if it turns itself off away from the dock, the dock doesn't know.
Should be resolved with #819
Now it will be:
device_state | calc_enabled | power |
---|---|---|
OFF | OFF | 0.25 |
OFF | ON | 0.25 |
ON | OFF | 0.25 |
ON | ON | 40 |
Can be tested by installing the master branch.
@wigster @RubenKelevra Are any of you able to test the suggested configuration? If it is working correctly it can be submitted as a profile to the library. So other users can also use it without any manual configuration.
@bramstroker sure, I was under the impression that there's something left to implement and thus the solution is only academical. :)
@RubenKelevra Are you still able to add this configuration in a model.json to the library and test if this is working correct for your vacuum? Then we can close this issue.
I'm guessing mapping my vacuum is not a trivial task :D
I'm guessing mapping my vacuum is not a trivial task :D
Lol, how is it still using power for half an hour when fully charged :-P. Yeah this is highly complicated to build something for.
I was also thinking about having a look into smartphone charging using similar approach as implemented in this issue. The companion app passes charging state to HA afaik, so we should also maybe be able to use this somehow. Will do some testing on this.
I was also thinking about having a look into smartphone charging using similar approach as implemented in this issue. The companion app passes charging state to HA afaik, so we should also maybe be able to use this somehow. Will do some testing on this.
Phones have very flat charging curve, unless you are using some fast charging technique. In this case, my initial idea was to read notification bar, where AccuBattery displays charging stats.
@bramstroker @KrzysztofHajdamowicz Charging a lithium-based battery always consists of 2 phases:
Sometimes CC phase ends at higher upper percent (and of course higher voltage) - service life of accu depends on that - higher % of change to CV -> lower accu service life.
High speed charging modifies only CC phase (in reality current is just not constant - it is based on temperature of battery).
It looks like BMS of this vacuum cleaner reports 100% battery when in reality it is just after end of CC phase.
Change CC -> CV is about at 85% real capacity of accu. Looking at the chart above I've drawn some lines (from this sketch is is about 26/30 but my "Riemann intergration by hand" isn't accurate :P ).
This issue got a little bit out of control ;-). Maybe we can start a discussion how to integrate phone charging support in a seperate discussion part.
Only thing left for this issue to be closed is getting some vacuum actually in the library. @RubenKelevra Are you able to do that with you vacuum and the proposed configuration? And test if it's working correctly. Let me know if you still need anything from my part.
Than we can close this issue.
Closing because of inactivity.
Sorry, totally forgot about this one. Maybe we could implement this into the measurement script?
So we can run the robot as empty as it gets, plug the dock into the power measuring device and specify how the vacuum is called in HA and how it's battery percentage attribute is called (if that's difficult to auto-detect), start the script and put the robot on the dock.
Then it will measure the average consumption per charging percentage. So say it is starting at 0% the measurement script will fetch the power consumption every second until 1% is hit and average it out and store it as 0%.
The 100% thingy, but still charging is more challenging, but maybe we could measure for an hour until longer, and use this as "first hour on the dock" average and then switch to the standby measurement done after that?
This would capture this and all other weird things, like robots maybe taking shorter or longer to go into deep sleep etc.
switch to the standby measurement done after that
What do you mean with this?
Btw I have started with some basic architecture to incoorporate charging devices in the measure tool. See #2603
switch to the standby measurement done after that
What do you mean with this?
Ah, sorry for not being clearer.
The idea is to start an average for the first hour of being at 100 % and then maybe another average for 15 minutes or so to get the real standby consumption. As most vacuum cleaners will be taking their sweet time to go into deep sleep or continue charging very slowly the last couple of percent, but showing 100 % in the stats. But after an hour they should be deep sleeping and we can measure their 24/7 standby, if they have nothing to do.
If we want to be pedantic, we could also measure averages of say 5 minutes slots after it hits 100% until 3 are roughly the same. This would allow us to be more accurate if the vacuum cleaner is idle for a short while at 100% and then starts cleaning again, or something like that.
I guess most people let them run daily and so the more simple solution would be enough, however I tend to automate each room with different automations, so sometimes it runs 5-6 times a day, sometimes it runs just once, that depends highly on what the motion sensors and door sensors "see" over the course of the day.
@bramstroker please reopen this ticket, to track the progress.
Do you need help for the implementation? :)
@RubenKelevra you can just track the mentioned PR: #2603. Might probably need some help on this. Especially the testing part and ironing out bugs. Maybe I continue a bit on the PR today.
Hey guys,
I was wondering if and how I can provide power consumption numbers for my robot vacuum to add it to the powercalc database for auto-detection?