OpenGoPro: GoPro class handler -- no battery status? Does not turn off wifi AP?

As I’ve climbed my learning curve spending time with both the tutorials and the demos, I’m beginning to understand just how powerful the GoPro class handler is for us. It handles all the down and dirty asynchronous programming, establishes loops and threads, and does keep alive for those of us who do not fully understand asynchronous I/O programming techniques.

That said, and it could be somthing I’m missing or misunderstand about the abstraction, I don’t think it is doing what its meant to do arond the areas of disabling the WiFi Access Point and returning the battery status.

My simple test was to establish the GoPro class using the convenience method rather than the context handler as outlined in its docs. As I note GoPro connects, establishes wifi and subscribes to notifications in its initialize and enter() methods, I tried to then disable wifi in order to conserve power and also monitor the battery conditions.

Here is my simple setup:

from open_gopro import GoPro
import logging
import time

logging.basicConfig(filename="gopro_test.log",level=logging.DEBUG)

#connect to camera, start services, etc.   Alternative to context manager usage with start() convenience method.
gopro = GoPro("2659")  #my camera identifier
gopro.start()
# if wifi ap is on, turn it off to save battery
if gopro.wifi.is_on:
    gopro.ble_command.enable_wifi_ap(False)

try:
    #see if it turned off
    assert not gopro.wifi.is_on
except Exception as e:
    #log the assertion error if it didn't
    logging.error(repr(e))

#now -- while keep alive is continously connecting, log battery level and see if it changes over time.  Look for final
#last gasp before battery level shuts down gopro.  Sample every 60seconds recording battery level.
samples = []
for x in range(0,1000):
    sample = (x, time.asctime(), gopro.ble_status.batt_level.id.value)
    samples.append(sample)
    print(sample)
    logging.info(sample)
    time.sleep(60)

Snippets from my log file are as follows:

  • Camera scan discovers camera and connects correctly including disovery of wifi, password, SSID, etc. As exepected, gopro.start() calls convenience method to enter the context stat using GoPro.enter() method both runs self.initialize() and leaves the AP in “on” state. i also see the first of the keep alive log entries, again, as expected.

  • Here’s where it seems to go off the rails. I then use what would intuitively seem to be a status flag for wifi – gopro.wifi.is_on which returns True and I then attempt to disable the wifi AP to conserve power:

DEBUG:open_gopro.wifi_controller:Waiting 1 second for Wi-Fi connection to establish...
DEBUG:open_gopro.util:Send cmd --> netsh wlan show interfaces
DEBUG:open_gopro.util:Receive response --> 

There is 1 interface on the system: 



    Name                   : Wi-Fi

    Description            : Killer Wireless-n/a/ac 1435 Wireless Network Adapter

    GUID                   : 77ff450e-786f-48ea-a991-82ff16779da7

    Physical address       : 9c:b6:d0:95:35:09

    State                  : connected

    SSID                   : syr h9 black dredge1

    BSSID                  : d6:32:60:ae:c8:4c

    Network type           : Infrastructure

    Radio type             : 802.11ac

    Authentication         : WPA2-Personal

    Cipher                 : CCMP

    Connection mode        : Profile

    Channel                : 161

    Receive rate (Mbps)    : 433.3

    Transmit rate (Mbps)   : 433.3

    Signal                 : 100% 

    Profile                : syr h9 black dredge1 



    Hosted network status  : Not available




INFO:open_gopro.wifi_controller:Wifi connection established!
INFO:open_gopro.ble_commands:<----------- enable_wifi_ap : False
DEBUG:open_gopro.gopro:CmdId.SET_WIFI acquiring semaphore
DEBUG:open_gopro.gopro:CmdId.SET_WIFI has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90072-aa8d-11e3-9046-0002a5d5c51b: 03:17:01:00
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90072-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03\x17\x01\x00')
DEBUG:open_gopro.gopro:Received response on UUID.CQ_COMMAND_RESP: b'02:17:00'
DEBUG:open_gopro.gopro:CmdId.SET_WIFI released the semaphore
INFO:open_gopro.ble_commands:-----------> 
{
    "status": "SUCCESS",
    "id": "UUID.CQ_COMMAND_RESP::CmdId.SET_WIFI"
}
ERROR:root:AssertionError()

Not the assertion error I logged which would seem my attempt to turn off the wifi AP failed. …

  • Finally, in my for loop at the end of the test code, I simplly log the battery condition every minute until the gopro device turns itself off at low battery status. Here are some snippets of those log entries:
INFO:root:(1, 'Wed Jul 14 16:16:11 2021', 2)
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
DEBUG:open_gopro.gopro:SettingId.LED has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90074-aa8d-11e3-9046-0002a5d5c51b: 03:5b:01:3d
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90074-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03[\x01=')
DEBUG:open_gopro.gopro:Received response on UUID.CQ_SETTINGS_RESP: b'02:5b:00'
DEBUG:open_gopro.gopro:SettingId.LED released the semaphore
INFO:open_gopro.ble_commands:-----------> 
{
    "status": "SUCCESS",
    "id": "UUID.CQ_SETTINGS_RESP::SettingId.LED"
}
INFO:root:(2, 'Wed Jul 14 16:17:11 2021', 2)
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
DEBUG:open_gopro.gopro:SettingId.LED has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90074-aa8d-11e3-9046-0002a5d5c51b: 03:5b:01:3d
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90074-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03[\x01=')
DEBUG:open_gopro.gopro:Received response on UUID.CQ_SETTINGS_RESP: b'02:5b:00'
DEBUG:open_gopro.gopro:SettingId.LED released the semaphore
INFO:open_gopro.ble_commands:-----------> 
{
    "status": "SUCCESS",
    "id": "UUID.CQ_SETTINGS_RESP::SettingId.LED"
} 

....

INFO:root:(140, 'Wed Jul 14 18:35:11 2021', 2)
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
DEBUG:open_gopro.gopro:SettingId.LED has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90074-aa8d-11e3-9046-0002a5d5c51b: 03:5b:01:3d
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90074-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03[\x01=')
DEBUG:open_gopro.gopro:Received response on UUID.CQ_SETTINGS_RESP: b'02:5b:00'
DEBUG:open_gopro.gopro:SettingId.LED released the semaphore
INFO:open_gopro.ble_commands:-----------> 
{
    "status": "SUCCESS",
    "id": "UUID.CQ_SETTINGS_RESP::SettingId.LED"
}
INFO:root:(141, 'Wed Jul 14 18:36:11 2021', 2)
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
DEBUG:open_gopro.gopro:SettingId.LED has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90074-aa8d-11e3-9046-0002a5d5c51b: 03:5b:01:3d
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90074-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03[\x01=')
DEBUG:open_gopro.gopro:Received response on UUID.CQ_SETTINGS_RESP: b'02:5b:00'
DEBUG:open_gopro.gopro:SettingId.LED released the semaphore
INFO:open_gopro.ble_commands:-----------> 
{
    "status": "SUCCESS",
    "id": "UUID.CQ_SETTINGS_RESP::SettingId.LED"
}
INFO:root:(142, 'Wed Jul 14 18:37:11 2021', 2)
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
DEBUG:open_gopro.gopro:SettingId.LED has semaphore
DEBUG:open_gopro.ble_controller:Writing to b5f90074-aa8d-11e3-9046-0002a5d5c51b: 03:5b:01:3d
DEBUG:bleak.backends.dotnet.client:Write Characteristic b5f90074-aa8d-11e3-9046-0002a5d5c51b : bytearray(b'\x03[\x01=')
DEBUG:bleak.backends.dotnet.client:_ConnectionStatusChanged_Handler: 0
DEBUG:open_gopro.ble_controller:On device BleakClientDotNet (F5:A2:15:A9:A4:F7), Disconnected callback called!
ERROR:open_gopro.gopro:Response timeout of 10 seconds!
INFO:open_gopro.ble_commands:<----------- set : LED.BLE_KEEP_ALIVE
DEBUG:open_gopro.gopro:SettingId.LED acquiring semaphore
INFO:root:(143, 'Wed Jul 14 18:38:11 2021', 2)

### So, I see several issues/questions here:

  1. It would seem the gopro.wifi.is_on status flag does not work as it would seem as it reports True even after executing gopro.ble_command.enable_wifi_ap(False) to turn off wifi AP.
  2. gopro.ble_command.enable_wifi_ap(False) doesn’t seem to disable the wifi access point as I would have expected.
  3. If I’m intepreting the battery status response correctly (gopro.ble_status.batt_level.id.value), it never changes from “2” even though actual battery level goes from 90%+ to 0% over this test period and logged each minute.
  4. I would have expected a “last gasp” error reported through the services that the ble client subscribed to when initializing including battery status. I think I have seen occassional errors where this interrrupt/battery status reported 0% when iniitializing (ie when battery is full and I’m establishing intial ble connection). However, this does not appear to be subscribed corrrctly at the end. My final error is noted in the log above (ERROR:open_gopro.gopro:Response timeout of 10 seconds!) before my last logging of battery condition which is still “2”.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Comments: 16 (9 by maintainers)

Most upvoted comments

USB stream / control: this has been confirmed to be coming in a future release. I don’t have a date right now. If you want, you can make an enhancement request in this repo and I can update it when more information becomes available.

Very cool to see GoPro adopting this feature!

Hey, so I’m going to close this out and merge what I currently have. Here is a summary of the remaining open items:

  • USB stream / control: this has been confirmed to be coming in a future release. I don’t have a date right now. If you want, you can make an enhancement request in this repo and I can update it when more information becomes available.
  • battery testing: I’ve done some initial testing here and see the same result as you. After poking around, this isn’t entirely unexpected. It appears that the command to turn off WiFi does not actually power off the WiFi chip. I’d like to get some more data here and, if it makes sense, take this internally for improvement. I’ve created a discussion about this: https://github.com/gopro/OpenGoPro/discussions/35
  • Bugs from your log: I do see one worrisome WiFi timeout in that log file. It seems to be a bug on the camera side. However, I don’t have a way to reliably reproduce this yet. I’m hoping it will show up during the battery testing from above.
  • Feature to go back to default WIFi in Python SDK after disconnecting from GoPro: I’m going to hold off on this for now. Ultimately, I want to be able support connecting to multiple GoPro’s which brings about it’s own set of problems since we can only connect to one per WiFi adapter. So I need to some more thinking / redesigning about this.