An open-source, MQTT-enabled multi-sensor and camera node built for Raspberry Pi. RVML integrates hardware sensors (PIR motion, BH1750 ambient light) and video camera capabilities (Picamera2) directly into Home Assistant via MQTT Discovery.
-
Home Assistant Auto-Discovery: Automatically exposes entities to Home Assistant upon connection.
-
PIR Motion Sensor: Real-time motion detection published via MQTT (
gpiozero). -
BH1750 Light Sensor: Ambient illuminance reading in lux over I2C (
smbus). -
Multi-Mode Camera Streaming:
-
MQTT Image Stream: Publishes raw JPEG payloads to Home Assistant.
-
HTTP MJPEG Stream: Embedded HTTP server streaming
.mjpg. -
TCP Socket Stream: Raw H.264 video feed over a socket connection.
-
Local Video Recording:
-
Encodes H.264 video to disk using
Picamera2hardware acceleration. -
Circular Storage Buffer: Configurable maximum file limit that overwrites older recordings sequentially (
recording_00.h264,recording_01.h264, ...) to prevent disk overflow. -
Mutual Exclusion: Ensures stream and recording routines manage camera hardware resources cleanly.
-
Raspberry Pi (e.g., Pi Zero W, 3B+, 4B, 5)
-
Raspberry Pi Camera Module (supported by
Picamera2) -
BH1750 Ambient Light Sensor (connected via I2C)
-
PIR Motion Sensor Module (connected via GPIO)
Ensure I2C and Camera interfaces are enabled on your Raspberry Pi:
sudo raspi-config
# Navigate to Interface Options -> Enable I2C and Camera
git clone https://github.com/johndeckardsoftware/rvml.git
cd rvmlpython -m venv venv/
source venv/bin/activateInstall necessary system packages for gpiozero, smbus, and picamera2:
sudo apt update
sudo apt install -y python3-pip python3-picam2 python3-smbus python3-gpiozero
Install the required Python packages:
pip install paho-mqtt gpiozero smbus2
Create or modify config.json in the project root directory:
{
"log_level": "INFO",
"mqtt": {
"server": "192.168.1.100",
"port": 1883,
"login": "mqtt_user",
"password": "mqtt_password",
"client_id": "rvml_node_01"
},
"pir": {
"enabled": true,
"running": true,
"pin": 18,
"wait_time": 5,
"state_topic": "rvml/sensors/pir/status"
},
"bh1750": {
"enabled": true,
"running": true,
"addr": 35,
"smbus": 1,
"wait_time": 15,
"state_topic": "rvml/sensors/bh1750/status"
},
"webcam": {
"enabled": true,
"default_mode": "MQTTCamera",
"video_folder": "/home/pi/rvml/videos",
"max_recording_files": 10,
"stream_command_topic": "rvml/camera/stream/set",
"stream_state_topic": "rvml/camera/stream/state",
"mode_command_topic": "rvml/camera/stream_mode/set",
"mode_state_topic": "rvml/camera/stream_mode/state",
"record_command_topic": "rvml/camera/record/set",
"record_state_topic": "rvml/camera/record/state",
"mjpeg": {
"port": 8080
},
"tcp": {
"port": 10001
}
}
}
Run the main application using Python:
python3 main.py -c config.json -l rvml.log
-
-c,--config: Path to configuration file (default:config.json). -
-l,--log: Path to output log file (default:rvml.log).
When RVML starts, HADiscovery automatically registers the following entities into Home Assistant:
| Entity Type | Entity Name | Function |
|---|---|---|
binary_sensor |
RVML Motion Sensor | Detects motion via PIR |
sensor |
RVML Ambient Light | Reports illuminance (lx) |
camera |
RVML Camera | Displays live image feed over MQTT |
switch |
RVML Camera Stream | Toggles stream ON/OFF |
switch |
RVML Camera Record | Toggles local H.264 recording ON/OFF |
select |
RVML Stream Mode | Switches stream format (MQTTCamera, mjpeg, tcp) |
├── config.py # Dynamic configuration loader, backup, and setup utility
├── bh1750.py # Driver thread for BH1750 ambient light sensor
├── pir.py # GPIO PIR motion sensor listener thread
├── mqtt.py # Paho MQTT client wrapper with auto-reconnect
├── ha_discovery.py # Home Assistant MQTT discovery entity registrar
├── webcam.py # Picamera2 engine with multi-mode streaming & recording
└── main.py # Entry point and signal shutdown handler
Distributed under the MIT License.