Python Code on Raspberry Pi¶
Overview¶
In order to establish a Bluetooth Low Energy (BLE) link to a Raspberry Pi or compatible Linux box, the BLEControlsPi app requires that the companion Python code provide free (MIT License) be installed and running on the Raspberry Pi.
An automated installer (bash file) is provided, which downloads the necessary pi unto your raspberry pi, installs the necessary dependencies and creates the systemD services required to run the code.
How to Install on the Raspberry Pi¶
Run the following commands in terminal window on the Raspberry Pi. For headless RPi - use SSH.
First, please ensure that your RPi is up to date by running these commands:
sudo apt update
sudo apt upgrade --yes
sudo reboot
Then, run the installer script with the curl command below, to set up btwifiset on your Pi.
curl -fL https://github.com/bluepieapps/blecontrolspi-python/releases/download/v1.1.0/bpablecontrolsinstall-v1.1.0.sh | bash
Installer will ask you:¶
Where you want to install the python code: the default is /usr/local/bluepieapps
it is recommended to just accept the default
Set the inactivity timeout: the default is 30 minutes
The code is run as a systemD service. if no data is excahnged between the iPhone/iPad and the Raspberry Pi, the service will shutdown after this inactivity timeout. This is recommended to shut down bluetooth BLE advertising when you do not need the code runnning.
Set an encryption password/key: the default is the current Raspberry Pi hostname.
controls values are encrypted using a key that is shared between the BLEControlsPi App on the iPhone/iPad and the Raspberry Pi. This is to prevent a third party from downloading the BLEControlsPi app and controlling your Raspberry Pi. It is recommended that you set something different then the hostname since the hostname is displayed in the app.
Note: a simple utility is provided (btpassword.py) which allows you to change the password on the Raspberry Pi after installation.
Enable the service to start on boot:
if you say yes to this, the service that runs the python code will start automatically after the Raspberry Pi boots up (see next section)
How to run the code:¶
The installer creates two services, located at /etc/systemd/system/:
- bpa-controls-channel.service: this is the main service which you start to run the necessary code
- bpa-bleconnectrouter.service: this is the underlying bluetooth connection and message router - you do not need to start this service directly.
If you selected to enable start on boot during the installation process, this service starts on every boot of the Raspberry Pi.
it is recommended to let the system start on boot - because it will shutdown automatically after 30 minutes (or what ever timeout you selected) if you do not use it.
If you said "N" (no), you will need to start the service manually on the Raspberry Pi, before you can use the BLEControlsApp on the iPhone/iPad.
note that even if you said Yes to start on boot - you may still need to restart the service if you allowed it to shut down due to inactivity.
To start the service manually - run:
sudo systemctl start bpa-controls-channel
To stop the service - run:
sudo systemctl stop bpa-controls-channel
To see if the services are running - run :
systemctl status bpa-controls-channel
systemctl status bpa-bleconnectrouter.service
You do not need to start
bpa-bleconnectrouter.servicebecause the starting the main servicebpa-controls-channelwill start it automatically.
Logging¶
By default, the systems logs many event in DEBUG level mode. You can change this in the code (to: INFO, CRITICAL) to get lighter logs. The logs are stored in syslog.
To see the logs:
journalctl -u bpa-bleconnectrouter -n 200 --no-pager
journalctl SYSLOG_IDENTIFIER=bpa-logger -n 200 --no-pager
Creating Handlers for your Controls¶
Each control you create in the app is given a unique control code. See Using Controls for a detailed explanation how controls work with the Raspberry Pi (RPi).
When you use a control, the control's unique identifier code and the control's value is sent to the RPi. In order to have some meaningful action on the RPi, you must define and register a handler (callback) for each control.
Handlers are defined in the class ActionController which is found in the installed file ActionController.py.
This file is found at /usr/local/bluepieapps/ directory (if you installed in the default location suggested by the installer)
Action Controller class:¶
The installed code has examples of handlers definition and registration for each type of control
When creating controls in the BLEControlsPi app, a control code is suggested. If you do not modify it, the python code installed will have an implementation for each of these codes - with the action to print the control's value to syslog. You can quickly get started by simply replacing the log statement by the action you want.
Creating a Handler for a specific control code is a two step process:
- Register a handler (callback) function for each control you have defined in your BLEControlsPi App on the phone/tablet.
- Add a definition (def...) for this handler will do when it receives a value from the phone/tablet
There are also a few specific handlers provided in this class not tied to a specific control (see below)
Register handlers:¶
You are provided with a reference to the Registrar class (self._registrar) which exposes various register methods - depending on the data type used for the control.
See the initial implementation of the function registerHandlers() for examples of how to register handlers for each control you have defined in your BLEControlsPi App.
You must call the appropriate registration method for each control type, as shown in the function registerHandlers().
For reference: Controls must register a callback handler using by the proper "type" of handler( string, bool, int, timestamp):
- Button -> register_event_handler
- Input Text, Color, picker -> register_string_handler
- Slider,Stepper -> register_int_handler
- Toggle -> register_bool_handler
- Date -> register_string_handler
Note: if you fail to use the correct type handler registration, ControlError is raised.
Once your have registered callback handlers for each control, write the code that handles what to do with the control's received value in the callback handler function you defined for that control.
Sending Data to iPhone/iPAd BLEControlsPi app:¶
There are two display controls (Gauge, Display Text) that only accepts data coming from the RPi. These do not need handlers since they never send idata to the RPi.
Also, some controls (see Using Controls) accept an initialization value.
typically, after a bluetooth connection is established, you would send the current value of the control if applicable, as it is on the RPi, so the control is effectively initialized on th iPhone/iPad
To send a value to a display control, or initialize a control on the phone/tablet, use:
- the convenience function
send(control_code, value)for an example of how this works - look at the provided
on-timer()function inActionControllerclass
Register Specialty convenience handlers provided:¶
-
register_timer_handler:
- this sets a periodic timer, which calls the handler you register.
- in the provide code, we define on_timer() handler which sends a counter value to the phone/tablet as well as the CPU Temperature.
-
register_on_connected:
- run specific code when the phone/tablets connect bluetooth.
- runs only once per connection
- useful for example to send initial values to controls on the phone/tablet when it connects to the raspberry pi.
- the example provided sends the CPU Temperature
-
register_on_ble_quit:
- ble router service will exit after a settable inactivity timeout, which causes this process to quit as well.
- run a synchronous callback, to perform cleanup before, ActionController process exits.
in the code provided, we have implemented the registration of a callback self.on_shutdown, but the handler itself does nothing.