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 1 年間 前
backend ebb6fca22c added a script for detecting when rd200.py is failing 1 年間 前
docs 06f983da10 initial 3 年 前
frontend 660c85c7d2 add notes and save from two months ago, shelving project for a bit 1 年間 前
test-scripts 16af4c1017 explains various prototypes 3 年 前
tools abb110924c import repo "radon-stuff" 2 年 前
.gitignore 5b5657c454 add locations database information 3 年 前
README.md 22cff4d881 attempts to fix a problem in the bluez org software, avoids a call to code that I think does not work 2 年 前

README.md

notes

  • grab a raspberry pi 1 b+ from the rpi bin
  • download debian image for this old rpi
  • boot then adduser
  • apt install sudo vim tmux git rsync usbutils bluetooth bluez bluez-tools rfkill

troubleshooting

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]

programming

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

troubleshooting

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:

on rpi B+,2B,3B ports 2,3,4,5 are ganged so even if bluetooth is plugged into port 4 you need to hit port 2

action 2 is cylcle power, port 1 is ethernet/wifi, on pi 3b+ ports are different

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

handle org.bluez.Error.InProgress

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

install PyGObject bindings

sudo apt install python3-gi ```

BLE info

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.

RadonEye BLE interface

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.

some deception

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.

Generic Access

attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34

Generic Attribute

attr handle: 0x0008, end grp handle: 0x0008 uuid: 00001801-0000-1000-8000-00805f9b34

LED Button Service

attr handle: 0x0009, end grp handle: 0x0011 uuid: 00001523-1212-efde-1523-785feabcd1

Device Information

attr handle: 0x0012, end grp handle: 0xffff uuid: 0000180a-0000-1000-8000-00805f9b34

LED Button Service (LBS) (official BLE documentation)

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.

Service UUID

The 128-bit vendor specific service UUID is 00001523-1212-EFDE-1523-785FEABCD123

Characteristics

This service has to characteristics

Button Characteristic 00001524-1212-EFDE-1523-785FEABCD123

Notify

Enable notifications for the Button Characteristic to receive button data from the application.

Read

Read button data from the application

Button Characteristic 00001525-1212-EFDE-1523-785FEABCD123

Write

Write data to theLED Characteristic to change the LED state