dvmarinoff / Auuki

Indoor Cycling App for Structured Training
https://auuki.com
GNU Affero General Public License v3.0
565 stars 94 forks source link

Ble Disconnects (?) in Middle of Workout #99

Closed GCuser99 closed 2 years ago

GCuser99 commented 2 years ago

Hi @dvmarinoff,

Here are the results of a short test I ran today on your development version (flux-devel.vercel.app) ...

I created the following workout file for the test:

<workout_file>
  <author/>
  <name/>
  <description/>
  <sportType>bike</sportType>
  <durationType>time</durationType>
  <tags/>
  <workout>
    <Warmup Duration="295" PowerLow="0.054" PowerHigh="0.554" pace="0"/>
    <SteadyState Duration="120" Power="0.901" pace="0"/>
    <SteadyState Duration="120" Power="0.5" pace="0"/>
    <SteadyState Duration="120" Power="0.901" pace="0"/>
    <SteadyState Duration="120" Power="0.5" pace="0"/>
    <SteadyState Duration="120" Power="0.901" pace="0"/>
    <SteadyState Duration="120" Power="0.5" pace="0"/>
    <SteadyState Duration="120" Power="0.901" pace="0"/>
    <FreeRide Duration="240" FlatRoad="0"/>
  </workout>
</workout_file>

Next I succesfully paired my Wahoo Kickr and cadence sensors ...

I started the 23 minute workout, and after about 10 minutes the activities power profile in the display stopped updating and (I perceived) my output power remained constant at 180 watts throughout the remainder of the workout. Here is a snapshot that I took at the end of the workout:

What I noticed during the workout:

I took a screen shot of the settings tab at the end of the ride and the Kickr no longer appears to be paired:

However, after uploading the fit file to Strava, it appears the entire 23 minute activity was captured and appears to verify that my power output was indeed 180 watts after the +-10 minute mark:

Screenshot 2022-02-02 143003

Here is the Developer Console output. Near the backing up of 600 records, the Ble for the controllable disconnected, but the cadence sensor remained connected until the end:

db.js:241 start db
views.js:12 start views.
connectionManager.js:9 start connection manager
index.js:22 start app.
idb.js:27 :idb :open :db 'store' :store-name 'session' ...
web-serial.js:214 

       :serial :ant-not-found
getKnownAnt @ web-serial.js:214
idb.js:93 :idb :getAll :store 'session' :success
models.js:458 :idb :restore 'session' :length 1
idb.js:93 :idb :clear :store 'session' :success
service.js:78 :rx :characteristics  Object
web-ble.js:151 Notifications started on cyclingPowerMeasurement: 00002a63-0000-1000-8000-00805f9b34fb.
web-ble.js:151 Notifications started on wahooTrainer: a026e005-0a7d-4ab3-97fa-f1500f9feb8b.
control.js:460 :rx :wcps :response [object Object] :raw 1,32,2
control.js:460 :rx :wcps :response [object Object] :raw 1,72,1,0,0,0
control.js:460 :rx :wcps :response [object Object] :raw 1,67,1,0
control.js:460 :rx :wcps :response [object Object] :raw 1,71,1,0,0,0
db.js:81 Object
service.js:78 :rx :characteristics  Object
common.js:84 maxRateCount: 3
web-ble.js:151 Notifications started on speedCadenceMeasurement: 00002a5b-0000-1000-8000-00805f9b34fb.
common.js:262 rateAdjuster :on pm :tsAvgDiff 1000.9999999999999 :result 2
common.js:84 maxRateCount: 2
common.js:84 maxRateCount: 2
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,0,0
common.js:262 rateAdjuster :on cscs :tsAvgDiff 916.5 :result 2
common.js:84 maxRateCount: 2
common.js:84 maxRateCount: 2
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,10,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,14,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,18,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,22,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,26,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,28,0
watch.js:277 backing up of 60 records ...
db.js:122 :zwo set target cadence 0
idb.js:93 :idb :put :store 'session' :success
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,32,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,36,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,40,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,42,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,46,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,50,0
watch.js:277 backing up of 120 records ...
db.js:122 :zwo set target cadence 0
idb.js:93 :idb :put :store 'session' :success
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,54,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,57,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,60,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,64,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,68,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,72,0
watch.js:277 backing up of 180 records ...
db.js:122 :zwo set target cadence 0
idb.js:93 :idb :put :store 'session' :success
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,76,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,78,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,82,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,86,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,90,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,92,0
watch.js:277 backing up of 240 records ...
db.js:122 :zwo set target cadence 0
idb.js:93 :idb :put :store 'session' :success
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,96,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,100,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,104,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,108,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,110,0
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,180,0
watch.js:277 backing up of 300 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 360 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,100,0
watch.js:277 backing up of 420 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 480 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
control.js:460 :rx :wcps :response [object Object] :raw 1,66,1,0,180,0
watch.js:277 backing up of 540 records ...
idb.js:93 :idb :put :store 'session' :success
device.js:87 Disconnected ble:controllable, Wahoo KICKR A730.
watch.js:277 backing up of 600 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 660 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 720 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 780 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 840 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 900 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 960 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 1020 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 1080 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 1140 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 1200 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 1260 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:277 backing up of 1320 records ...
idb.js:93 :idb :put :store 'session' :success
watch.js:53 Workout done!
watch.js:38 Workout done!
watch.js:277 backing up of 1380 records ...
idb.js:93 :idb :put :store 'session' :success
db.js:122 :zwo set target cadence 0
watch.js:277 backing up of 1400 records ...
idb.js:93 :idb :put :store 'session' :success
models.js:394 Array(1422)
lock.js:51 Wake lock released.
idb.js:93 :idb :put :store 'session' :success
lock.js:51 Wake lock released.
idb.js:93 :idb :put :store 'session' :success
device.js:87 Disconnected ble:speed-and-cadence, Wahoo CADENCE DF21.
dvmarinoff commented 2 years ago

Thanks for the report, it’s incredibly valuable. And I am sorry to hear your workout didn't went through.

In my case, my Tacx Flux S trainer has a well known firmware bug, which makes it drop the connection when you stop pedalling after a prolong steady effort at intensity. But in any case I get drop outs rarely, like 1 a week, and it’s quick and easy to reconnect the controllable from the top menu.

The rest is more or less expected behaviour. The workout kept running, and the power value remained at the last data point it received. What I can do is reset values to 0 when the connection is dropped, but trying to distinguish between real signal and signal that’s stuck is hard in this case (some trainers seriously over smooth data when in ERG, etc., and such a feature is likely to cause more problems than solve any).

GCuser99 commented 2 years ago

I'm glad the test was helpful feedback. It is pretty amazing that your code works as well as it does without testing.

I didn't try to reconnect the device because I really didn't understand what was going on until after the workout was completed. I will try again to see if the dropout was just a fluke.

As for a fix other than an auto-reconnect, which you're not supporting now, I wouldn't bother... Maybe if you can get the Ant+ side of this working, in Windows someday... :-)

dvmarinoff commented 2 years ago

Hm, I'll have to think of some other way to communicate disconnections. Maybe a text message could show up on top of the current power graph. Else the red-yellow-green indicator on the side of the controllable label, at the top bar indicates the current status of the connection: disconnected-connecting-connected. But I guess it's confusing when the resistance remains the same and the clock is ticking. My trainer resets to 0 resistance on disconnection, and the sudden drop in resistance is quite clear sign of what is going on.

GCuser99 commented 2 years ago

I know now to look at the red-yellow-green indicator light. I wasn't really confused and knew something was wrong, but wanted to finish the test without complicating things. And besides I needed the exercise! Thanks again for sharing your software...

TClin76 commented 2 years ago

@dvmarinoff BLE unexpected disconnection also happened in my case, but not so often. However my trainer (Magene) handle controllable disconnection is quite different from your TACX Flux. It seems that the ERG is still working, therefore I couldn't notice from resistance suddenly dropped. I think it is a good way to reset power value to 0 which is much easier for user to notice that the connection is dropped.

BTW, I can manually re-connect the device without any problem.

dvmarinoff commented 2 years ago

@TClin76 Thanks for the report!

If I am not mistaken thats on MacOS. Can you share more about your setup and also how often you get the drop outs?

TClin76 commented 2 years ago

@dvmarinoff That's correct. I use Chrome on MacOS and connect Magene Gravat as controllable & power meter, and another Magene cadence sensor. Sometimes it works perfect for a week, but sometimes it gets drop even more than once during a workout. I would say roughly 10-20% chance to get drop out for an 1-hour workout.

dvmarinoff commented 2 years ago

OK, that's more in line with random interference events. The auto reconnects feature would be able to fix this inconvenience.

dvmarinoff commented 2 years ago

I am working on bluetooth auto-reconnects, but will have to withhold them for a few more days, I am having some issues with the scanning API. A few more stability improvements are coming along too, but need more testing.

dvmarinoff commented 2 years ago

Closing this one. Will track progress of web-bluetooth auto reconnects here.

Did a lot of work on the issue last week, but with little progress. Some unexpected web-bluetooth behavior turned out to be related to a current bug in MacOS bluetooth which was only partially resolved by the latest update. Will do some easy features this week and resume work on bluetooth in the next one.