Open
Description
CircuitPython version and board name
Adafruit CircuitPython 9.2.7 on a Feather nRF52840 Express.
Code/REPL
import asyncio
import time
import _bleio
import neopixel
import os
import board
import busio
import digitalio
import gc
import supervisor
from adafruit_ble import BLERadio
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
mac_address = 0
sw_version = "v1_2_9"
def parse_uname_output(uname_output):
return {'version': uname_output[3] if len(uname_output) > 3 else None}
# uname_output-take only version
uname_output = os.uname()
fw_version = parse_uname_output(uname_output)
def get_final_string():
global mac_address
mac_address = str(_bleio.adapter.address).replace("<Address ", "").replace(">", "")
# print(f"[sensera app reads]: {mac_address}")
easyg_device_name = "EasyG" + "".join(mac_address.split(":")[-4:])
print("EasyG Name",easyg_device_name)
return easyg_device_name
colors = {
"white" :(255, 255, 255), # white
"off" :(0,0,0),
"red" :(255,0,0),
"green" :(0, 255, 0),
"yellow" :(255, 255, 0),
"orange" :(255,165,0),
"blue" :(0, 0, 255)
}
pixels = neopixel.NeoPixel(board.NEOPIXEL,1,brightness=0.2)
ble = BLERadio()
ble.name = get_final_string()
advertisement = ProvideServicesAdvertisement()
easystatus = {
"easystatus": {
1: "TBD", #Heart_rate_monitor
2: 3, #Vibration_pattern
3: 2, #Suction_intensity
4: 3, #Vibration_intensity
5: 0, #External_target_lubrication
6: 0, #Internal_target_lubrication
7: 25.0, #temperature_external_target
8: 25.3, #temperature_internal_target
9: 25, #External_heater_T
10: 25, #Internal_heater_T
11: 0, #Pressure_sensor_L
12: 0, #Pressure_sensor_R
13: mac_address,#MAC
14: False, #Sensera_Status
15: None, #battery_level
16: None #charge_status
}
}
easystatus1 = {
"easystatus1": {
17: fw_version,
18: sw_version,
19: None, #wifi_version()
20: "internal", #choosen_pump: "internal"/"external"/"both"
21: 0, #power_button_count (1-8)
22: 0, #drop_button_count (1/0)
23: 0, #touch_pin1.raw_value
24: 0, #touch_pin2.raw_value
25: 0, #gyro
26: 0, #Accelerometer
27: 0, #System_Current
28: 0, # touch1_average
29: 0, # touch2_average
30: 0 # current_avg_cap
}
}
if ble.advertising:
print("Auto-advertising detected. Stopping it...")
ble.stop_advertising()
def log_event(message):
try:
with open("/log.txt", "a") as f:
timestamp = time.monotonic()
f.write(f"[{timestamp:.1f}] {message}\n")
except Exception as e:
print(f"Failed to write to log: {e}")
async def ble_handler():
toggle_debug = True
while True:
log_event("ble_handler: Top of loop")
gc.collect()
print("Free mem:", gc.mem_free(), "Allocated:", gc.mem_alloc())
if not ble.connected and not ble.advertising:
ble.stop_advertising()
print("stop Advertising...")
ble.start_advertising(advertisement)
print("start Advertising...")
#await sensera_debug_log("start Advertising")
if ble.connected:
conn = ble.connections[0]
print("Connected to central!", conn)
while conn.connected:
#device_cloud_commands = senserainfo.settings
#senserainfo.easygstatus = easystatus
#senserainfo.easygstatus1 = easystatus1
log_event("keep alive ble_handler device conected")
print("keep alive ble_handler device conected")
if toggle_debug :
pixels[0] = colors["orange"]
print("orange on")
else :
pixels[0] = colors["off"]
print("orange off")
toggle_debug = not toggle_debug
await asyncio.sleep(0.5) # Avoid busy-waiting
print("Connection lost!")
#await sensera_debug_log("Connection lost")
ble.stop_advertising()
if toggle_debug :
pixels[0] = colors["green"]
print("green on")
else :
pixels[0] = colors["off"]
print("orange off")
toggle_debug = not toggle_debug
log_event("keep alive ble_handler device not connected")
print("keep alive ble_handler device not connected")
await asyncio.sleep(2)
async def main():
ble_task = asyncio.create_task(ble_handler())
tasks = [ble_task]
try:
await asyncio.gather(*tasks)
except Exception as e:
print("Top-level crash:", e)
log_event(f"Top-level exception: {e}")
while True:
pixels[0] = colors["red"]
time.sleep(0.5)
pixels[0] = colors["off"]
time.sleep(0.2)
if __name__ == "__main__":
reason = supervisor.runtime.run_reason
log_event(f"Run reason: {reason}")
log_event("System booted. Running main.")
pixels[0] = colors["yellow"]
time.sleep(0.5)
pixels[0] = colors["off"]
time.sleep(0.2)
try:
asyncio.run(main())
except Exception as e:
log_event(f"asyncio.run crash: {e}")
Behavior
Your code.py uses BLE only for advertising
The Glider app connects, and you can:
Create folders
Write files
After each file/folder operation (when running on battery, not USB), the device:
Performs: Run reason: supervisor.RunReason.AUTO_RELOAD
On reconnect (reopen app), the written data appears and is correct
Description
Your code.py uses BLE only for advertising
The Glider app connects, and you can:
Create folders
Write files
After each file/folder operation (when running on battery, not USB), the device:
Performs: Run reason: supervisor.RunReason.AUTO_RELOAD
On reconnect (reopen app), the written data appears and is correct
Additional information
No response