Each device (sensor) needs to have the relevant section updated in the config on the server. This is the example section for the sensors in this repository.
{
"hostname": "rpi",
"username": "vti",
"mac_address": "2c:cf:67:28:80:0a",
"registration": "2024-09-02T11:53:49.694564Z",
"sensors": [
{
"args": [
"--upload-interval",
"5"
],
"entry_point": "radar.py",
"git_url": "https://github.com/jsliacan/sensors.git",
"git_version": "varia",
"name": "VTIGarminVariaRCT716"
},
{
"args": [
"--upload-interval",
"5"
],
"entry_point": "lidar.py",
"git_url": "https://github.com/jsliacan/sensors.git",
"git_version": "varia",
"name": "VTIGarminLidarLiteV3"
},
{
"args": [
"--upload-interval",
"5"
],
"entry_point": "button.py",
"git_url": "https://github.com/jsliacan/sensors.git",
"git_version": "varia",
"name": "VTIButton"
}
],
"project": "validation",
"model": "CardiLidar"
}It is possible to copy the data files at regular intervals during the activity to a USB storage attached to the RPi. This line should do it:
shutil.copyfile(filename, "/media/vti/bikedata/"+filename.split("/")[-1])Clearly, there are caveats.
- The USB needs to be attached, otherwise this will crash the process.
- Make sure to format USB device as ext4 and put a filesystem on it. The code expects the USB to be
bikedataand mounts to/media/vti/bikedataon the RPi. I used Disk Utility on Fedora and once I formatted the USB disk I created a partition calledbikedataon it (ext4 type). That's it.
- Python 3.x: Ensure you have Python 3 installed on your system.
- Dependencies: The framework uses the
requestsmodule for handling HTTP requests. You can install it using:
pip install requestsClone the repository to your local machine:
git clone https://github.com/bicycledata/sensor_template.git
cd sensor_templateTo create a custom bicycle sensor, extend the BicycleSensor class
and implement the abstract methods: write_header() and
write_measurement(). The provided SensorTemplate class serves as
an example implementation that records the current time as a sensor
measurement.
Example:
class MyCustomSensor(BicycleSensor):
def write_header(self):
self.write_to_file('time, speed')
def write_measurement(self):
speed = get_speed_data() # Replace with actual sensor logic
self.write_to_file(f"{time.time()}, {speed}")You can run the provided SensorTemplate class with the following
command:
./sensor.py --hash <device_hash> --name <sensor_name> [options]--hash(required): The unique hash of the device, used for identifying the sensor during uploads.--name(required): The name of the sensor.--loglevel(optional): Set the logging level (DEBUG,INFO,WARNING). Default isINFO.--measurement-frequency(optional): Frequency of sensor measurements in Hertz (measurements per second). Default is1.0 Hz.--stdout(optional): Enable logging output to the console (stdout).--upload-interval(optional): Interval between data uploads in seconds. Default is300 seconds(5 minutes).
The framework handles the following operations:
- File Management: Data is written to CSV files stored in the
pendingdirectory. Upon successful upload, files are moved to theuploadeddirectory. - Data Upload: Data is uploaded to a remote server (configured in
the
_upload_datamethod) using HTTP POST requests. The upload logic is executed in a separate thread to ensure that the main sensor loop runs without interruptions. - Signal Handling: The framework gracefully handles shutdown
signals (
SIGTERM,SIGINT) and ensures that any pending data is uploaded before exiting.
Logging is configured through the configure() function. The
framework supports:
- File-based logging: Logs are stored in the
log/sensor_template.logfile. - Rotating logs: By enabling the
rotatingoption, logs are rotated when they reach 5MB in size, with a backup count of 2. - Console output: Enable logging to the console using the
--stdoutflag.
The framework's automated upload feature sends sensor data to the
server at regular intervals. The upload process is managed by a
separate thread, ensuring it does not interfere with data collection.
The upload endpoint and payload are defined in the _upload_data()
method.
Note: If the upload fails, the data remains in the pending
directory and the framework retries in the next cycle.
Contributions are welcome! If you have suggestions for improvements or find any bugs, feel free to open an issue or submit a pull request.
This repository is licensed under the MIT License. See the LICENSE file for more details.