Files
venus/_template/dbus-template.py
Paul G dd566f6975 Apply Venus OS best practices across all services
- Standardize multilog to s25000 n4 (~100KB cap) to prevent filling /data
- Use VeDbusService register=False + deferred register() in dbus-generator-ramp and dbus-vrm-history
- Add @exit_on_error decorator to template GLib callback
- Document best practices in README and template README

Made-with: Cursor
2026-03-16 18:40:54 +00:00

134 lines
3.9 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Venus OS D-Bus service template.
To create a new service:
1. Copy the _template/ directory and rename it to dbus-<your-service-name>/
2. Rename this file to match your service (e.g. your_service.py)
3. Update config.py with your service name, product ID, etc.
4. Update service/run to point to your renamed script
5. Update install.sh with your service name
6. Update build-package.sh with your file list
"""
import logging
import os
import signal
import sys
import time
sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python'))
from vedbus import VeDbusService # noqa: E402
from ve_utils import exit_on_error # noqa: E402
from settingsdevice import SettingsDevice # noqa: E402
import dbus # noqa: E402
from gi.repository import GLib # noqa: E402
from config import ( # noqa: E402
SERVICE_NAME,
DEVICE_INSTANCE,
PRODUCT_NAME,
PRODUCT_ID,
FIRMWARE_VERSION,
CONNECTED,
MAIN_LOOP_INTERVAL_MS,
LOG_LEVEL,
VERSION,
)
logger = logging.getLogger('dbus-template')
class TemplateService:
"""Main service class. Rename to match your service."""
def __init__(self):
self._running = False
self._dbusservice = None
self._settings = None
def start(self):
"""Initialize D-Bus service and start the main loop."""
bus = dbus.SystemBus()
self._dbusservice = VeDbusService(
SERVICE_NAME, bus=bus, register=False
)
# Mandatory D-Bus paths
self._dbusservice.add_path('/Mgmt/ProcessName', __file__)
self._dbusservice.add_path('/Mgmt/ProcessVersion', VERSION)
self._dbusservice.add_path('/Mgmt/Connection', 'local')
self._dbusservice.add_path('/DeviceInstance', DEVICE_INSTANCE)
self._dbusservice.add_path('/ProductId', PRODUCT_ID)
self._dbusservice.add_path('/ProductName', PRODUCT_NAME)
self._dbusservice.add_path('/FirmwareVersion', FIRMWARE_VERSION)
self._dbusservice.add_path('/Connected', CONNECTED)
# --- Add your custom D-Bus paths here ---
# self._dbusservice.add_path('/YourPath', initial_value)
# Settings (stored in Venus OS localsettings, persist across reboots)
settings_path = '/Settings/Template'
supported_settings = {
'enabled': [settings_path + '/Enabled', 1, 0, 1],
# 'your_setting': [settings_path + '/YourSetting', default, min, max],
}
self._settings = SettingsDevice(
bus, supported_settings, self._on_setting_changed
)
self._dbusservice.register()
logger.info('Service registered on D-Bus as %s', SERVICE_NAME)
self._running = True
GLib.timeout_add(MAIN_LOOP_INTERVAL_MS, self._update)
@exit_on_error
def _update(self):
"""Called every MAIN_LOOP_INTERVAL_MS. Return True to keep running."""
if not self._running:
return False
# --- Add your main loop logic here ---
return True
def _on_setting_changed(self, setting, old, new):
"""Called when a Venus OS setting changes."""
logger.info('Setting %s changed: %s -> %s', setting, old, new)
def stop(self):
"""Clean shutdown."""
self._running = False
logger.info('Service stopped')
def main():
logging.basicConfig(
level=getattr(logging, LOG_LEVEL, logging.INFO),
format='%(asctime)s %(name)s %(levelname)s %(message)s',
datefmt='%Y-%m-%d %H:%M:%S',
)
logger.info('Starting dbus-template v%s', VERSION)
service = TemplateService()
def shutdown(signum, frame):
logger.info('Received signal %d, shutting down...', signum)
service.stop()
sys.exit(0)
signal.signal(signal.SIGTERM, shutdown)
signal.signal(signal.SIGINT, shutdown)
service.start()
mainloop = GLib.MainLoop()
mainloop.run()
if __name__ == '__main__':
main()