Zwift Sensor Component - Feedback and Testers Needed

I’ll check the new stuff out. Thanks for the hard work and thanks for the heads up.

Must say that I really love this component, the only thing I miss is in which world your last ride was in, or what route you did select. But I guess it is impossible to extract, else it would be somewhere in the attributes :wink:

super cool! the latest_activity does seem to have a “world id” property but i’m not sure how that correlated to the different worlds.

Watopia 1
Richmond 2
London 3
New York 4
Innsbruck 5
Yorkshire 7

I assume there is a world ID for the Giro TT, and I’m not sure if the MTB course it technically a different world?

i’m very interested in that “Last ride” panel.

Thanks for the info about the world id property and the names behind the ID’s. Let’s see if I can get that working :slight_smile:

For the “Last ride” panel, I have used a Markdown Card with the following code. Ofcourse the XXXXX needs to be replaced with your own zwift ID.

> Last session: {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.name }}
> 
> ![Image]( {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.primaryImageUrl }} )
> 
> The ride started on {{ as_timestamp(states.sensor.zwift_online_XXXXX.attributes.latest_activity.startDate) | timestamp_custom(' %d %B %Y at %H:%M ') | replace(" 0", "") }}
> The ride took {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.duration }} Minutes.
> The ride ended on {{ as_timestamp(states.sensor.zwift_online_XXXXX.attributes.latest_activity.endDate) | timestamp_custom(' %d %B %Y at %H:%M ') | replace(" 0", "") }}
> 
> Ride stats:
> {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.distanceInMeters }}  Meters driven.
> {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.totalElevation }} Climbing done.
> {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.avgWatts }} Average watts.
> {{ states.sensor.zwift_online_XXXXX.attributes.latest_activity.calories }} Calories burnt.
2 Likes

Thanks @phillprice ! I integrated this into version 2.1 in HACS. a “world_name” will now be present on the latest_activity attribute in the online sensor. @Maurice_van_den_Hoog give it a shot!

Thanks a lot @snicker, it’s working great!

zwift2

Noob question for you guys. I think whats been done here is fantastic!

having a bit of trouble getting things setup, although i feel that I’m very close… everything is installed, I’m getting an error from my configuration.yaml. HA enters safe mode and says ‘Secret MyUsername is not defined’… I feel like its something simple I am missing? everything is in the appropriate folders.
could someone point me in the right direction?
Thanks

you have to add that to your secrets.yaml file. docs here https://www.home-assistant.io/docs/configuration/secrets/

alternatively, if you aren’t sharing your configuration file with anyone or uploading to Github etc, you can just write your username there.

1 Like

This is how I have it in my files:

Configuration.yaml

sensor:
  - platform: zwift
    username: !secret my_zwift_username
    password: !secret my_zwift_password
    players:
      - !secret my_friends_zwift_player_id

secrets.yaml

my_zwift_username: XXX
my_zwift_password: XXX
my_friends_zwift_player_id: XXX

This secets.yaml file is in the same folder as the configuration.yaml

Hope it helps :slight_smile:

1 Like

Excellent! I’m in business. Made a lot of progress today. my end goal is a diy Kickr Climb. after my progress today I was confident enough to place an order for the remaining hardware.

I’ve made small modifications to the code that @Maurice_van_den_Hoog provided and have a great dashboard. I’ve also integrated some rudimentary GPIO switches on my dashboard which I’ve verified are working. I have also created a serial input, for the Gradient/angle sensor (MPU6050) which is being fed from an Arduino Uno. I couldn’t get the MPU working on the Pi but it was quite easy with the arduino

this should allow me to grab the gradient from the current activity, and tell my linear actuator (driven through L298N driver) to keep moving until the accelerometer (serial input) matches what’s coming from zwift.
feel like I’m getting close! thanks for all the help! I’ll be sure to keep updating!
here’s a screenshot

2 Likes

can’t wait to see the finished product!

1 Like

Wow, nice one @quartapound. Looks great and sounds promising :wink: Also going to create a profile part, as you have done.

1 Like

screen captured a video today while the wife was Zwifting. wanted to see how quick things responded and make sure things were working with the live stats. looking good!
I assume the gradient reported is affected by what we have the trainer difficulty set to?
I’ll also setup averaging on the accelerometer sensor so it stabilizes.

because the gradient is not provided by the API, the calculation is done in python code as a delta between two updates:

line 333 of sensor.py:

                        if self.players[player_id].data.get('distance',0) > 0:
                            delta_distance = distance - self.players[player_id].data.get('distance',0)
                            delta_altitude = altitude - self.players[player_id].data.get('altitude',0)
                            if delta_distance > 0:
                                gradient = delta_altitude / delta_distance

@quartapound I don’t think anyone else has paid a detailed amount of attention to the gradient, and there are is one concern I’ve had:

  • the altitude is also reported from the API as a strange value. At some point I found on the internet that it needs to have 9000 subtracted from it and then divided by 2 to get altitude in meters. (wish I would have recorded the source of that understanding). I am not sure if this is consistent based on units reported from the API or if it is consistent from world to world

I’ve found that the gradient is quite consistent to what is shown on the screen in my rides though, but I also have my units in metric. I am not sure what happens if you change to imperial.

I suspect there might be an issue with that formula. You mention the source of your formula in post # 40, " on the Zwift Coders facebook group that the altitude units are in half-centimeters and sea level is offset by 9000 half-centimeters in wattopia."

She rode in London, I’ll get her to ride on Watopia tomorrow and I’ll see if the formula matches for that world. strava said the ride ended at 96m, screen recording of HA showed 4851m

thinking out loud, the ‘altitude’ variable in sensor.py is still in centimeters… not meters?

EDIT:
so I’ve done some testing. I wonder if Zwift has changed their code since that post. I’m also wondering if this change has to do with resolution for accuracy in races? Is it possible that they used to have accuracy to 0.5cm (5mm) and now they have improved it to 1mm?
… I’ve edited sensor.py to simply divide the incoming player_state.altitude / 1000 and I’m now getting exactly the numbers I’d expect. this is on Watopia. not using the 900 offset. here are some screenshots I’ve used to cross reference with strava. Starting location in Watopia has a section that’s -3%grade where you start, it changes quickly. I put my avatar in this spot, then let the HA plugin run, then looked on strava at an old ride for elevation info.

I’ll do some more testing in different locations tomorrow if I can. either way it shouldnt change the delta calculation for the gradient I’d imagine?

thanks for the awesome detective work… it is possible that it changed or i simply have had it wrong from the beginning! either way, do let me know after a few more rides if it’s consistent and the value should be changed in the code. I haven’t been able to ride this week… fractured my toe riding outdoors with flip flops on last weekend :frowning:

Is there a way to add the workout message/protobuf data to the accessible information?