Giter Site home page Giter Site logo

edwork / homeassistant-peloton-sensor Goto Github PK

View Code? Open in Web Editor NEW
76.0 10.0 15.0 367 KB

A platform which allows you to get current and past ride data from Peloton into HomeAssistant

License: Apache License 2.0

Python 99.01% Shell 0.99%
homeassistant homeassistant-integration peloton peloton-api peloton-client hacktoberfest

homeassistant-peloton-sensor's Introduction

Home Assistant Peloton Sensor

hacs_badge CodeQL Validation Dependency Validation HASSFest Validation

Development & Community

This integration is developed and maintained by myself (edwork@) and a small group of contributors. We are not affiliated with Peloton. If you would like to show your support you're welcome to buy me a coffee!

"Buy Me A Coffee"

Please join our community discussion here on the HomeAssistant Forms.

Overview

HomeAssistant-Peloton-Sensor is an integration for HomeAssistant that exposes your latest or current Peloton Workout session as a sensor. This can be useful to toggle lights, fans, or scenes according to your workout.

This integration creates one of the below sensors for each user. The "Workout" binary sensor registers itself as a device with all other sensors created as entities.

Sensor Name Sensor Type Unit of Measurement Attributes Notes
Workout Binary Sensor (Running) - Workout Type, Device Type, Ride Title, Ride Description, Workout Image, FTP, Instructor, Paused On/running when user is working out.
Cadence: Average Sensor rpm
Cadence: Max Sensor rpm
Calories Sensor kcal
Distance Sensor mi / k Uses unit of measurement specified in user's Peloton profile.
Duration Sensor min
End Time Sensor -
Start Time Sensor -
Heart Rate: Average Sensor bpm
Heart Rate: Max Sensor bpm
Leaderboard: Rank Sensor -
Leaderboard: Total Users Sensor -
Power Output Sensor Wh
Resistance: Average Sensor %
Resistance: Max Sensor %
Speed: Average Sensor mph / kph Uses unit of measurement specified in user's Peloton profile.
Speed: Max Sensor mph / kph Uses unit of measurement specified in user's Peloton profile.
Workout count Sensor These sensors are disabled by default.
Available types:
- Bike Bootcamp
- Cardio
- Cycling
- Meditation
- Row Bootcamp
- Rowing
- Running
- Strength
- Stretching
- Tread Bootcamp
- Walking
- Yoga

Under the Hood

This integration uses Pylotoncycle to poll Peloton's API. Keep in mind that polling won't be instant when creating Automations.

Integration Installation

Using HACS (Recommended)

  1. Search for and install "Peloton" in HACS.
  2. Restart Home Assistant.
  3. Set up the integration from your Home Assistant Integrations page.

Manually Copy Files

  1. Download this repository and place the custom_components/peloton/ directory within home_assistant_root/config/custom_components/.
  2. Restart Home Assistant.
  3. Set up the integration from your Home Assistant Integrations page.

Use Cases

  • Automate lights and fans when you start or end a workout, or when your output exceeds a certain threshold.
  • Motovation - make HomeAssistant remind you to workout!
  • Export your ride stats to InfluxDB.

To Do

  • Expose more useful information by examining the entire JSON Object or other endpoints (PRs Welcome!)

Final Thoughts

Please feel free to critique the code as well as submit feature requests or additions! The goal is to turn this into an award winning HomeAssistant Integration!

homeassistant-peloton-sensor's People

Contributors

carpii avatar dependabot[bot] avatar edwork avatar elahd avatar justmedude avatar miablo avatar robertd502 avatar scribblrsam avatar superm1 avatar tony1661 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

homeassistant-peloton-sensor's Issues

became unavailable

Just tried the latest version on the bike and tread, the UI integrations works, but when I start a class, it does not work :-(

Home Assistant Core 2022.6.5
Home Assistant Supervisor 2022.05.3
Home Assistant OS 8.1

image

This error originated from a custom integration.

Logger: custom_components.peloton
Source: custom_components/peloton/init.py:249
Integration: Peloton (documentation, issues)
First occurred: 9:09:52 am (3 occurrences)
Last logged: 9:10:16 am

Unexpected error fetching peloton data: an integer is required (got type NoneType)
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 191, in _async_refresh
self.data = await self._async_update_data()
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 150, in _async_update_data
return await self.update_method()
File "/config/custom_components/peloton/init.py", line 75, in async_update_data
"quant_data": compile_quant_data(
File "/config/custom_components/peloton/init.py", line 249, in compile_quant_data
datetime.fromtimestamp(workout_stats_summary["end_time"], user_timezone)
TypeError: an integer is required (got type NoneType)

No power output?

Hey there!

I was truly excited to test this out with home assistant, imagining all the silly stuff I can get up to with lights, sonos, etc. : )

After installing the integration, logging in and hitting "Just Ride", I see all the sensors light up (with a few seconds delay)... all sensors except Power Output:

image

Is there any additional configuration required to get this metric displayed?
Thanks!

fail in version 2023.3

Hi Ed, FYI

Detected integration that called async_setup_platforms instead of awaiting async_forward_entry_setups; this will fail in version 2023.3. Please report issue to the custom integration author for peloton using this method at custom_components/peloton/init.py, line 98: hass.config_entries.async_setup_platforms(entry, PLATFORMS)

Error getting sensor to work

I can't get the sensor to work. Here is what I am getting in the log. What could I do to solve this?

Logger: homeassistant.components.sensor
Source: custom_components/peloton/sensor.py:81
Integration: Sensor (documentation, issues)
First occurred: 7:13:20 AM (1 occurrences)
Last logged: 7:13:20 AM

peloton: Error on device update!
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 432, in _async_add_entity
    await entity.async_device_update(warning=False)
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 601, in async_device_update
    await task
  File "/usr/local/lib/python3.9/concurrent/futures/thread.py", line 52, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/peloton/sensor.py", line 81, in update
    workouts = conn.GetRecentWorkouts(1)
  File "/usr/local/lib/python3.9/site-packages/pylotoncycle/pylotoncycle.py", line 111, in GetRecentWorkouts
    resp_summary = self.GetWorkoutSummaryById(workout_id)
  File "/usr/local/lib/python3.9/site-packages/pylotoncycle/pylotoncycle.py", line 132, in GetWorkoutSummaryById
    resp = self.GetUrl(url)
  File "/usr/local/lib/python3.9/site-packages/pylotoncycle/pylotoncycle.py", line 62, in GetUrl
    resp = self.s.get(url, timeout=10).json()
  File "/usr/local/lib/python3.9/site-packages/requests/models.py", line 900, in json
    return complexjson.loads(self.text, **kwargs)
  File "/usr/local/lib/python3.9/site-packages/simplejson/__init__.py", line 525, in loads
    return _default_decoder.decode(s)
  File "/usr/local/lib/python3.9/site-packages/simplejson/decoder.py", line 370, in decode
    obj, end = self.raw_decode(s)
  File "/usr/local/lib/python3.9/site-packages/simplejson/decoder.py", line 400, in raw_decode
    return self.scan_once(s, idx=_w(s, idx).end())
simplejson.errors.JSONDecodeError: Expecting value: line 2 column 5 (char 5)

Can't change password

I recently changed my peloton password and the integration in home assistant now fails. It says "Failed to set up: Login Failed". There's no menu option to re-configure my credentials.

Template not working properly

Not sure if I'm doing something wrong but I've tried copy/pasting the yaml custom lovelace template in and it doesn't appear to work correctly. I've obviously tried changing the peloton username to my own but still nothing.

The one thing I've noticed is that I'm not sure if maybe something changed in the way the sensors/attributes are grouped together in the entities. Each "Sensor" appears to be its own entity and maybe before this wasn't the case?

I've tried each of the following setups without any success:
state_attr('sensor.Sir_Farts_A_Lot', "Speed Max Mph") | float | round(2) }} max
state_attr('sensor.kyle_on_peloton_speed_max', "Speed Max Mph") | float | round(2) }} max
state_attr('sensor.kyle_on_peloton', "Speed Max Mph") | float | round(2) }} max

My username is "Sir_Farts_A_Lot" but my sensors all show up as "kyle_on_peloton". Is my setup just wrong or is something else going on here?

Screenshot_11172022

Here's my yaml that isn't working:

type: markdown
content: >+
{% if state_attr('sensor.kyle_on_peloton', "Resistance %") | float > 0 -%}

Current Metrics:

Heart Rate (bpm): {{ state_attr('sensor.kyle_on_peloton', "Heart Rate Bpm") }}
Resistance (%): {{ state_attr('sensor.kyle_on_peloton', "Resistance %") }}
Speed (Mph): {{ state_attr('sensor.kyle_on_peloton', "Speed Mph") }}
Speed (Kph): {{ state_attr('sensor.kyle_on_peloton', "Speed Kph") }}
Cadence Rpm: {{ state_attr('sensor.kyle_on_peloton', "Cadence Rpm") }}
Power (W): {{ state_attr('sensor.kyle_on_peloton', "Power W") }}


{%- endif %}

Latest Workout Summary:

- Date: {{ state_attr('sensor.kyle_on_peloton', "Start Time")|float|timestamp_custom('%Y/%m/%d » %H:%M') }} - {{ state_attr('sensor.kyle_on_peloton', "End Time")|float|timestamp_custom('%H:%M') }} ({{ state_attr('sensor.kyle_on_peloton', "Duration Min") }} mins)

{% if (state_attr('sensor.kyle_on_peloton', 'Workout Image')|string != 'None') %}
<img src="{{ state_attr('sensor.kyle_on_peloton', "Workout Image") }}">
{% endif %}

{{ state_attr('sensor.kyle_on_peloton', "Ride Title") }} ({{ state_attr('sensor.kyle_on_peloton', "Workout Type") }})

  • {{ state_attr('sensor.kyle_on_peloton', "Description") }}
  • Instructor: {{ state_attr('sensor.kyle_on_peloton', "Instructor") }}

Latest Workout Metrics:

- Distance (Mi): {{ state_attr('sensor.kyle_on_peloton', "Distance Mi") | float | round(2) }}
- Heart Rate (bpm): {{ state_attr('sensor.kyle_on_peloton', "Heart Rate Average Bpm") | float | round(0) }} avg / {{ state_attr('sensor.kyle_on_peloton', "Heart Rate Max Bpm") | float | round(0) }} max
- Resistance: {{ state_attr('sensor.kyle_on_peloton', "Resistance Average %") | float | round(0) }}% avg / {{ state_attr('sensor.kyle_on_peloton', "Resistance Max %") | float | round(0) }}% max
- Speed (Mph): {{ state_attr('sensor.kyle_on_peloton', "Speed Average Mph") | float | round(2) }} avg / {{ state_attr('sensor.kyle_on_peloton', "Speed Max Mph") | float | round(2) }} max
- Speed (Kph): {{ state_attr('sensor.kyle_on_peloton', "Speed Average Kph") | float | round(2) }} avg / {{ state_attr('sensor.kyle_on_peloton', "Speed Max Kph") | float | round(2) }} max
- Cadence (Rpm): {{ state_attr('sensor.kyle_on_peloton', "Cadence Average Rpm") | float | round(0) }} avg / {{ state_attr('sensor.kyle_on_peloton', "Cadence Max Rpm") | float | round(0) }} max
- Power (W): {{ state_attr('sensor.kyle_on_peloton', "Power Average W") | float | round(2) }} avg / {{ state_attr('sensor.kyle_on_peloton', "Power Max W") | float | round(2) }} max
- Total Work: {{ state_attr('sensor.kyle_on_peloton', "Total Work") | float | round(0) }} J
- Output (KJ): {{ state_attr('sensor.kyle_on_peloton', "Output Kj") | float | round(2) }}
- Calories (KCal): {{ state_attr('sensor.kyle_on_peloton', "Calories KCal") }}
{% if state_attr('sensor.kyle_on_peloton', "Leaderboard Rank") != "None" -%}
- Leaderboard Rank: {{ state_attr('sensor.kyle_on_peloton', "Leaderboard Rank") }} / {{ state_attr('sensor.kyle_on_peloton', "Leaderboard Users") }} ({{ 100 - (100 * (state_attr('sensor.kyle_on_peloton', "Leaderboard Rank") | int ) / (state_attr('sensor.kyle_on_peloton', "Leaderboard Users") | int)) | round(0) }}%)
{%- endif %}
theme: solarized_light

HA Error Related to No Version Key

Upon starting HA, I get this warning relating to the peloton add-in:

2021-04-25 16:05:03 WARNING (MainThread) [homeassistant.loader] No 'version' key in the manifest file for custom integration 'peloton'. As of Home Assistant 2021.6, this integration will no longer be loaded. Please report this to the maintainer of 'peloton'

Not sure if you were aware of this, but wanted to bring it to your attention. More information can be found here: https://www.home-assistant.io/blog/2021/03/03/release-20213/#breaking-changes

Add a version into manifest

Including this custom component in, I notice that HA marks it as it won't be supported in upcoming release without adding an extra key to the manifest.

No 'version' key in the manifest file for custom integration 'peloton'. As of Home Assistant 2021.6, this integration will no longer be loaded. Please report this to the maintainer of 'peloton'

Can you add this in the future?

not working

updated to 0.5.3 but still data not populating (worked fine before) only date/time and class rank

Update Interval Settings + Logic

In order to not overload the API we need to have:

  • A setting for the user to select how often to poll the API
  • Logic to increase the polling interval while a workout is in progress and decrease the interval when idle.
  • An off period defined by the user to not poll the API.

All of these ideas are to prevent overloading the API while not in use.

Current values/sensors don't drop to zero when not in use

I don't know if this is a problem on my end, or just how the sensors work, but sensors like current cadence/resistance/heart rate/speed don't zero out when a workout isn't in progress/running. What ever the final value was of the workout, is the persistent value until you workout again.

Installation issues

Hi I am a HA noob, so apologies first up, this might be more of a basic HA question. I am running Hass IO on Raspberry Pi (image provided officially).
After I followed the instructions to install this sensor, I keep getting the error No module named "pylotoncycle"
I don't seem to have python environment via the Terminal integration, so Python is unavailable.

I downloaded the Python module using curl and copied the *.py files to the custom_components/peloton folder, no dice. Before I start changing the import statements, is there a better and obvious way to do this that I am missing?

Many thanks for the work on this integration. Cheers.

Some structures changed after api update?

Seeing the below errors upon logging in now.
2021-06-23 11:38:48 ERROR (MainThread) [homeassistant.components.sensor] peloton: Error on device update! Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 358, in _async_add_entity await entity.async_device_update(warning=False) File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 466, in async_device_update await task File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run result = self.fn(*self.args, **self.kwargs) File "/config/custom_components/peloton/sensor.py", line 80, in update conn = pylotoncycle.PylotonCycle(self.user, self.password) File "/config/custom_components/peloton/pylotoncycle/pylotoncycle.py", line 31, in __init__ self.login(username, password) File "/config/custom_components/peloton/pylotoncycle/pylotoncycle.py", line 52, in login self.total_workouts = resp['user_data']['total_workouts'] KeyError: 'user_data'

Add Workout Counter Sensor

Add a sensor, set of sensors, or sensor with sub-attributes that counts how many workouts a user has taken. This could be useful to watch for upcoming milestones.

Primary State

Is it possible to add the primary state back to the new code? It was easy to track if a workout was happening by just triggering off the 'Active' status vs Complete.

# Update Primary State if (workout_latest["status"]== 'COMPLETE'): self._state = 'Complete' elif (workout_latest["status"]== 'IN_PROGRESS'): self._state = 'Active' else: self._state = 'Unavailable'

Thank you for a great plugin.

This entity is no longer being provided by the peloton integration.

Hi Ed, not sure if this a problem with my setup, but the binary sensor for 'workout type' has stopped working with 2023.1.0

I will keep debugging.....

  peloton_workout:
    icon_template: mdi:shoe-sneaker
    friendly_name: "Peloton Workout"
    value_template: >
      {{ state_attr('binary_sensor.neil_on_peloton_workout', "Workout Type") }}

binary_sensor.neil_on_peloton_workout

This entity is no longer being provided by the peloton integration. If the entity is no longer in use, delete it in settings.

Home Assistant 2023.1.0
Supervisor 2022.12.1
Operating System 9.4
Frontend 20221213.1 - latest

image

image

from a tread workout
image

image

Peloton errors when starting workout

Whenever I start a workout I get a number of the errors below in my logs. Not doing anything special. It is a Peloton Plus with which I'm using an Apple Watch for heart rate monitoring.

I'm using HA 2011.11.2 and Peloton 0.10.0.

2023-11-11 10:54:57.760 ERROR (MainThread) [custom_components.peloton] Unexpected error fetching peloton data: list index out of range
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 290, in _async_refresh
self.data = await self._async_update_data()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 246, in _async_update_data
return await self.update_method()
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/peloton/__init__.py", line 79, in async_update_data
"quant_data": compile_quant_data(
^^^^^^^^^^^^^^^^^^^
File "/config/custom_components/peloton/__init__.py", line 278, in compile_quant_data
if isinstance((value := metric.get("values")[len(metric.get("values"))-1]), int)
~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
IndexError: list index out of range

At some point I'll try to set up in my dev environment to debug. Looking at that line of code, I'd anticipate that the "values" list is empty, and it is trying to get item '-1' from it.

Missing Attributes

Awesome integration thanks for this!

I've noticed recently however that not all attributes are populating like they used to. I don't see any errors specifically in the logs. Is this a known issue?

Thanks.

image
image

End Time always = Start Time during workout

The end time is always the start time during a workout. Therefore there's no way of displaying the actual estimated end time allowing for any pauses.

If there's no pause (almost always the case), then start time plus duration works nicely - and that's what I'm using at the moment.

Why this is important: my wife likes to know when I'll be done without coming in and disturbing my mojo. 😁

Attribute names

Good morning and fantastic work on this. I am using this sensor with custom:entity-attributes-card to show some stats from my most recent ride, but it's not clear to me how the attributes are actually named. I've been able to guess at many of them (the single word attributes are obvious) or get close enough with wildcards - for example, sensor.peloton_user.duration* - but some of them I simply can't figure out. Is it possible to list them all here?
image
Thanks!

Error after reinstall

I'm refreshing some of my Home Assistant tabs and ran into this error after removing and then re-adding the Peloton integration via HACS:
image
with this accompanying entry in the logs:

Source: requirements.py:275
First occurred: 8:49:40 AM (2 occurrences)
Last logged: 8:49:56 AM

Error handling request
Traceback (most recent call last):
  File "/usr/lib/python3.10/site-packages/aiohttp/web_protocol.py", line 433, in _handle_request
    resp = await request_handler(request)
  File "/usr/lib/python3.10/site-packages/aiohttp/web_app.py", line 504, in _handle
    resp = await handler(request)
  File "/usr/lib/python3.10/site-packages/aiohttp/web_middlewares.py", line 117, in impl
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/security_filter.py", line 85, in security_filter_middleware
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/forwarded.py", line 100, in forwarded_middleware
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/request_context.py", line 28, in request_context_middleware
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/ban.py", line 80, in ban_middleware
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/auth.py", line 235, in auth_middleware
    return await handler(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/view.py", line 146, in handle
    result = await result
  File "/usr/lib/python3.10/site-packages/homeassistant/components/config/config_entries.py", line 148, in post
    return await super().post(request)
  File "/usr/lib/python3.10/site-packages/homeassistant/components/http/data_validator.py", line 72, in wrapper
    result = await method(view, request, data, *args, **kwargs)
  File "/usr/lib/python3.10/site-packages/homeassistant/helpers/data_entry_flow.py", line 71, in post
    result = await self._flow_mgr.async_init(
  File "/usr/lib/python3.10/site-packages/homeassistant/config_entries.py", line 845, in async_init
    flow, result = await task
  File "/usr/lib/python3.10/site-packages/homeassistant/config_entries.py", line 863, in _async_init
    flow = await self.async_create_flow(handler, context=context, data=data)
  File "/usr/lib/python3.10/site-packages/homeassistant/config_entries.py", line 962, in async_create_flow
    await _load_integration(self.hass, handler_key, self._hass_config)
  File "/usr/lib/python3.10/site-packages/homeassistant/config_entries.py", line 2026, in _load_integration
    await async_process_deps_reqs(hass, hass_config, integration)
  File "/usr/lib/python3.10/site-packages/homeassistant/setup.py", line 389, in async_process_deps_reqs
    await requirements.async_get_integration_with_requirements(
  File "/usr/lib/python3.10/site-packages/homeassistant/requirements.py", line 52, in async_get_integration_with_requirements
    return await manager.async_get_integration_with_requirements(domain)
  File "/usr/lib/python3.10/site-packages/homeassistant/requirements.py", line 171, in async_get_integration_with_requirements
    await self._async_process_integration(integration, done)
  File "/usr/lib/python3.10/site-packages/homeassistant/requirements.py", line 186, in _async_process_integration
    await self.async_process_requirements(
  File "/usr/lib/python3.10/site-packages/homeassistant/requirements.py", line 246, in async_process_requirements
    self._raise_for_failed_requirements(name, missing)
  File "/usr/lib/python3.10/site-packages/homeassistant/requirements.py", line 275, in _raise_for_failed_requirements
    raise RequirementsNotFound(integration, [req])
homeassistant.requirements.RequirementsNotFound: Requirements for peloton not found: ['git+https://github.com/RobertD502/pylotoncycle@dev#pylotoncycle==0.6.0.1'].```

Add UI Config Flow Handler

Currently the integration is configured via configuration.yaml file, so we need to implement a UI config flow. See the following docs:

This should:

  • Migrate existing users who are configured in yaml automatically
    • Prompt them to remove the yaml config.
    • retain the existing entity_ids
  • Allow a new user to login, validating their credentials are correct.
  • Handle bad passwords for pre-existing logins warning the user.

Please feel free to comment about the requirements or submit PRs with changes. I believe this is a requirement for integrating into mainline HASS.

Bike, Tread and Guide differences

Thanks Ed love your work and effort, hoping the following observation help?

The State attributes are quite different, eg there are no ‘Heat Rate’ values on the tread (would love to trigger a fan on the tread) also labeled ‘Prism’, the ‘output Kj’ did not update every 30 secs or so, only on completion and no Calories?

image

Entity implements `device_state_attributes`

After updating Home Assistant to version 2021.12.1 with this integration installed I received the following warning in my log:

2021-12-13 11:50:37 WARNING (MainThread) [homeassistant.helpers.entity] Entity sensor.peloton_mdegat01 (<class 'custom_components.peloton.sensor.PelotonSensor'>) implements device_state_attributes. Please report it to the custom component author.

So as requested I am reporting it. To my knowledge this warning just started appearing in version 2021.12.1. I am not super diligent about checking my HA logs but I check them often enough that I feel like I would've noticed it if this was happening in version 2021.11.

Minor changes to the Example Template Card YAML

@edwork - I've noticed that the Example Template Card has not been displaying properly, and while I recognize that it is for example purposes only, thought I'd offer an update to correct some issues I've come across. Additionally, the Latest Workout Metrics will only display if the last workout session occurred on the bike.

  {% if is_state('sensor.peloton_username', 'Active') %}

  ### Current Metrics:
  
  <font color="firebrick"><ha-icon icon="mdi:heart-pulse"></ha-icon></font> **Heart Rate (bpm):** {{ state_attr('sensor.peloton_username', "Heart Rate Bpm") }}
  <font color="darkorange"><ha-icon icon="mdi:omega"></ha-icon></font> **Resistance (%):** {{ state_attr('sensor.peloton_username', "Resistance %") }}
  <font color="darkorchid"><ha-icon icon="mdi:speedometer"></ha-icon></font> **Speed (Mph):** {{ state_attr('sensor.peloton_username', "Speed Mph") }}
  <font color="darkorchid"><ha-icon icon="mdi:speedometer"></ha-icon></font> **Speed (Kph):** {{ state_attr('sensor.peloton_username', "Speed Kph") }}
  <font color="mediumseagreen"><ha-icon icon="mdi:sine-wave"></ha-icon></font> **Cadence Rpm:** {{ state_attr('sensor.peloton_username', "Cadence Rpm") }}
  <font color="orangered"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> **Power (W):** {{ state_attr('sensor.peloton_username', "Power W") }}
  
  ---
  
  {%- endif %}
  
  ### Latest Workout Summary:
  
  <ha-icon icon="mdi:calendar-range"></ha-icon>  - **Date:** {{ as_timestamp(state_attr('sensor.peloton_username', "Start Time"))|float|timestamp_custom('%Y/%m/%d &raquo; %H:%M') }} - {{ as_timestamp(state_attr('sensor.peloton_username', "End Time"))|float|timestamp_custom('%H:%M') }} ({{ state_attr('sensor.peloton_username', "Duration Min") }} mins)

  {% if state_attr('sensor.peloton_username', 'Workout Image') != 'None' %}
  <img src="{{ state_attr('sensor.peloton_username', "Workout Image") }}">
  {% endif %}
  
  **{{ state_attr('sensor.peloton_username', "Ride Title") }} ({{ state_attr('sensor.peloton_username', "Workout Type") }})**
  - *{{ state_attr('sensor.peloton_username', "Description") }}* 
  - Instructor: {{ state_attr('sensor.peloton_username', "Instructor") }}

  {% if is_state_attr('sensor.peloton_username', 'Workout Type','cycling') %}
  
  ---
  
  ### Latest Workout Metrics:
  
  <font color="royalblue"><ha-icon icon="mdi:map-marker-distance"></ha-icon></font>  - **Distance (Mi):** {{ state_attr('sensor.peloton_username', "Distance Mi") | float | round(2) }}
  <font color="firebrick"><ha-icon icon="mdi:heart-pulse"></ha-icon></font> - **Heart Rate (bpm):** {{ state_attr('sensor.peloton_username', "Heart Rate Average Bpm") | float | round(0) }} avg / {{ state_attr('sensor.peloton_username', "Heart Rate Max Bpm")  | float | round(0) }} max
  <font color="darkorange"><ha-icon icon="mdi:omega"></ha-icon></font> - **Resistance:** {{ state_attr('sensor.peloton_username', "Resistance Average %") | float | round(0) }}% avg / {{ state_attr('sensor.peloton_username', "Resistance Max %") | float | round(0) }}% max
  <font color="darkorchid"><ha-icon icon="mdi:speedometer"></ha-icon></font> - **Speed (Mph):** {{ state_attr('sensor.peloton_username', "Speed Average Mph")  | float | round(2) }}  avg / {{ state_attr('sensor.peloton_username', "Speed Max Mph")  | float | round(2) }} max
  <font color="darkorchid"><ha-icon icon="mdi:speedometer"></ha-icon></font> - **Speed (Kph):** {{ state_attr('sensor.peloton_username', "Speed Average Kph")  | float | round(2) }}  avg / {{ state_attr('sensor.peloton_username', "Speed Max Kph")  | float | round(2) }} max
  <font color="mediumseagreen"><ha-icon icon="mdi:sine-wave"></ha-icon></font> - **Cadence (Rpm):** {{ state_attr('sensor.peloton_username', "Cadence Average Rpm")  | float | round(0) }} avg / {{ state_attr('sensor.peloton_username', "Cadence Max Rpm")  | float | round(0) }} max
  <font color="orangered"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> - **Power (W):** {{ state_attr('sensor.peloton_username', "Power Average W")  | float | round(2) }} avg / {{ state_attr('sensor.peloton_username', "Power Max W")  | float | round(2) }} max
  <font color="orangered"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> - **Total Work:** {{ state_attr('sensor.peloton_username', "Total Work")  | float | round(0) }} J
  <font color="orangered"><ha-icon icon="mdi:lightning-bolt"></ha-icon></font> - **Output (KJ):** {{ state_attr('sensor.peloton_username', "Output Kj")  | float | round(2) }}
  <font color="crimson"><ha-icon icon="mdi:food"></ha-icon></font> - **Calories (KCal):** {{ state_attr('sensor.peloton_username', "Calories KCal") }}
  <font color="yellowgreen"><ha-icon icon="mdi:chevron-triple-up"></ha-icon></font> - **Leaderboard Rank:** {{ state_attr('sensor.peloton_username', "Leaderboard Rank") }} / {{ state_attr('sensor.peloton_username', "Leaderboard Users") }} ({{ 100 - (100 * (state_attr('sensor.peloton_username', "Leaderboard Rank") | int ) / (state_attr('sensor.peloton_username', "Leaderboard Users") | int)) | round(0) }}%)

  {% endif %}

Not available in config flow

Hi! Just tried installing via HACS and I couldn't find it in the "Add integration" UI to actually install and configure it.

Then I stumbled on #38 and saw that the 0.8 release hadn't been cut yet, so I tracked the master branch in HACS, restarted, confirmed it had the newest version on-disk, and... still can't find it in the UI to actually add it to my HA instance.

Not entirely sure what might be the issue here- I can see in the logs that HA notices there's a Peloton integration, but besides the initial We found a custom integration peloton message, it doesn't output anything else.

Happy to dig into things further!

Peloton website stats vs HA stats

First, a huge THANK YOU for all of your hard work! This is awesome!

I did a comparison of the stats that show up in HA versus what is on the Peloton website. Screenshots and comments/questions/thoughts below. I thought it might be helpful for you to see someone else's account/stats in case it is different from yours. Thanks!

image

image

Not adding sensor after installing via HACS

I've installed via HACS and updated configuration.yaml. I'm not seeing any errors, but it's not populating the sensor.

I've restarted and manually added to files into custom_components as well.

During a Ride Countdown the primary binary_sensor goes unavailable

Only tested during a pre-recorded 20 minute ride, during the 60 second countdown my sensor went unavailable.

Steps to Reproduce:

  • Select and start a pre-recorded ride
  • Observe the binary_sensor._on_peloton sensor go Unavailable

Likely what's being returned during this time is either null or different than the expected value. This should be a trivial fix.

HACS support

Great work, but would be great to get HACS support.

Warning logged every 30 seconds after updating to `0.6.0`

After updating to 0.6.0 and restarting I now see a warning in my logs every 30 seconds from my peloton sensors (seems like every time they update) I turned on debug logging as well for this component so here's the logs I get each sensor update:

2021-12-20 11:17:13 DEBUG (SyncWorker_15) [custom_components.peloton.sensor] Logging in and setting up session to the Peloton API
2021-12-20 11:17:15 DEBUG (SyncWorker_15) [custom_components.peloton.sensor] Updating Primary State
2021-12-20 11:17:15 DEBUG (SyncWorker_15) [custom_components.peloton.sensor] Updating Extra State Attributes
2021-12-20 11:17:15 WARNING (SyncWorker_15) [custom_components.peloton.sensor] Error on parsing State Attributes, something in the API may have changed

The sensors seem to be working fine I think? Honestly I'm not sure, I haven't really looked that closely at them in a while. The main thing I do with them is when state is Active and attributes.Workout Type is cycling or bike_bootcamp I use that as a room presence indicator (i.e. someone is using the bike). That attribute still seems to be there, if others are missing I wouldn't really know. Here's the full state of my sensor, if something looks like it is missing then let me know:
Screen Shot 2021-12-20 at 11 23 49 AM

I can set log level of this component to error if this warning is ignorable to prevent it from spamming my logs but ideally it would be either fixed or removed somehow since I like logging at warning level in general.

Lots of log errors lately

Hey @edwork! I hope you're doing well. I'm not sure if this is something on my end, on Peloton's end, or within the integration. But I have been receiving a lot of these errors lately. Any ideas?

Logger: homeassistant.helpers.entity
Source: custom_components/peloton/sensor.py:80
First occurred: 10:12:09 AM (186 occurrences)
Last logged: 10:58:10 AM

Update for sensor.peloton_xxx fails
Update for sensor.peloton_yyy fails
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 277, in async_update_ha_state
    await self.async_device_update()
  File "/usr/src/homeassistant/homeassistant/helpers/entity.py", line 473, in async_device_update
    raise exc
  File "/usr/local/lib/python3.8/concurrent/futures/thread.py", line 57, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/config/custom_components/peloton/sensor.py", line 80, in update
    conn = pylotoncycle.PylotonCycle(self.user, self.password)
  File "/usr/local/lib/python3.8/site-packages/pylotoncycle/pylotoncycle.py", line 31, in __init__
    self.login(username, password)
  File "/usr/local/lib/python3.8/site-packages/pylotoncycle/pylotoncycle.py", line 52, in login
    self.total_workouts = resp['user_data']['total_workouts']
KeyError: 'user_data'

KeyError: 'ride'

Just popped up today?

Home Assistant 2022.9.4
Supervisor 2022.08.6
Operating System 9.0
Frontend 20220907.2 - latest

This error originated from a custom integration.

Logger: custom_components.peloton
Source: custom_components/peloton/init.py:58
Integration: Peloton (documentation, issues)
First occurred: 4:03:59 pm (3 occurrences)
Last logged: 4:04:19 pm

Unexpected error fetching peloton data: 'ride'
Traceback (most recent call last):
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 205, in _async_refresh
self.data = await self._async_update_data()
File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 164, in _async_update_data
return await self.update_method()
File "/config/custom_components/peloton/init.py", line 58, in async_update_data
workouts = await hass.async_add_executor_job(api.GetRecentWorkouts, 1)
File "/usr/local/lib/python3.10/concurrent/futures/thread.py", line 58, in run
result = self.fn(*self.args, **self.kwargs)
File "/usr/local/lib/python3.10/site-packages/pylotoncycle/pylotoncycle.py", line 114, in GetRecentWorkouts
if 'instructor_id' in resp_workout['ride']:
KeyError: 'ride'

image

Entities have become unavailable

My integration was working fine up until at a day ago when the integration failed.

I have tried removing and readding through HACS.

See log below.

2023-07-10 14:04:49.916 ERROR (MainThread) [custom_components.peloton] Unexpected error fetching peloton data: list index out of range
Traceback (most recent call last):
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 283, in _async_refresh
    self.data = await self._async_update_data()
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/src/homeassistant/homeassistant/helpers/update_coordinator.py", line 242, in _async_update_data
    return await self.update_method()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/peloton/__init__.py", line 79, in async_update_data
    "quant_data": compile_quant_data(
                  ^^^^^^^^^^^^^^^^^^^
  File "/config/custom_components/peloton/__init__.py", line 278, in compile_quant_data
    if isinstance((value := metric.get("values")[len(metric.get("values"))-1]), int)
                            ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Various Peloton HA Integration Errors in Log

Just upgraded to 2023.2.4 and seeing these pop up in the logs:

Detected integration that called async_setup_platforms instead of awaiting async_forward_entry_setups; this will fail in version 2023.3. Please report issue to the custom integration author for peloton using this method at custom_components/peloton/__init__.py, line 98: hass.config_entries.async_setup_platforms(entry, PLATFORMS)
Logger: homeassistant.components.sensor
Source: components/sensor/__init__.py:503
Integration: Sensor (documentation, issues)
First occurred: 9:00:02 AM (3 occurrences)
Last logged: 9:00:02 AM

Entity sensor.mark_on_peloton_start_time (<class 'custom_components.peloton.sensor.PelotonStatSensor'>) is using state class 'measurement' which is impossible considering device class ('timestamp') it is using; expected None; Please update your configuration if your entity is manually configured, otherwise report it to the custom integration author.
Entity sensor.mark_on_peloton_end_time (<class 'custom_components.peloton.sensor.PelotonStatSensor'>) is using state class 'measurement' which is impossible considering device class ('timestamp') it is using; expected None; Please update your configuration if your entity is manually configured, otherwise report it to the custom integration author.
Entity sensor.mark_on_peloton_power_output (<class 'custom_components.peloton.sensor.PelotonStatSensor'>) is using state class 'measurement' which is impossible considering device class ('energy') it is using; expected None or one of 'total_increasing', 'total'; Please update your configuration if your entity is manually configured, otherwise report it to the custom integration author.

Heartrate

I created automations based on current heartrate with the old integration. This does not seem possible with the current integration. I only see Avg HR and Max HR. Am I missing something?

BTW - Great work on this integration. Thank you!

Date of class

Looks like missing sensor for date of class in attributes - defaults to 1969

Get this error in the HA logs

After copying the custom components folder in, updating config, and restarting

Platform error sensor.peloton - No module named 'pylotoncycle'

Values do not reflect actuals

I really love, that you made the effort of trying to get the Peloton readouts integrate with Home Assistant.
In my Setup however, the values are not updated properly, workouts are not recognized or updated. E.g I did two rides yesterday, today it only shows only one rides values. Also, do I need to reset the values to 0 each day with an automation (calories, distance etc.)?

HA - Heart Rate BPM

Hello,

I noticed that the value reported in HA is up to 30bpm off/lower than what is actual.

Should this be value vs average_value?
self._attributes.update({"Heart Rate Bpm":str(stats_latest["metrics"][4]["average_value"])})

Update:
I changed to this and it is now back in sync:
self._attributes.update({"Heart Rate Bpm":str(stats_latest["metrics"][4]["values"][-1])})

Have notify.alexa call out stats via TTS

I've got it to trigger via events and give pre-typed responses, however I'd like to have it provide data during certain milestones. Any idea on how to do this? Below is what I have tried.

data:
data:
type: tts
message: '{{ state_attr(''sensor.peloton_username'', "Workout Type" ) }}'
service: notify.alexa_media_echo_show

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.