homeassistant-powercalc
homeassistant-powercalc copied to clipboard
Feature/smart speakers (for further discussion and planning)
Spun off from https://github.com/bramstroker/homeassistant-powercalc/discussions/964
Most of these smart speakers have a fairly fixed power consumption afaik, and are a perfect candidate to put in the library as a lot of people own them. I will do some testing on my google nest/home mini's. To see if the power consumption is constant and what happens when I play music of ask some questions.
Devices we have access to:
- [x] Lenovo Smart Clock with Google Assistant
- [ ] Google Home
- [ ] Google Home Mini (1st Gen)
- [ ] Google Nest Mini (2nd Gen) - Maybe?
Possible other devices:
- [ ] Google Home Max?
- [ ] Google Nest Audio?
- [ ] Google Nest Hub (This is half a speaker, half an ipad)
- [ ] Google Nest Hub Max (This is half a speaker, half an ipad)
- [ ] Amazon Echo Dot (1st Gen)
- [ ] Amazon Echo Dot (2nd Gen)
- [ ] Amazon Echo Dot (3rd Gen)
- [ ] Amazon Echo Dot (4th Gen)
Best way to model this domain?
- [ ] Should there be an explicit media_player + device_class: speaker domain? (https://www.home-assistant.io/integrations/media_player/#device-class ); as opposed to things like a chromecast or tv?
- [ ] If there's a media player + device_class speaker domain, is it useful to support a linear config for state: playing + volume_level, is_volume_muted: false?
What I've tried so far: I decided to try out a linear config with a calibration range for volume. Not sure if I'm better off choosing generic music, and listening for a long period; or a constant sound which would exercise the speakers in a specific, consistent fashion.
The alternative is choosing a fixed config + states_power; but that would mean putting in up to 100 measurements for the volume_level
attribute; plus needing to exact match strings?
https://github.com/bramstroker/homeassistant-powercalc/blob/75dce80040277c94c6eab1888da4ed6f7e789c03/custom_components/powercalc/strategy/fixed.py#L55
Alternative 3: Templates?
Something like:
playing: "{{4.41 * states('media_player.family_room_speaker', 'volume_level')}}"
(max watts - min watts) * volume % ?
Other notes: These attributes are available
device_class: speaker
friendly_name: Family room speaker
supported_features: 152509
volume_level: 0.30000001192092896
is_volume_muted: false
media_position_updated_at: '2022-08-28T02:30:39.930774+00:00'
app_id: 7F8E0EF3
app_name: iHeartRadio
media_content_id: >-
https://live.fresh927.com.au/freshaac?uid=1597280537064&host=google.appliance.au&clientType=google_home&devicename=google_home&playedFrom=73&terminalid=386&profileid=1408028966&territory=AU&amsparams=playerid%3AiHeartRadioGoogleHome%3Bskey%3A1661653835.318&listenerId=1661653835318_99806&dist=iheart&at=0&fb_broadcast=0&init_id=8169&modTime=1661653835318&pname=OrganicWeb&birthYear=&gender=&age=&zipcode=
media_content_type: music
media_position: 1.645719
media_title: Fresh 92.7 Adelaide
media_album_name: Fresh 92.7 Adelaide
media_album_artist: Electronic Music For Adelaide Youth
entity_picture_local: >-
/api/media_player_proxy/media_player.family_room_speaker?token=be9b1caada48a2cabf385358f63cefe854c92f4d466d7bc4af202ce4667c9e71&cache=3fcb86270a9da5bc
entity_picture: https://i.iheart.com/v3/re/new_assets/5d23ec89db1e1347a068f5ad
Pull Request Test Coverage Report for Build 3168639783
- 53 of 58 (91.38%) changed or added relevant lines in 6 files are covered.
- 5 unchanged lines in 2 files lost coverage.
- Overall coverage decreased (-0.1%) to 96.017%
Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
---|---|---|---|
custom_components/powercalc/sensors/power.py | 24 | 26 | 92.31% |
custom_components/powercalc/strategy/linear.py | 10 | 13 | 76.92% |
<!-- | Total: | 53 | 58 |
Files with Coverage Reduction | New Missed Lines | % |
---|---|---|
custom_components/powercalc/sensors/group.py | 1 | 99.48% |
custom_components/powercalc/sensors/power.py | 4 | 92.16% |
<!-- | Total: | 5 |
Totals | |
---|---|
Change from base Build 3123076186: | -0.1% |
Covered Lines: | 2459 |
Relevant Lines: | 2561 |
💛 - Coveralls
After some experimentation, I think I liked fixed_config + states + templates to do a simple linear range based on volume.
IE:
- platform: powercalc
entity_id: media_player.family_room_speaker
fixed:
power: 2.511
states_power:
idle: 2.511
playing: "{{((4.41 - 2.511) * state_attr('media_player.family_room_speaker', 'volume_level')) + 2.511}}"
This isn't as good as playing a known piece of music and sampling at every point on the scale; but for now; it seems the quickest way to work "out of the box".
Have provided 2x different possible ways to model in JSON schema for discussion
I like the approach with state power in combination with a template for the linear volume scale. Than we also need to extend the current possibilities with all kind of complicated extra configuration.
I don't think it will matter that much which type of music / sound is playing. Did you test that already? Does the power behave linear on volume, you already did some measurements on different volume levels?
I don't think it will matter that much which type of music / sound is playing. Did you test that already?
I did see differences with "radio presenter waffles on for a bit" vs "constant music"; so I feel like picking a standard piece for measurement is worth while; if we go down the path of building a measurement script similar to lightglobes. Probably not a shrill tone for 4.5 hours though at increasing volumes!
Does the power behave linear on volume, you already did some measurements on different volume levels?
It is difficult to say from the limited sampling and the music I was using. It was roughly increasing; but I did see "volume 100%; silence" using less power than say "volume 50%; rhythmic music" in some examples; which made me want to pick a constant tone as the proxy for what people are outputting through these media players.
I'm torn though, as "sample radio show" seems much more plausible for the kinds of output that would be typically seen, even if not as clean as measuring a constant tone.
Ah hah. A bit of research, no, it is not a simple linear increase, but yes, sound engineers have an approximation qnd measurement approach
https://www.musiciansfriend.com/thehub/understanding-wattage-speaker-efficiency-amplifier-loudness
@CloCkWeRX Which exact model do you have? I have a few of these mini devices. Different versions of them.
Currently doing some quick measurements on a Nest Mini (model H2C) In idle state the device fluctuates around ~1.4 watt Need to do measurements on different volume levels when playing. I would suggest to take measurement each 10 points. I.e (10, 20, 30 .... 100) Let's pick a song which we stream through spotify. Do you have any idea which?
Which exact model do you have?
I have:
- 1-2 google home mini (1st generation) devices... somewhere
- 1x google home
- 1x lenovo smart speaker w/google assistant (sample measurements done here)
Songs; well...
Radiohead – The National Anthem (https://www.youtube.com/watch?v=NfQD1QiQ9o4) might do the trick. Shamelessly lifted from https://www.whathifi.com/features/10-best-songs-to-test-your-speakers
Alright, time to start on this one I reckon!
Radiohead – The National Anthem (https://www.youtube.com/watch?v=NfQD1QiQ9o4) might do the trick. Shamelessly lifted from https://www.whathifi.com/features/10-best-songs-to-test-your-speakers
Seems fine by me.
I just started to measure my Nest mini.
Extended the measure.py tool to have an option to calculate average power for a given duration.
I have set it to 4 minutes. python3 measure.py average 240
This will run for the given amount of seconds and waits for the configured SLEEP_TIME
between each power measurements.
Next I have set the volume to steps of 10, starting with 10 using the mediaplayer control of HA.
After that I have streamed the song Radiohead - National Anthem using spotify (https://open.spotify.com/track/4Wgj6jzoI2gYlumXdYAB8U?si=a4a83b91d97b4d7a), and directly after hitting the play button started the measure tool.
I am at volume level 50 right now, but the dissonance in the radiohead song at the end is getting harder to handle for me on the higher sound levels ;-). Particularly because the speakers of the nest are also very bad quality. Anyway I will just continue, so expect to finish the proces in half an hour.
I also have the following multiroom / smart speakers which I can measure:
- Denon HEOS 1 HS2
- Harman Kardon Citation MultiBeam 700
- Google Home mini (maybe it's the same as Nest mini, but I have to check).
- Amazon Alexa (some old model, need to check for exact specs)
I have added the average measure function to this PR, so when you pull your branch again you should also be able to use that.
I have implemented calculation_enabled_strategy
in the model.json for Google Nest Mini, and also added a test to verify everything is working correctly.
Also checked measurements using another song (Shape of my heart by Sting) on 2 different volume levels and got exactly the same averages (~0.5%).
And did some extra verifications with my Zhurui PR10 meter which got similar readings as my Shelly Plug S.
So everything looks very good and consistent.
1.65 standby power is when the device is idle.
However when I mute the volume (when the song is still streaming) the consumption is approximately 2.0 watt. I suggest to set this reading as the 0 value for the calibration table (as volume 0 equals mute). Will test that later today. Have to go now.
Best way to model this domain?
- [ ] Should there be an explicit media_player + device_class: speaker domain? (https://www.home-assistant.io/integrations/media_player/#device-class ); as opposed to things like a chromecast or tv?
We can maybe constraint this later, but right now manufacturer/model is enought. When Google Nest Mini is detected for example we now it is a media_player and has device class speaker. So no need to do extra checks for that right now.
- [ ] If there's a media player + device_class speaker domain, is it useful to support a linear config for state: playing + volume_level, is_volume_muted: false?
See my contribution for google nest mini in this PR, which is working as expected now.
You'll need to add 0 calibration value for the power when muted.
And also add calculation_enabled_condition
to check for state playing. When it is playing the linear strategy will be used, in all other cases it will use standby power.
Music used does not seem to matter that much.
Only thing I still want to test other streaming provider than spotify to see if the power is similar.
Sonos speakers are also widely used, so would also be awesome to add those. My parents have one, and we have a few at work. I will see what I can do.
Have been working on measuring the Citation Multibeam as well, but it's a difficult one to get right, because it goes to some kind of network sleep time after exactly 18 minutes (which is also according to manufacturer specs). I have been measuring and I see it goes from 7.5 watt in idle state to 2 watt after 18 minutes. This is not something we can handle yet with the current configuration/architecture and it is not an easy one, as we need to add timer logic to the power calculation and additional configuration possibilities. Will give it some thought but will leave it out this PR (first iteration).
Google Home Mini added.
Also added section to the Wiki with measure instructions https://github.com/bramstroker/homeassistant-powercalc/wiki/Contributing-new-lights.
@CloCkWeRX I worked this weekend on this PR. See my comments above. Everything is finished from my side. Only thing left is to check/remeasure the Google Home device (as this only has a min and max currently, and no calibrate table). Are you able to do this, then we can incoorporate the feature for next upcoming V1.0 version.
Kudos, SonarCloud Quality Gate passed!
0 Bugs
0 Vulnerabilities
0 Security Hotspots
0 Code Smells
No Coverage information
0.0% Duplication
Merging this as I want to get it in v1.0.0 beta asap, so it can be tested by others. Google Home profile can be improved upon in the future.
Anyone working on Google Home Nest Hub support?