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
This commit is contained in:
16
README.md
16
README.md
@@ -74,6 +74,22 @@ Some projects require API keys or credentials. These are excluded from version c
|
|||||||
- `dbus-windy-station/station_config.example.json` --> `station_config.json`
|
- `dbus-windy-station/station_config.example.json` --> `station_config.json`
|
||||||
- `watermaker/ui/.env.example` --> `.env`
|
- `watermaker/ui/.env.example` --> `.env`
|
||||||
|
|
||||||
|
## Venus OS Best Practices
|
||||||
|
|
||||||
|
These projects follow guidelines from the [Venus OS wiki](https://github.com/victronenergy/venus/wiki):
|
||||||
|
|
||||||
|
**D-Bus Service Registration** -- Create `VeDbusService` with `register=False`, add all paths and populate initial values, then call `register()`. This prevents consumers from querying the service before it is fully initialized ([details](https://github.com/victronenergy/venus/wiki/dbus-api)).
|
||||||
|
|
||||||
|
**Mandatory D-Bus Paths** -- Every service must publish: `/Mgmt/ProcessName`, `/Mgmt/ProcessVersion`, `/Mgmt/Connection`, `/DeviceInstance`, `/ProductId`, `/ProductName`, `/FirmwareVersion`, `/Connected`.
|
||||||
|
|
||||||
|
**Stability and Exception Handling** -- Don't code too defensively. If something goes wrong, let the process exit cleanly and let daemontools restart it. For `GLib.timeout_add` callbacks in Python, an unhandled exception silently drops the callback without exiting; use `exit_on_error()` from `ve_utils.py` to ensure crashes propagate. Background threads should always set `daemon=True` ([details](https://github.com/victronenergy/venus/wiki/howto-add-a-driver-to-Venus#4-stability---exceptions-handling)).
|
||||||
|
|
||||||
|
**Logging** -- Use `multilog t s25000 n4` in `service/log/run` to cap log storage at ~100KB per service (4 files x 25KB). This matches the Victron v2.23 standard and prevents filling the `/data` partition on space-constrained devices.
|
||||||
|
|
||||||
|
**Service Directory** -- Symlink services to `/opt/victronenergy/service` (not `/service`, which is a tmpfs overlay). The `install.sh` scripts handle this with fallback logic.
|
||||||
|
|
||||||
|
**Persistence** -- Install code under `/data/` so it survives firmware updates. Add an entry in `/data/rc.local` to restore the service symlink after updates.
|
||||||
|
|
||||||
## New Project Template
|
## New Project Template
|
||||||
|
|
||||||
See [`_template/`](_template/) for a skeleton D-Bus service with all the boilerplate: main script, config, daemontools service, install/uninstall scripts, and build packaging.
|
See [`_template/`](_template/) for a skeleton D-Bus service with all the boilerplate: main script, config, daemontools service, install/uninstall scripts, and build packaging.
|
||||||
|
|||||||
@@ -34,6 +34,15 @@ Update these for your service:
|
|||||||
| `/Connected` | int | Connection status (0/1) |
|
| `/Connected` | int | Connection status (0/1) |
|
||||||
| `/Settings/Template/Enabled` | int | Enable/disable via settings |
|
| `/Settings/Template/Enabled` | int | Enable/disable via settings |
|
||||||
|
|
||||||
|
## Venus OS Best Practices
|
||||||
|
|
||||||
|
The template follows these [Venus OS wiki](https://github.com/victronenergy/venus/wiki) guidelines:
|
||||||
|
|
||||||
|
- **`register=False`** -- `VeDbusService` is created with `register=False`, paths are added, then `register()` is called to prevent race conditions with consumers.
|
||||||
|
- **`@exit_on_error`** -- Applied to the `GLib.timeout_add` callback so unhandled exceptions crash the process instead of silently dropping the callback.
|
||||||
|
- **`daemon=True`** -- Set on background threads so they don't prevent process exit.
|
||||||
|
- **multilog** -- Log size capped at `s25000 n4` (~100KB) to avoid filling the `/data` partition.
|
||||||
|
|
||||||
## Checklist
|
## Checklist
|
||||||
|
|
||||||
- [ ] Unique service name in `config.py` (`com.victronenergy.yourservice`)
|
- [ ] Unique service name in `config.py` (`com.victronenergy.yourservice`)
|
||||||
@@ -41,4 +50,6 @@ Update these for your service:
|
|||||||
- [ ] All file references updated in `service/run`, `install.sh`, `build-package.sh`
|
- [ ] All file references updated in `service/run`, `install.sh`, `build-package.sh`
|
||||||
- [ ] Custom D-Bus paths added
|
- [ ] Custom D-Bus paths added
|
||||||
- [ ] Settings paths updated
|
- [ ] Settings paths updated
|
||||||
|
- [ ] `@exit_on_error` on all `GLib.timeout_add` callbacks
|
||||||
|
- [ ] Background threads use `daemon=True`
|
||||||
- [ ] README replaced with your own documentation
|
- [ ] README replaced with your own documentation
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import time
|
|||||||
sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python'))
|
sys.path.insert(1, os.path.join(os.path.dirname(__file__), 'ext', 'velib_python'))
|
||||||
|
|
||||||
from vedbus import VeDbusService # noqa: E402
|
from vedbus import VeDbusService # noqa: E402
|
||||||
|
from ve_utils import exit_on_error # noqa: E402
|
||||||
from settingsdevice import SettingsDevice # noqa: E402
|
from settingsdevice import SettingsDevice # noqa: E402
|
||||||
import dbus # noqa: E402
|
import dbus # noqa: E402
|
||||||
from gi.repository import GLib # noqa: E402
|
from gi.repository import GLib # noqa: E402
|
||||||
@@ -84,6 +85,7 @@ class TemplateService:
|
|||||||
self._running = True
|
self._running = True
|
||||||
GLib.timeout_add(MAIN_LOOP_INTERVAL_MS, self._update)
|
GLib.timeout_add(MAIN_LOOP_INTERVAL_MS, self._update)
|
||||||
|
|
||||||
|
@exit_on_error
|
||||||
def _update(self):
|
def _update(self):
|
||||||
"""Called every MAIN_LOOP_INTERVAL_MS. Return True to keep running."""
|
"""Called every MAIN_LOOP_INTERVAL_MS. Return True to keep running."""
|
||||||
if not self._running:
|
if not self._running:
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-template
|
exec multilog t s25000 n4 /var/log/dbus-template
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-raymarine-publisher
|
exec multilog t s25000 n4 /var/log/dbus-raymarine-publisher
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ class GeneratorRampController:
|
|||||||
|
|
||||||
for attempt in range(max_retries):
|
for attempt in range(max_retries):
|
||||||
try:
|
try:
|
||||||
self.dbus_service = VeDbusService(SERVICE_NAME, self.bus)
|
self.dbus_service = VeDbusService(SERVICE_NAME, self.bus, register=False)
|
||||||
break # Success
|
break # Success
|
||||||
except dbus.exceptions.NameExistsException:
|
except dbus.exceptions.NameExistsException:
|
||||||
if attempt < max_retries - 1:
|
if attempt < max_retries - 1:
|
||||||
@@ -317,6 +317,7 @@ class GeneratorRampController:
|
|||||||
onchangecallback=self._on_setting_changed,
|
onchangecallback=self._on_setting_changed,
|
||||||
gettextcallback=lambda p, v: f"{v} min")
|
gettextcallback=lambda p, v: f"{v} min")
|
||||||
|
|
||||||
|
self.dbus_service.register()
|
||||||
self.logger.info("D-Bus service created")
|
self.logger.info("D-Bus service created")
|
||||||
|
|
||||||
def _generator_state_text(self, path, value):
|
def _generator_state_text(self, path, value):
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-generator-ramp-webui
|
exec multilog t s25000 n4 /var/log/dbus-generator-ramp-webui
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
# Logs service output using multilog
|
# Logs service output using multilog
|
||||||
#
|
#
|
||||||
|
|
||||||
exec multilog t s99999 n8 /var/log/dbus-generator-ramp
|
exec multilog t s25000 n4 /var/log/dbus-generator-ramp
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-lightning
|
exec multilog t s25000 n4 /var/log/dbus-lightning
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-meteoblue-forecast
|
exec multilog t s25000 n4 /var/log/dbus-meteoblue-forecast
|
||||||
|
|||||||
@@ -5,4 +5,4 @@
|
|||||||
# Logs service output using multilog
|
# Logs service output using multilog
|
||||||
#
|
#
|
||||||
|
|
||||||
exec multilog t s99999 n8 /var/log/dbus-no-foreign-land
|
exec multilog t s25000 n4 /var/log/dbus-no-foreign-land
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-tides
|
exec multilog t s25000 n4 /var/log/dbus-tides
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ class VrmHistoryService:
|
|||||||
|
|
||||||
for attempt in range(max_retries):
|
for attempt in range(max_retries):
|
||||||
try:
|
try:
|
||||||
self.dbus_service = VeDbusService(SERVICE_NAME, self.bus)
|
self.dbus_service = VeDbusService(SERVICE_NAME, self.bus, register=False)
|
||||||
break
|
break
|
||||||
except dbus.exceptions.NameExistsException:
|
except dbus.exceptions.NameExistsException:
|
||||||
if attempt < max_retries - 1:
|
if attempt < max_retries - 1:
|
||||||
@@ -135,6 +135,9 @@ class VrmHistoryService:
|
|||||||
svc.add_path('/History/GeneratorRuntime', '')
|
svc.add_path('/History/GeneratorRuntime', '')
|
||||||
svc.add_path('/History/BatteryCycles', '')
|
svc.add_path('/History/BatteryCycles', '')
|
||||||
|
|
||||||
|
# Register service after all paths added (Venus OS best practice)
|
||||||
|
svc.register()
|
||||||
|
|
||||||
def _setup_settings(self):
|
def _setup_settings(self):
|
||||||
try:
|
try:
|
||||||
base = DBUS_CONFIG['settings_path']
|
base = DBUS_CONFIG['settings_path']
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-vrm-history
|
exec multilog t s25000 n4 /var/log/dbus-vrm-history
|
||||||
|
|||||||
@@ -1,2 +1,2 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
exec multilog t s99999 n8 /var/log/dbus-windy-station
|
exec multilog t s25000 n4 /var/log/dbus-windy-station
|
||||||
|
|||||||
Reference in New Issue
Block a user