BLE Water Level Sensor Communication
Overview
The SMARTA L v2 base station communicates with a separate, external BLE-enabled water level sensor to obtain tank level readings. The base station acts as a BLE client (or central device) that actively scans for and processes advertising data from the designated BLE sensor.
BLE Sensor Interaction Model
- Sensor Advertising: The external water level sensor periodically broadcasts its data within BLE advertising packets. This data typically includes the raw sensor reading (e.g., pressure value) and potentially other status information.
- Base Station Scanning: The base station (
main.ino
-initialize_ble_client()
) continuously or periodically performs BLE scans (pBLEScan->start()
) to discover nearby BLE devices. - Sensor Identification (Pairing/Targeting):
- The base station is configured with the MAC address of the specific water level sensor it should listen to. This MAC address is stored in preferences as
adv_id
(getSettingValues()
inmain.ino
). - The
adv_id
can be set/updated via the Sensor MAC Characteristic (f3b5a8d4-2b6e-4a1b-8b1e-3c4d5e6f7a96
). Writing a new MAC address to this characteristic updates the preference and typically triggers a device restart to apply the change (SensorMacCallbacks::onWrite()
inmain.ino
).
- The base station is configured with the MAC address of the specific water level sensor it should listen to. This MAC address is stored in preferences as
- Data Reception and Processing:
- During a scan, if the base station detects an advertising packet from the configured sensor's MAC address (
adv_id
), it extracts the service data from the advertisement (scanCompleteCallback()
inmain.ino
). - The
scanCompleteCallback()
function is triggered when a scan is complete or when a device matching certain criteria is found (if filters were applied, though in this case, it seems to iterate through all results). - It specifically checks
if (device_id == adv_id)
to process data only from the paired sensor. - The raw service data (
ble_service_data = device.getServiceData()
) is then parsed. The current implementation appears to take the first few bytes of the service data, subtracts one from each byte's decimal value, and concatenates them to formblePayloadString
. It also creates a binary string representation inblePayloadBytes
. - The RSSI of the sensor's advertisement is also captured (
lastSensorRSSI = device.getRSSI()
).
- During a scan, if the base station detects an advertising packet from the configured sensor's MAC address (
- Data Utilization:
- The parsed
blePayloadString
(representing the raw sensor value) is then used in conjunction with calibration values (e.g.,raw_zero
,height
,sensorType
- also configurable via BLE, seePumpControlCallbacks::onWrite()
inmain.ino
forcal:
command) to calculate the actual tank level (tank_level_condition_get()
inmain.ino
). - This calculated tank level and other sensor-related data (like
raw_known
,level_known
) are then made available via the Pump Data Characteristic and transmitted via MQTT.
- The parsed
Key Code References
- BLE Scanning Initialization:
initialize_ble_client()
inmain.ino
sets up the BLE scanner and callbacks. - Scan Completion and Data Parsing:
scanCompleteCallback(BLEScanResults results)
inmain.ino
handles the results of a BLE scan, identifies the target sensor by its MAC address (adv_id
), and extracts/parses the advertising service data. - Sensor MAC Configuration: The
adv_id
is retrieved from preferences (getSettingValues()
inmain.ino
) and can be updated via theSENSOR_MAC_UUID
characteristic (SensorMacCallbacks
inmain.ino
). - Sensor Data Storage: Variables like
ble_service_data
,blePayloadString
,lastSensorRSSI
store the incoming data from the sensor. - Calibration Data:
sensorType
,raw_zero
,height
are used to convert raw sensor readings to meaningful levels. These are configurable. - Tank Level Calculation:
tank_level_condition_get()
inmain.ino
likely uses the parsed sensor data and calibration parameters.
Pairing and Sensor Management
- The "pairing" is essentially the act of configuring the base station with the correct MAC address (
adv_id
) of the BLE sensor. - If the sensor needs to be replaced or changed, its new MAC address must be written to the base station via the
Sensor MAC Characteristic
. - The OLED display might show "NO SENSOR DETECTED" (
noSensorDetectedDisplay()
inOLED.ino
) if no valid data is received from the configured sensor after a certain period or ifsensorValid
is false. - A successful pairing/update of the sensor MAC is usually indicated on the OLED (
sensorPairedDisplay()
inOLED.ino
).
Data Flow Summary
- External BLE Sensor advertises its readings.
- Base Station scans for BLE advertisements.
- Base Station identifies the target sensor using the stored
adv_id
(MAC address). - Base Station extracts and parses the service data from the sensor's advertisement.
- The raw data is converted to a tank level using calibration parameters.
- The tank level and other system data are then exposed via the base station's own BLE services (e.g., Pump Data Characteristic) and sent to the cloud via Wi-Fi/LTE.
Borehole Sensor Support (Secondary BLE Sensor)
Overview
SMARTA L v2 firmware supports a second BLE water level sensor, referred to as the Borehole Sensor. This sensor is handled in parallel with the main tank sensor, allowing the system to monitor and report borehole water levels independently.
Configuration and Activation
- The borehole sensor is identified by its own MAC address (
bh_adv_id
), stored in preferences and configurable similarly to the main sensor. - Borehole sensor calibration parameters are independent and default to 10 bar operation (
bh_sensorType
,bh_raw_zero
,bh_height
,bh_level_known
,bh_raw_known
). - The borehole sensor is only active if the
borehole_active
boolean (stored in preferences) is set totrue
.
BLE Scanning and Data Processing
- During BLE scans, the base station checks for both the main tank sensor (
adv_id
) and the borehole sensor (bh_adv_id
). - If a device with the borehole sensor's MAC address is found and
borehole_active
is true, its service data is extracted and parsed similarly to the main sensor. - The borehole sensor's raw data is processed using its own calibration parameters via the
bh_pressure_process()
function.
MQTT Publishing
- When a new reading is received from the borehole sensor, the following MQTT topics are published (if
borehole_active
is true):bh_ble_data
: Parsed borehole sensor value (string)bh_ble_data_raw
: Raw binary string representationborehole_level
: The calculated borehole water level (integer, in centimeters or as configured)
- The
borehole_level
is published immediately upon receiving a new reading, without any additional validity or time-gap checks.
Code References
- BLE Scan Callback:
scanCompleteCallback()
inmain.ino
processes both main and borehole sensors. - Borehole Sensor Variables:
bh_adv_id
,bh_ble_service_data
,bh_sensorType
,bh_raw_zero
,bh_height
,bh_level_known
,bh_raw_known
,bh_tank_level
, etc. - Activation Flag:
borehole_active
boolean, loaded from preferences. - Pressure Processing:
bh_pressure_process()
inmain.ino
converts borehole sensor data to a level. - MQTT Publishing: Borehole sensor data is published to MQTT topics directly in the BLE scan callback.
Data Flow for Borehole Sensor
- Borehole BLE Sensor advertises its readings.
- Base Station scans for BLE advertisements.
- If
borehole_active
is true and the borehole sensor is detected, its service data is parsed. - The raw data is converted to a borehole level using borehole calibration parameters.
- The borehole level and raw data are published to MQTT topics (
bh_ble_data
,bh_ble_data_raw
,borehole_level
) immediately.