Poll the rd200 over ble and get the most recent radon samples. Device is made by EcoSense and has pretty bad user interface, this replaces that.
kyle 660c85c7d2 add notes and save from two months ago, shelving project for a bit | vor 1 Jahr | |
---|---|---|
backend | vor 2 Jahren | |
docs | vor 3 Jahren | |
frontend | vor 1 Jahr | |
test-scripts | vor 3 Jahren | |
tools | vor 3 Jahren | |
.gitignore | vor 3 Jahren | |
README.md | vor 2 Jahren |
apt install sudo vim tmux git rsync usbutils bluetooth bluez bluez-tools rfkill
List of linux connected bluetooth interfaces
# hcitool dev
Devices:
hci0 00:1A:7D:DA:71:15
# sudo hcitool -i hci0 lescan
LE Scan ...
CF:CD:27:79:55:6B FR:R20:SN1735
C9:31:F4:9A:B1:86 (unknown)
CF:CD:27:79:55:6B (unknown)
CF:CD:27:79:55:6B FR:R20:SN1735
CF:CD:27:79:55:6B (unknown)
CF:CD:27:79:55:6B FR:R20:SN1735
... [ctrl] + [c]
# sudo gatttool -t random -b CF:CD:27:79:55:6B -I
D:27:79:55:6B][LE]> connect
Attempting to connect to CF:CD:27:79:55:6B
Error: connect to CF:CD:27:79:55:6B: Device or resource busy (16)
# sudo hciconfig hci0 reset
# sudo gatttool -t random -b CF:CD:27:79:55:6B -I
[CF:CD:27:79:55:6B][LE]> connect
Attempting to connect to CF:CD:27:79:55:6B
Connection successful
[CF:CD:27:79:55:6B][LE]> primary
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0009, end grp handle: 0x0011 uuid: 00001523-1212-efde-1523-785feabcd123
attr handle: 0x0012, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34fb
[CF:CD:27:79:55:6B][LE]> char-desc
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0007, uuid: 00002a04-0000-1000-8000-00805f9b34fb
handle: 0x0008, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0009, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x000a, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000b, uuid: 00001524-1212-efde-1523-785feabcd123
handle: 0x000c, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x000d, uuid: 00001525-1212-efde-1523-785feabcd123
handle: 0x000e, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x000f, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0010, uuid: 00001526-1212-efde-1523-785feabcd123
handle: 0x0011, uuid: 00002902-0000-1000-8000-00805f9b34fb
handle: 0x0012, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0013, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0014, uuid: 00002a29-0000-1000-8000-00805f9b34fb
[CF:CD:27:79:55:6B][LE]>
... [ctrl] + [d]
sudo apt install python3 python3-pip build-essential libbluetooth-dev
# pybluez requires libbluetooth-dev
: pip install pybluez
# pybluez does not support ble, use BLE_GATT instead
pip install BLE_GATT
# BLE_GATT has a problem with notifications, check out either bluepy or bleak
2021 December 2 I found that sometimes, after a boot, the service will be running, bluetooth is displayed via lsusb, but bluetoothctl run by the service sees no devices. I updated the service to run after bluetooth is available and have not seen the issue since. This DOES NOT show that the problem is fixed, as at the time of discovery was after bluetooth had initialized. Rather than research this issue a stab in the dark is what we have. 2021 December 14 After a boot last night we found that this did not work, again lsusb shows the device, bluetoothctl does not show devices, either run manually or from the radon-eye services. This means that the service either does not run after bluetooth or waiting does not work. the problem looks like this
$ lsusb
Bus 001 Device 005: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
$ bluetoothctl
Agent registered
[bluetooth]# scan on
No default controller available
I think I am going to test moving the systemd After
and new Requires
to the radon-eye@.service
and see if that helps
Other info I collected, bluetoothd
was active running process, rfkill list all
shows all bluetooth non-blocked
OKay found something
$ hciconfig list
hci0: Type: Primary Bus: USB
BD Address: 00:1A:7D:DA:71:15 ACL MTU: 310:10 SCO MTU: 64:8
DOWN
RX bytes:351 acl:0 sco:0 events:11 errors:0
TX bytes:33 acl:0 sco:0 commands:11 errors:0
looks like the bluetooth adapter hci0
is shown as DOWN
looking at dmesg shows these logs
Bluetooth: hci0: unexpected event for opcode 0x0000
Bluetooth: hci0: command 0x0c14 tx timeout
Bluetooth: hci0: command 0x0c25 tx timeout
Bluetooth: hci0: command 0x0c38 tx timeout
Bluetooth: hci0: unexpected event for opcode 0x0c14
using hciconfig hci0 up
does make device UP
but bluetoothctl still does not see devices,
another recommendation is:
$ sudo btmgmt power off
Set Powered for hci0 failed with status 0x11 (Invalid Index)
$ sudo btmgmt power on
Set Powered for hci0 failed with status 0x11 (Invalid Index)
I got nowhere, did a reboot
And another completely unrelated issue just popped up, yay!
$ bluetoothctl
Agent registered
[bluetooth]# scan on
Failed to start discovery: org.bluez.Error.NotReady
for this issue I just issued a power off, then a power on, this helped this issue was started around the time I added the check for bluetoothctl reporting no default controller and me adding a subprocess.popen.communicate call that might have resulted in
Dec 14 22:39:46 solar-aquarium python3[1336]: tried to closed subprocess stdin but got error: argument should be integer or bytes-like object, not 'str'
2021 Dec 19th
More problems, last night I tried to add WiFi accesspoint via USB to the rpi running this project. It was connected to two radoneye devices but around 18:00 it stopped communicating with both of them. I did spill some tea in the living room and Emma sa moving stuff around, but I think that happened at 23:00. At 18:00 I think wesley arrived and we had either ordered pizza or were waiting for it to be made so I do not think I was doing anything. Anyways, running bluetoothctl
right now with scan on
does nothing.
`$ hciconfig list
hci0: Type: Primary Bus: USB
BD Address: 00:1A:7D:DA:71:15 ACL MTU: 310:10 SCO MTU: 64:8
UP RUNNING INQUIRY
RX bytes:13550 acl:101 sco:0 events:1405 errors:0
TX bytes:11588 acl:101 sco:0 commands:1212 errors:0
$ hcitool -i hci0 lescan LE Scan ... CF:CD:27:79:55:6B FR:R20:SN1735 CF:CD:27:79:55:6B (unknown) Disable scan failed: Input/output error
Okay, this is weird, after issuing the `hcitool` low energy scan, it looks like bluetoothctl started working. I am starting to suspect that even though `hcitool` and `hciconfig` are not recommended that they handle certain failures where `dbus` and `bluetoothctl` do not.
The `rd200.py` process was logging the same error while the above was happeneing
Dec 19 14:56:00 solar-aquarium python3[461]: device not found, retrying in a second... Dec 19 14:56:00 solar-aquarium python3[461]: device not found, retrying in a second... Dec 19 14:56:00 solar-aquarium python3[461]: device not found, retrying in a second... Dec 19 14:56:00 solar-aquarium python3[461]: device not found, retrying in a second...
2021 December 24
rebooted last night, this morning bluetoothctl and hcitool lescan both show no device found, dmesg shows errors:
Bluetooth: HCI device and connection manager initialized Bluetooth: HCI socket layer initialized Bluetooth: L2CAP socket layer initialized Bluetooth: SCO socket layer initialized usbcore: registered new interface driver btusb Bluetooth: hci0: unexpected event for opcode 0x0000 Bluetooth: hci0: command 0x1001 tx timeout Bluetooth: BNEP (Ethernet Emulation) ver 1.3 Bluetooth: BNEP filters: protocol multicast Bluetooth: hci0: CSR: Local version failed (-110) Bluetooth: BNEP socket layer initialized
decided to try to automate unplugging and replugging the bluetooth usb device using mvp/uhubctl on rpi.
install pre-packaged, `apt install uhubctl` then modify permissions on the usb hub using `udev` rules. example udev rule is stored in `backend/52-usb.rules`. It allows anyone in the `dialout` group to power cycle the usb hub. `sudo usermod -aG dialout radon`, copy the script over to `/etc/udev/rules.d/` and reload udev rules, `sudo udevadm trigger --attr-match=subsystem=usb`
at first I did not get permissons to work I was going to try to reboot, but before I did, testing command worked to fix bluetooth:
sudo uhubctl --location=1-1 --port=2 --action=2
reboot did get the group thing working, so now it is just a thing to decide when to issue the above command, it seems somewhat risky with two rd200.py running
2022 Jan 19th
a couple more issues
we can get into a state
[bluetooth]# scan on Failed to start discovery: org.bluez.Error.InProgress [bluetooth]# scan off Failed to stop discovery: org.bluez.Error.Failed [bluetooth]# exit
I was working on this issue and found that one of the rd200.py processes looks like it hung after restarting
`rd200.py` does not detect this issue
a solution that seemed to work was just running `bluetoothctl power off` then `bluetoothctl power on` this is a bit of an issue as doing this in two processes is going to be an issue. I am not even sure why this issue cropped up.
do something like:
import time import os import errno
try:
# use a file as a lock (exclusive create)
f=open('someFile', mode='x')
ble_ctl(addr:str, retry = 50, powerCycle = True)
# delete the file
f.close()
os.remove('someFile')
except Exception as e:
if(errno.EEXIST == e.errno):
# make sure the file lock is not broken
try:
old=os.stat('someFile')
if(60 < (int(time.time()) - int(old.st_mtime))):
print("someFile lock was borked, cleaning up")
os.remove('someFile')
except Exception as e2:
print("failed to cleanup borked someFile lock", e2)
else:
print("unexpected error while dealing with org.bluez.Error.InProgress", e)
2022 Feb 20
only the bedroom device was connected and the basement was not. strace on the process for the basement shows that it was doing a read write and select with, I think a 500ms timeout. It looked like it was looping and not doing anything. Log just shows a message about `failed to cleanup BLE_GATT objects because...` and nothing eles. I logged into the `bluetoothctl` interface and issued the `connect AA:BB:CC:DD:EE:FF` command and exited and the process went back to normal. I think there is an exception not being raised and causing the loop to fail. I should probably do something about this, but I cannot really find where in the code the problem is occurring.
2022 Jun 03
Looks like it stopped, uptime is 3 days, programs are running but cannot get out of an issue where:
[bluetooth]# connect C2:58:00:9A:26:29 Attempting to connect to C2:58:00:9A:26:29 Failed to connect: org.bluez.Error.Failed [bluetooth]# scan off Failed to stop discovery: org.bluez.Error.Failed
`bluetoothctl` shows activity, neighbors samsung TV, etc, but interacting, using connect, etc just gives `org.bluez.Error.Failed` messages.
I issued the `bluetoothctl power off`, waited a couple seconds, `bluetoothctl power on`
This did something but did not fix bluetooth, i noticed the other process was repeating every half second in strace:
_newselect(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=500000}) = 0 (Timeout) eventfd2(0, EFD_CLOEXEC|EFD_NONBLOCK) = 7 write(7, "\1\0\0\0\0\0\0\0", 8) = 8 write(6, "\1\0\0\0\0\0\0\0", 8) = 8 futex(0x1ac6c70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x1ac6b9c, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x1ac303c, FUTEX_WAKE_PRIVATE, 1) = 1 poll([{fd=7, events=POLLIN}], 1, 0) = 1 ([{fd=7, revents=POLLIN}]) read(7, "\2\0\0\0\0\0\0\0", 16) = 8 write(7, "\1\0\0\0\0\0\0\0", 8) = 8 futex(0x1ae8604, FUTEX_WAKE_PRIVATE, 2147483647) = 0 close(7) = 0 clock_gettime64(CLOCK_MONOTONIC, {tv_sec=328018, tv_nsec=340560669}) = 0 _newselect(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=500000}) = 0 (Timeout) eventfd2(0, EFD_CLOEXEC|EFD_NONBLOCK) = 7 write(7, "\1\0\0\0\0\0\0\0", 8) = 8 write(6, "\1\0\0\0\0\0\0\0", 8) = 8 futex(0x1ac6c70, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x1ac6b9c, FUTEX_WAKE_PRIVATE, 1) = 1 futex(0x1ac303c, FUTEX_WAKE_PRIVATE, 1) = 1 poll([{fd=7, events=POLLIN}], 1, -1) = 1 ([{fd=7, revents=POLLIN}]) read(7, "\1\0\0\0\0\0\0\0", 16) = 8 futex(0x1ae85f8, FUTEX_WAKE_PRIVATE, 1) = 1 poll([{fd=7, events=POLLIN}], 1, 0) = 1 ([{fd=7, revents=POLLIN}]) read(7, "\1\0\0\0\0\0\0\0", 16) = 8 write(7, "\1\0\0\0\0\0\0\0", 8) = 8 futex(0x1ae8604, FUTEX_WAKE_PRIVATE, 2147483647) = 0 close(7) = 0 clock_gettime64(CLOCK_MONOTONIC, {tv_sec=328018, tv_nsec=899447448}) = 0
## python BLE_GATT trouble - ModuleNotFoundError: No module named 'gi'
internet says it is PyGObject introspection, bindings to support GTK+ 3 and GNOME
sudo apt install python3-gi ```
UUID is 128-bit value representing a unique characteristic, for example, 00002A00-0000-1000-8000-00805F9B34FB
is the "Device Name Characteristic".
Address is a 6-octect MAC (48-bit) number unique to every device.
data from BLE is little endian
GATT is Generic Attribute Profile
BLE peripherals can only be connected to one central device at a time
Bluetooth base UUID address is 0000xxxx-0000-1000-8000-00805f9b34
, the Device Name Characteristic is sometimes shortened to just 0x2A00.
someone posted a dump of their work sniffing traffic on the official Android app and found that sending 0x50 to the characteristic 00001524-1212-efde-1523-785feabcd1
returns a 20 byte field back where the 3rd to 6th bytes are big-endian formatted IEEE754 representation of a floating point value of the Radon level in picocuries per liter -- the response is written to 00001525 ... characteristic.
The advertisement claims 30 readings per hour but then they mention that the first value is available after 10 minutes. It would seem that they take five readings and then update the display. The data on the display is the only externally accessible data so we are only going to see a maximum of six readings an hour. Nyquist sampling says that we have got to sample twice so we should be sampling twelve times an hour.
attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34
attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34
attr handle: 0x0009, end grp handle: 0x0011 uuid: 00001523-1212-efde-1523-785feabcd1
attr handle: 0x0012, end grp handle: 0xffff uuid: 0000180a
-0000-1000-8000-00805f9b34
The GATT LED Button Service (LBS) is a custom service that receives information about the state of an LED and sends notifications when a button changes its state.
The 128-bit vendor specific service UUID is 00001523-1212-EFDE-1523-785FEABCD123
This service has to characteristics
Enable notifications for the Button Characteristic to receive button data from the application.
Read button data from the application
Write data to theLED Characteristic to change the LED state