In 2018, Basalsure was originally built on Raspbian version 9 (stretch) and it was still in use in May of 2022. At that time, I realized how out of date version 9 of Raspbian (now commonly referred to as Raspberry Pi OS) had become -- the newest version of Raspberry Pi OS was version 11 (bullseye). And so, I decided to have a go at installing Basalsure onto the newest release, RPiOS v11. This page documents the procedure that I used.
It turns out that this documentation is also a great, step-by-step tutorial for a newcomer to use to install RPiOS and Basalsure.
$ cat /etc/os-release /boot/issue.txt | egrep 'PRETTY_NAME=|reference'
PRETTY_NAME="Raspbian GNU/Linux 9 (stretch)"
Raspberry Pi reference 2017-09-07
$ cat /etc/os-release /boot/issue.txt | egrep 'PRETTY_NAME=|reference'
PRETTY_NAME="Raspbian GNU/Linux 11 (bullseye)"
Raspberry Pi reference 2022-04-04
From https://www.raspberrypi.com/software/ I downloaded and installed the Raspberry Pi Imager for Windows. Using it, I chose "Raspberry Pi OS Lite, 32-bit, Debian version: 11 (bullseye)" and, using the settings button on the bottom right, set the hostname, WiFi information, enabled ssh, and setup an account for myself. I then "burned" that image onto a 4G SD card that I had laying around, popped it into the RPi Zero W in my basalsure2 box, in within a couple of minutes it was on my WiFi network and I could ssh into it. Easy peasy!
A 4GB SD card is plenty large enough for a Basalsure device and, though small by today's standards, is nice in the sense that burning or cloning them is far faster than with larger cards. My production, basalsure1 box has been in constant use for over four years now. It uses a high-end, 32GB Samsung SD card, but it needs nowhere near that much space:
basalsure1:~ $ df -h|grep -B1 /root
Filesystem Size Used Avail Use% Mounted on
/dev/root 30G 1.6G 27G 6% /
And this is how basalsure2's disk space looks immediately after booting it up with Raspberry Pi OS Lite v11:
basalsure2:~ $ df -h|grep -B1 /root
Filesystem Size Used Avail Use% Mounted on
/dev/root 3.4G 1.5G 1.8G 45% /
While a large size is not important, getting a modern, high-speed SD card is probably worthwhile. There is a marked difference in the speed of the old (slow) 4GB SD card that I used to build the new basalsure2 (this guide) verses the really nice SD card that basalsure1 has.
I utterly despise the vim defaults that try to do "smart" mouse things (like move the cursor to where the mouse was clicked). That behaviour makes everything that I do below harder to do, so I first fix my ~/.vimrc (and /root/.vimrc). This is what I like to place into those files:
" TIP: run :scriptnames to see what scripts were loaded by vim
if filereadable("/usr/share/vim/vim82/defaults.vim")
source /usr/share/vim/vim82/defaults.vim
endif
set mouse-=a
NOTE: Skip this step if you did not add a RTC to you RPi. I followed the software configuration procedures that I documented in Adding a "Real Time Clock" (RTC) module to get the RTC working. Step 4 was slightly different as /lib/udev/hwclock-set is a much smaller and simpler script in RPiOSv11 than in v9. There was one fewer lines to comment out.
NTP is managed by systemd's timesyncd and settings are in the file /etc/systemd/timesyncd.conf. For me, settings look like this, and of note, IP address 10.10.10.1 is the host inside of my home network that runs a NTP server:
[Time]
NTP=10.10.10.1 0.ubuntu.pool.ntp.org 1.ubuntu.pool.ntp.org 2.ubuntu.pool.ntp.org 3.ubuntu.pool.ntp.org
FallbackNTP=0.pool.ntp.org 1.pool.ntp.org 0.fr.pool.ntp.org
After making those changes, run "systemctl restart systemd-timesyncd" followed by "systemctl status systemd-timesyncd" and "timedatectl" to make sure that everything is still working OK.
I have found ssmtp to be the best way to send email out from my RPis, and s-nail to be the best command-line mail client. Install them via:
The ssmtp configuration file is /etc/ssmtp/ssmtp.conf and I use my personal gmail account to send emails. On the gmail side, you'll need to create an app password to use, that will be different than your regular password and can be restricted to just email.
There are ssmtp setup guides online, but in general, these are the things you'll need to set in the /etc/ssmtp/ssmtp.conf file:
root=somebody@gmail.com
mailhub=smtp.gmail.com:587
hostname=basalsureX
UseSTARTTLS=Yes
UseTLS=Yes
AuthUser=somebody@gmail.com
AuthPass=XYXYX-app-password-XYXYX
Next, we need to add s-nail as a system alternative for /usr/bin/mail (this really should be done by default, but it's not)...
root@basalsure2:# update-alternatives --install /usr/bin/mail mail /usr/bin/s-nail 50
update-alternatives: using /usr/bin/s-nail to provide /usr/bin/mail (mail) in auto mode
# mail --version
s-nail v14.9.22, 2021-02-24 (built for Linux)
To test your outbound mail flow, to something like this, which should successfuly send an email to your.email@gmail.com:
root@basalsure2:# echo "test message" | mail -s 'test from basalsure device' your.email@gmail.com
I have a number of OS-level items that are common to how I personally run my Linux computers that aren't really relevant to anyone else. I chose not to document them here, but I did want to list them, primarily for my benefit later, when I do this again...
All of these live in my home dir's bin dir. They all run from root's crontab file, with the exception of ssh_vpn.sh, which is a service managed by systemd (/etc/systemd/system/sshvpn.service).
I have a custom and very large /etc/wpa_supplicant/wpa_supplicant.conf file that allows my basalsure boxes to hop onto a number of WiFi networks, including my mobile phone's hotspot. The Raspberry Pi Imager only installs one network and so I need to move my wpa_supplicant.conf file into place.
Download the newest release to the RPi, from the Code area of this site: https://sourceforge.net/p/basalsure/code/HEAD/tree/releases/
On the RPi itself, you likely can use wget to download it; something similar to this:
user@rpi:~ $ wget https://sourceforge.net/p/basalsure/code/HEAD/tree/releases/basalsure-1.2.6-1.deb
Once downloaded, use apt-get to install it, like this:
user@rpi:~ $ sudo apt-get install ./basalsure-1.2.6-1.deb
You can use systemctl to have systemd show you the status of basalsure, as well as stop and start it (and restart it), like this:
hightowe@basalsure2:~ $ sudo systemctl stop basalsure
root@basalsure2:/# systemctl status basalsure
● basalsure.service - Basalsure
Loaded: loaded (/etc/systemd/system/basalsure.service; enabled; vendor pre>
Active: inactive (dead)
root@basalsure2:/# systemctl start basalsure
root@basalsure2:/# systemctl status basalsure
● basalsure.service - Basalsure
Loaded: loaded (/etc/systemd/system/basalsure.service; enabled; vendor pre>
Active: active (running) since Sat 2022-05-14 10:55:11 EDT; 6s ago
Main PID: 3725 (basalsure.py)
Tasks: 1 (limit: 415)
CPU: 5.911s
CGroup: /system.slice/basalsure.service
└─3725 /usr/bin/python /sbin/basalsure.py
The installation will have placed the basalsure program at /sbin/basalsure.py and the configuration file at /etc/basalsure_conf.yml with sub-configs in files underneath /etc/basalsure_conf.d/. Your best bet for getting things configured correctly is likely to stop basalsure from running through systemd and then run /sbin/basalsure.py yourself, as root, and work your way through any problems and configuration changes that you need to make.
In /etc/basalsure_conf.yml, you will need to define the input_pins and output_pins per the way that you wired up your hardware. For me, on the 2023 build, those values are:
input_pins: [ 11, 15, 19 ]
output_pins: [ 13, ]
You will also want to label the pins so that you can refer to the pins by those labels elsewhere in the configurations. For me, on the 2023 build, those values are:
labels_pins:
15: "02:00am"
11: "09:45pm"
19: "11:30pm"
13: "buzzer"
You will want to check the buzzer-config section to verify the output_pin.
You will want to review and configure any of the notification method sections that you intend to use; sections like: smtp, twilio, and pushover.
At the end of the file, you will see that other configuration files are included and we will deal with each of those next.
The file /etc/basalsure_conf.d/basalsure_conf-alsa.yml is where the Advanced Linux Sound Architecture (ALSA) configuration is done, to facilitate the USB speaker support that basalsure has. Within that file, relatively close to the top, you will need to verify or set aplay_device and amixer_cardn which define the PCM device to play sound through and the "sound card number" that the mixer uses to control its volume.
For me, on the 2023 build, those values are as follows (and they should be the same for you if you purchased the same USB speaker):
aplay_device: 'default:CARD=UACDemoV10'
amixer_cardn: "UACDemoV10"
If you need to change those values, then you'll need to determine what they need to be and "aplay -l" is the primary command to use.
hightowe@basalsure2:~ $ aplay -l
**** List of PLAYBACK Hardware Devices ****
card 0: b1 [bcm2835 HDMI 1], device 0: bcm2835 HDMI 1 [bcm2835 HDMI 1]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 1: Headphones [bcm2835 Headphones], device 0: bcm2835 Headphones [bcm2835 Headphones]
Subdevices: 4/4
Subdevice #0: subdevice #0
Subdevice #1: subdevice #1
Subdevice #2: subdevice #2
Subdevice #3: subdevice #3
card 2: UACDemoV10 [UACDemoV1.0], device 0: USB Audio [USB Audio]
Subdevices: 1/1
Subdevice #0: subdevice #0
In the aplay -l output above:
1. card 0, named b1, is the RPi's HDMI audio output
2. card 1, named Headphones, the the RPi's headphone jack
3. card 2, named UACDemoV10, is the USB speaker that is plugged in.
ALSA controls volume at the card level, and in our case it is card 2 that we want to control. Sound is played at the PCM (Pulse Code Modulation) level and every sound card will have several PCMs, and all cards should have a default PCM which should usually be fine to use. Here is the list of PCMs on the USB audio speaker shown above:
hightowe@basalsure2:~ $ aplay -L|grep CARD=UACDemoV10
hw:CARD=UACDemoV10,DEV=0
plughw:CARD=UACDemoV10,DEV=0
default:CARD=UACDemoV10
sysdefault:CARD=UACDemoV10
front:CARD=UACDemoV10,DEV=0
surround21:CARD=UACDemoV10,DEV=0
surround40:CARD=UACDemoV10,DEV=0
surround41:CARD=UACDemoV10,DEV=0
surround50:CARD=UACDemoV10,DEV=0
surround51:CARD=UACDemoV10,DEV=0
surround71:CARD=UACDemoV10,DEV=0
iec958:CARD=UACDemoV10,DEV=0
dmix:CARD=UACDemoV10,DEV=0
From that list, you can see that I chose default:CARD=UACDemoV10 for my aplay_device setting. I could have set amixer_cardn to the number 2, but as of basalsure version 1.2.6, you can specify the card name and the basalsure software will find the card number to use, and so that is what I did.
A little further down the file you sill see a section named sounds that deinfes all of the sounds that basalsure is configured to play.
In this example:
0200_placed:
wav: '/usr/share/sounds/basalsure/0200_placed.wav'
volume: '85%'
0200_taken:
wav: '/usr/share/sounds/basalsure/0200_taken.wav'
volume: '65%'
Two sounds are defined, 0200_placed and 0200_taken, and each one points to its respective *.wav file and has the volume set. In this case, we have basalsure speak more quietly at 2am when I remove that syringe than at the time that it is placed, many hours prior.
All of the spoken voices were made at this great site using "Salli, Female" - https://www.texttovoice.online/
This config file defines all of the condition monitoring that the basalsure state machine does. It is a complex file, but if you take your time and review it carefully it is not too difficult.
We can have one or more monitoring-timeframe-options sections that define a set of timeframes and a label each one. In the file that ships with the basalsure code, two monitoring-timeframe-options are defined: alarm-433MHz-first and alarm-buzzer-first. As those names imply, the first configuration fires the 433 MHz nurse alarm first and the other fires the internal buzzer (and ALSA sounds) first. If not responded to, those configurations escalate to the next steps.
The monitoring-timeframes setting will reference one of the monitoring-timeframe-options defined before it, and is the set that will be used.
The time-spans that are defined (such as '23:40-23:59|*|*|*') are in the format of the timespan module that basalsure uses: https://github.com/jart/timespan
The file next defines an array of condition-monitors. Each condition monitor must have a unique name (basalsure will warn you if not), and each defines the timeframe in which it is to apply, the alarm_states to look for, and then the alarms to trigger if those alarm_states are true in that timeframe.
Let's walk through a condition monitor definition:
# Buzzer escalators for basal times
- name: "9:45pm Levemir Buzzer"
timeframe: '0945pm-buzzer'
alarm_states:
- { input: "09:45pm", state: 0 } # syringe is in place
alarms:
- type: "buzzer"
time: -1 # Turn buzzer on indefinitely
- type: "alsa"
sound: "call_to_arms"
time: 12
realarm_frequency: 12 # secs
This condition monitor:
This config file defines all of the state change monitoring/actions that the basalsure state machine does. It is a complex file, but if you take your time and review it carefully it is not too difficult.
The file defines an array of state-change-checks that are very similar in style to the condition-monitors that we covered above. Each state change check must have a unique name (basalsure will warn you if not), and each defines the timeframe in which it is to apply, the input_that_changed that would trigger this check to be analyzed, the alarm_states to look for, and then the alarms to trigger if those alarm_states are true when the relevant input changed in that timeframe.
Let's walk through a state change check definition:
# Quick beep for syringe insertion
- name: "9:45pm syringe inserted"
timeframe:
- '*|*|*|*'
input_that_changed: "09:45pm"
alarm_states:
- { input: "09:45pm", state: 0 } # syringe is in place
alarms:
- type: "alsa"
sound: "0945_placed"
- type: "buzzer"
time: 0.066
This state change check:
That's it. You should now be in business with a working Basalsure RPi!
Most people can skip this section, unless you plan to have more than one Basalsure device, or you would like to make a backup of your SD card for safe keeping.
All of the work that was documented above was done on my basalsure2 box (backup/dev/test) and it took me about four hours. To quickly move the work into production on basalsure1, I cloned the SD card and then needed to make these changes to properly convert it from basalsure2 to basalsure1:
Wiki: 2018 Build
Wiki: Adding a "Real Time Clock" (RTC) module
Wiki: Software Configuration