Odometer for the Science Gallery exhibit with server api.
The project consists of the odometer running on a Raspberry Pi and the corresponding Node Server. The server connnects to CouchDB using nano.
Additionally, a cheer bot can be activated to cheer runners on.
Components:
- Raspberry Pi 3 or 4
- Hall Sensor
- VCC: connected to 3V3 power (pin 1)
- Gnd: connected to Ground (pin 6)
- Vout: connected to GPIO 17 (pin 11)
- Resistor 10k ohm
Make sure to set the following environment variables:
export SERVER_PROD=http://ratwheelserver.com
export DEVICE_ID=ratwheel
export SESSION_TIMEOUT=10.0
export SUBMISSION_FREQUENCY=1
export MAGNET_ANGLE=180
SERVER_PROD indicates the IP address or domain of the data server.DEVICE_ID identifies the device, SESSION_TIMEOUT sets the time interval (in seconds) for a new session to start (i.e., if the wheel does not turn for the specified time, the device creates a new session for a new user), and SUBMISSION_FREQUENCY determines the frequency in which the current rpm are sent to the server. MAGNET_ANGLE describes how far the magnets are apart to be able to discount rpm.
Also, make sure to set the timezone of the device, e.g.:
sudo timedatectl set-timezone Australia/Melbourne
To execute the python script on startup make sure to install a cronjob using
crontab -e
and adding the following line to it:
@reboot . $HOME/.profile; python /home/pi/code/ratwheel/RPi/python/odometer.py > /home/pi/logs/odometer.log &
To make sure the odometer pings the server in regular intervals also add the following cronjob:
*/1 * * * * . $HOME/.profile; python /home/pi/code/ratwheel/RPi/python/server_connection.py &
Install packages using npm install. Start via npm start.
The server receives updates from wheels via the API. The following routes are available:
-
GET
/api/live: live dashboard showing wheel activity. Examples for how to process server responses can be found in live.js./api/history?limit=N: loads the lastNsessions from the server's cache. The most current sessions are listed last./api/simulator: deprecated. Used to generate fake wheel activity.
-
POST
/api/rpm: receives odometer updates. Parameters includedeviceId,rpm(rotations per minute),sessionId,rotations, and a timestamp (ts). If nosesionIdis specified orsessionIdis set to new, the server creates a new session and returns thesessionIdfrom the corresponding database entry. Therotationsshould specify the rotations the wheel made since the last update. The server will add rotations and process the session, returning a session object with the following parameters:
{ deviceId: 'armwheel', sessionId: '51050eaa7eeb5bcac3519db8130a29bc', status: 'inactive', rotations: 0.014866666666666667, tsStart: 1626769990064, tsEnd: 1626769990572, rpm: '0', kmh: 0.21, avgRpm: 1, totalMinutes: 0.04, km: 0.00003035825700918937, avgKmh: 0.22, topSpeed: 0.25, likes: 2, likedBy: { bot: 2 }, mouseId: 1, cheerCondition: 'viral' }
- The
mouseIdis a human-readable, incrementing identifier, which is reset with each server relaunch.- example call:
curl -X POST http://localhost:3000/api/rpm -d '{"deviceId": "ratwheel", "rpm": 5, "sessionId": "new", "rotations": 12, "ts": 62}' -H 'Content-Type: application/json'
- example call:
/api/like: likes are collected device-specific or general. If nodeviceIdis specified, the like will be added to all active sessions. Optionally, likes can be signed according to where they come from (e.g., a bot or human agent).- example call (generic):
curl -X POST http://localhost:3000/api/like -d '{}' -H 'Content-Type: application/json' - example call (device-specific):
curl -X POST http://localhost:3000/api/like -d '{"deviceId": "armwheel"}' -H 'Content-Type: application/json' - example call (including source):
curl -X POST http://localhost:3000/api/like -d '{"deviceId": "armwheel", "likedBy": "human"}' -H 'Content-Type: application/json'
- example call (generic):
/api/ping: odometers ping the server regardless of wheel activity. Status can be monitoried via/api/live.- example call:
curl -X POST http://localhost:3000/api/ping -d '{"deviceId": "armwheel"}' -H 'Content-Type: application/json'
- example call:
Wheel and server variables are configured in wheel_config.yaml. For each device, diameter and deviceId can be set. Additionally, the server provides a cheer bot, designed to like up active sessions. When a new session is created, the server randomly picks a condition from cheerbot.conditions. A timer is started with a random interval between minDelay and maxDelay. Once the timer is triggered and if the session is still active, a burst of likes are scheduled in the time interval specified as burstInterval. How many cheers are scheduled depends on the condition and the values specified as minCheers and maxCheers.
- Running on Rainbows, in Pursuit, 19 July 2021
This application is published under the MIT license and GPL v3.