polarofficial / polar-ble-sdk

Repository includes SDK and code examples. More info https://polar.com/en/developers
Other
447 stars 147 forks source link

ACC error "notificationNotEnabled" was observed sometime at the recovery procedure of BLE disconnection. #403

Closed ymatt345 closed 7 months ago

ymatt345 commented 8 months ago

Platform your question concerns:

Device:

Description:

Hi, I would like to know the ACC recovery procedure after the ble disconnection and to know how to proceed the recovery when the ACC error “notificationNotEnabled” was reported.

I have integrated ble-sdk 5.1.1 to my storyboard app. Prior to this version, It seems that I did not face this problem.

I described my recovery procedure as follows.

  1. At the ble-disconnection do onlineStreamStop for hr and acc.
func deviceDisconnected(_ polarDeviceInfo: PolarDeviceInfo) {
          Task { @MainActor in
            self.deviceConnectionState = DeviceConnectionState.disconnected(polarDeviceInfo.deviceId)
            self.onlineStreamStop(feature: PolarDeviceDataType.acc)
            self.onlineStreamStop(feature: PolarDeviceDataType.hr)
            /// when ble is connecting, the status becomes Connecting and then Connected. 
         }
    }
  1. At the Connected delegate, after 5 second later do hrStreamStart() and accToggle()
func deviceConnected(_ polarDeviceInfo: PolarDeviceInfo) {
        Task { @MainActor in
            self.deviceConnectionState = DeviceConnectionState.connected(polarDeviceInfo.deviceId)
        let waitTimer = Timer.scheduledTimer(withTimeInterval: 5.0, repeats: false, block: { (timer) in

                self.hrStreamStart()
                self.accToggle?.dispose()
                self.accToggle = nil
                self.accToggle(self)       
    }
}
  1. At the accToggle(), do startAccStreaming and monitor if error was observed.
@IBAction func accToggle(_ sender: Any) {
        if accToggle == nil {

                ~
           var accStreamSettings:[TypeSetting] = []
            accStreamSettings.append(TypeSetting(type: PolarSensorSetting.SettingType.sampleRate, values: [50]))
            accStreamSettings.append(TypeSetting(type: PolarSensorSetting.SettingType.range, values: [2]))
            accStreamSettings.append(TypeSetting(type: PolarSensorSetting.SettingType.resolution, values: [16]))
            let    selectedSettings = RecordingSettings(feature: PolarDeviceDataType.acc ,settings: accStreamSettings)
            var logString:String = "Stream accStreamSettings \(String(describing: accStreamSettings))  
            var polarSensorSettings:[PolarSensorSetting.SettingType : UInt32] = [:]
            for setting in accStreamSettings{ 
                  polarSensorSettings[setting.type] = UInt32(setting.values[0]
                  logString.append(" \(setting.type) \(setting.values[0])")
             }
           NSLog(logString)

           Task { @MainActor in
                 self.onlineStreamingFeature.isStreaming[.acc]
             }
            onlineStreamingDisposables[.acc] = api.startAccStreaming(self.appdelegate.sensorId,            settings:PolarSensorSetting(polarSensorSettings))
                   .subscribe{ e in
                        switch e {
                               case .next(let data):

                ~  process acc data

             case .error(let err):
                                NSLog("ACC error: \(err)  self.deviceConnectionState \(self.deviceConnectionState )")

        // ACC error: notificationNotEnabled was observed sometimes after ble disconnected recovery.
        // Please advise me how to programmatically check “err” message.

                         case .completed:
                                NSLog("ACC completed:")
                            break
                       }
                 }
        } else {
            print("accToggle not equal nil")
            accToggle?.dispose()
        }
    }

I tried to check the Acc error code, but failed to programmatically check it. If some thing wrong with my recovery process, please let me know. Best regards,

ACC error at recovery H10.pdf

aburashima commented 8 months ago

Hi ymatt345, Unfortunately, I can not help you as I myself just start using the package. But could you please help me with your expertise? In your code you set the acceleration stream parameters sample rate, range and resolution as 50, 2 and 16 respectively. What are the possible values of these parameters? What are the parameters' units?
I receive the following reading from the stream, e.g.: x: -926 y: 41 z: 47 timeStamp: 599618754506351232 As far as I understand, the acceleration components are measured in one thousandth of G. But what are the units of the timestamp? Thank you in advance!

jimmyzumthurm commented 8 months ago

Hi @ymatt345 The timestamp is the amount of nanoseconds since 1st January 2000 UTC time. The accelerometer data you provide here is in "milli-G" unit, as you correctly assumed. Note that acceleration of gravity is present in the data.

The parameters given for the start measurement should first be asked to the device using requestStreamSettings API.

In that specific case : sampling rate = 50 Hz Range = +-2G -> all the accelerometer values will be in +- 2000 mG range (it will saturate over this range). This allows to have greater accuracy of data in case your application is analyzing smaller movements than having greater range, but all acceleration over +- 2G will be lost. Resolution = 16 -> data is on 16 bits, this you don't need to worry about that, this is used for internal logic only.

aburashima commented 8 months ago

Hi @ymatt345 The timestamp is the amount of nanoseconds since 1st January 2000 UTC time. The accelerometer data you provide here is in "milli-G" unit, as you correctly assumed. Note that acceleration of gravity is present in the data.

The parameters given for the start measurement should first be asked to the device using requestStreamSettings API.

In that specific case : sampling rate = 50 Hz Range = +-2G -> all the accelerometer values will be in +- 2000 mG range (it will saturate over this range). This allows to have greater accuracy of data in case your application is analyzing smaller movements than having greater range, but all acceleration over +- 2G will be lost. Resolution = 16 -> data is on 16 bits, this you don't need to worry about that, this is used for internal logic only.

Got it! Thanks a lot for the detailed explanation!

ymatt345 commented 8 months ago

We would like you to understand that this problem is very critical for our app and provide a solution to us.

Our app provides over 24 hours of continuous activity and sleep monitoring. If ACC error "notificationNotEnabled" occurred when disconnecting BLE, ACC data could not be monitored. This means the app will no longer monitor your activity and sleep.

ACC error "notificationNotEnabled" was observed once a week. This means the App does not function.

Your body posture, such as when you lay-down and stand-up, tells us the timing of go-to-bed and wake-up especially for sleep monitoring.

Therefore, it is necessary and important to clarify the recovery process for the ACC error "notificationNotEnabled".

We are waiting for the solution from developer.

Best regards,

ymatt345 commented 8 months ago

Hi aburashima and jimmyzumthurm

As you suggested that "requestStreamingSettings" give us the available setting for the device. I am now working on the ACC from H10 and "requestStreamingSettings" returned the available settings option for ACC that is sampleRate, values: [50, 25, 100, 200]), SettingType.range, values: [4, 8, 2] and SettingType.resolution, values: [16]. That is why I chose the sampleRate 50, range 2 and resolution 16 for the settings.

Are you saying that the making "requestStreamingSettings" would resolve the ACC error "notificationNotEnabled" after recovery procedure of BLE disconnection. I have already inserted the "requestStreamingSettings" prior to "startAccStreaming", but ACC error "notificationNotEnabled" was observed sometimes.

Is this the bug on H10 firmware? I have never faced the "notificationNotEnabled" error for the first connection.

This occurs immediately after the BLE retry step if the disconnected state is followed by the connected state. But It happens once per several retry procedures.
I wish you to investigate this problem.

ymatt345 commented 7 months ago

Hi, I could solve the issue by revising the recovery procedure for temporary BLE disconnection. Thank you.