2 Commits

Author SHA1 Message Date
f23a91bd4f feat(deb): Create first changelog 2025-04-18 19:24:05 +02:00
28d4ce0116 feat(deb): Start packaging branch 2025-04-18 19:24:04 +02:00
16 changed files with 158 additions and 75 deletions

27
debian/changelog vendored Normal file
View File

@@ -0,0 +1,27 @@
revpi-middleware (0.0.1-1+deb12+1) bookworm; urgency=medium
* docs: Start git project with python git-ignore and Readme
* docs: Use 'reuse' for SPDX Headers and Licenses
* feat: Add python base project files
* feat: Add proginit application basic module
* feat: Add the data directory for additional data files for the project
* test: Add tests directory with a dummy test
* build: Add all necessary files for the build system
* feat: Add dummy main application script
* feat: Add systemd file and data to integrate the app as a daemon
* chore: Update proginit to 1.4.0
* feat(dbus): Add ResetDriverWatchdog helper as global dbus helper
* feat(process_image): Add D-Bus interface for piControl driver
* feat(dbus): Add initial D-Bus middleware implementation
* feat(dbus): Add `extend_interface` function for dynamic interface naming
* feat(dbus): Add DBus policy configuration for revpi-middleware
* feat: Add MiddlewareDaemon implementation to revpi-middleware
* feat: Add daemon mode and signal handling to main application
* feat(cli): Add D-Bus helper functions for CLI commands.
* feat(cli): Add await_signal function to handle D-Bus signals
* feat(cli): Add `await-reset` to wait for piControl reset signal
* chore(build): Update requirements for this project
* feat(cli): Add new CLI tool entry point for `revpictl`
* feat(deb): Start packaging branch
-- Sven Sager <s.sager@kunbus.com> Fri, 18 Apr 2025 19:02:20 +0200

36
debian/control vendored Normal file
View File

@@ -0,0 +1,36 @@
Source: revpi-middleware
Section: python
Priority: optional
Maintainer: KUNBUS GmbH <support@kunbus.com>
Rules-Requires-Root: no
Homepage: https://revolutionpi.com/
Vcs-Browser: https://gitlab.com/revolutionpi/revpi-middleware
Vcs-Git: https://gitlab.com/revolutionpi/revpi-middleware.git -b debian/bookworm
Build-Depends:
debhelper-compat (= 13),
dh-python,
python3-all,
python3-gi (>= 3.42.2),
python3-pydbus (>= 0.6.0),
python3-setuptools,
Standards-Version: 4.6.2
Package: revpi-middleware
Architecture: all
Pre-Depends: ${misc:Pre-Depends}
Depends:
${python3:Depends},
${misc:Depends}
Description: Revolution Pi middleware with D-Bus interface
The Revolution Pi middleware provides a robust communication interface for
Revolution Pi industrial computers. It enables seamless integration between
hardware components and applications through a D-Bus interface. The middleware
serves as a bridge for data exchange, device configuration, and system
monitoring.
.
Key features:
* Hardware abstraction layer for Revolution Pi I/O modules
* Real-time data processing and event handling
* Simplified API for accessing Revolution Pi hardware features
* Extensive configuration options for industrial automation tasks
* Built-in monitoring and diagnostic capabilities

27
debian/copyright vendored Normal file
View File

@@ -0,0 +1,27 @@
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
Source: https://gitlab.com/revolutionpi/opcua-revpi-server
Files: *
Copyright: 2025 KUNBUS GmbH
License: GPL-2+
Files: debian/*
Copyright: 2025 KUNBUS GmbH
License: GPL-2+
License: GPL-2+
This package is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
.
This package is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>
.
On Debian systems, the complete text of the GNU General
Public License version 2 can be found in "/usr/share/common-licenses/GPL-2".

7
debian/gbp.conf vendored Normal file
View File

@@ -0,0 +1,7 @@
[DEFAULT]
upstream-branch = main
upstream-tag = v%(version)s
debian-branch=debian/bookworm
debian-tag = debian/%(version)s
debian-tag-msg = %(pkg)s Debian release %(version)s
pristine-tar = True

4
debian/revpi-middleware.install vendored Normal file
View File

@@ -0,0 +1,4 @@
data/dbus-policy/com.revolutionpi.middleware1.conf /usr/share/dbus-1/system.d
data/etc/default/revpi-middleware /etc/default/
data/etc/revpi-middleware/revpi-middleware.conf /etc/revpi-middleware/
data/systemd/before_253/revpi-middleware.service /lib/systemd/system/

2
debian/revpi-middleware.links vendored Normal file
View File

@@ -0,0 +1,2 @@
/usr/share/revpi-middleware/revpi-middleware /usr/sbin/revpi-middleware
/usr/share/revpi-middleware/revpicli /usr/bin/revpicli

7
debian/rules vendored Executable file
View File

@@ -0,0 +1,7 @@
#!/usr/bin/make -f
export PYBUILD_NAME=revpi-middleware
export PYBUILD_INSTALL_ARGS=--install-lib=/usr/share/$(PYBUILD_NAME)/ --install-scripts=/usr/share/$(PYBUILD_NAME)/
%:
dh $@ --with python3 --buildsystem=pybuild

1
debian/source/format vendored Normal file
View File

@@ -0,0 +1 @@
3.0 (quilt)

View File

@@ -5,9 +5,8 @@ from threading import Thread
from time import sleep
from gi.repository import GLib
from pydbus import SessionBus, SystemBus
from pydbus import SystemBus
from .. import proginit as pi
from ..dbus_middleware1 import REVPI_DBUS_BASE_PATH
from ..dbus_middleware1 import REVPI_DBUS_NAME
@@ -35,7 +34,7 @@ def simple_call(method: str, *args, interface: str, object_path=REVPI_DBUS_BASE_
Any
The result of the method invocation on the targeted D-Bus interface.
"""
bus = SessionBus() if pi.pargs.use_session_bus else SystemBus()
bus = SystemBus()
revpi = bus.get(REVPI_DBUS_NAME, object_path)
iface = revpi[interface]
return getattr(iface, method)(*args)
@@ -56,7 +55,7 @@ def await_signal(signal_name: str, timeout: int, interface: str, object_path=REV
detected_signal = True
loop.quit()
bus = SessionBus() if pi.pargs.use_session_bus else SystemBus()
bus = SystemBus()
revpi = bus.get(REVPI_DBUS_NAME, object_path)
iface = revpi[interface]

View File

@@ -42,7 +42,7 @@ class MiddlewareDaemon:
if self.bus_provider and self.bus_provider.is_alive():
return
self.bus_provider = BusProvider(use_system_bus=not pi.pargs.use_session_bus)
self.bus_provider = BusProvider()
self.bus_provider.start()
log.debug("leave MiddlewareDaemon.dbus_start")

View File

@@ -2,5 +2,27 @@
# SPDX-FileCopyrightText: 2025 KUNBUS GmbH
# SPDX-License-Identifier: GPL-2.0-or-later
"""D-Bus middleware version 1 of revpi_middleware."""
from .dbus_helper import REVPI_DBUS_BASE_PATH, REVPI_DBUS_NAME
from .dbus_helper import extend_interface
from ..__about__ import __author__, __copyright__, __license__, __version__
REVPI_DBUS_NAME = "com.revolutionpi.middleware1"
REVPI_DBUS_BASE_PATH = "/com/revolutionpi/middleware1"
def extend_interface(*args) -> str:
"""
Extends an interface name by appending additional segments to a pre-defined base name.
This function takes multiple arguments, concatenates them with a predefined base
interface name, and returns the resulting string, effectively constructing an
extended interface name.
Args:
*args: str
Components to be appended to the base interface name.
Returns:
str
Fully constructed interface name by joining the base interface name with
the provided segments.
"""
return ".".join([REVPI_DBUS_NAME, *args])

View File

@@ -6,7 +6,7 @@ from logging import getLogger
from threading import Thread
from gi.repository import GLib
from pydbus import SessionBus, SystemBus
from pydbus import SystemBus
from . import REVPI_DBUS_NAME
from .process_image import InterfacePiControl
@@ -16,27 +16,19 @@ log = getLogger(__name__)
class BusProvider(Thread):
def __init__(
self,
picontrol_device="/dev/piControl0",
config_rsc="/etc/revpi/config.rsc",
use_system_bus=True,
):
def __init__(self):
log.debug("enter BusProvider.__init__")
super().__init__()
self._bus = SystemBus() if use_system_bus else SessionBus()
self._bus = SystemBus()
self._loop = GLib.MainLoop()
self.picontrol_device = picontrol_device
self.config_rsc = config_rsc
def run(self):
log.debug("enter BusProvider.run")
self._bus.publish(
REVPI_DBUS_NAME,
InterfacePiControl(self.picontrol_device, self.config_rsc),
InterfacePiControl(),
)
self._loop.run()

View File

@@ -1,31 +0,0 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: 2025 KUNBUS GmbH
# SPDX-License-Identifier: GPL-2.0-or-later
"""Helper for dbus."""
from logging import getLogger
log = getLogger(__name__)
REVPI_DBUS_NAME = "com.revolutionpi.middleware1"
REVPI_DBUS_BASE_PATH = "/com/revolutionpi/middleware1"
def extend_interface(*args) -> str:
"""
Extends an interface name by appending additional segments to a pre-defined base name.
This function takes multiple arguments, concatenates them with a predefined base
interface name, and returns the resulting string, effectively constructing an
extended interface name.
Args:
*args: str
Components to be appended to the base interface name.
Returns:
str
Fully constructed interface name by joining the base interface name with
the provided segments.
"""
return ".".join([REVPI_DBUS_NAME, *args])

View File

@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: 2025 KUNBUS GmbH
# SPDX-FileCopyrightText: 2020-2023 Sven Sager
# SPDX-License-Identifier: GPL-2.0-or-later
"""
Helper for the process image.
@@ -7,6 +7,7 @@ Helper for the process image.
The ResetDriverWatchdog class is a copy of revpipyload project module "watchdogs"
https://github.com/naruxde/revpipyload/blob/b51c2b617a57cc7d96fd67e1da9f090a0624eacb/src/revpipyload/watchdogs.py
"""
import os
from fcntl import ioctl
from logging import getLogger
@@ -18,9 +19,9 @@ log = getLogger(__name__)
class ResetDriverWatchdog(Thread):
"""Watchdog to catch the reset_driver action."""
def __init__(self, picontrol_device: str):
def __init__(self, pi_control_device="/dev/piControl0"):
super(ResetDriverWatchdog, self).__init__()
self.procimg = picontrol_device
self.procimg = pi_control_device
self.daemon = True
self._calls = []
self._exit = False
@@ -34,7 +35,7 @@ class ResetDriverWatchdog(Thread):
"""
Mainloop of watchdog for reset_driver.
If the thread cannot open the process image or the IOCTL is not
If the thread can not open the process image or the IOCTL is not
implemented (wheezy), the thread function will stop. The trigger
property will always return True.
"""
@@ -50,7 +51,7 @@ class ResetDriverWatchdog(Thread):
)
return
# The ioctl will return 2 bytes (c-type int)
# The ioctl will return 2 byte (c-type int)
byte_buff = bytearray(2)
while not self._exit:
try:
@@ -72,7 +73,7 @@ class ResetDriverWatchdog(Thread):
def register_call(self, function):
"""Register a function, if watchdog triggers."""
if not callable(function):
raise ValueError("Function is not callable.")
return ValueError("Function is not callable.")
if function not in self._calls:
self._calls.append(function)
@@ -88,7 +89,7 @@ class ResetDriverWatchdog(Thread):
log.debug("leave ResetDriverWatchdog.stop()")
def unregister_call(self, function=None):
"""Remove a function from the watchdog trigger."""
"""Remove a function call on watchdog trigger."""
if function is None:
self._calls.clear()
elif function in self._calls:

View File

@@ -8,7 +8,7 @@ from logging import getLogger
from pydbus.generic import signal
from .process_image_helper import ResetDriverWatchdog
from ..interface_helper import ResetDriverWatchdog
log = getLogger(__name__)
@@ -27,11 +27,10 @@ class InterfacePiControl:
NotifyDriverReset = signal()
def __init__(self, picontrol_device: str, config_rsc: str):
self.picontrol_device = picontrol_device
self.config_rsc = config_rsc
def __init__(self):
self.pi_control = "/dev/piControl0"
self.wd_reset_driver = ResetDriverWatchdog(self.picontrol_device)
self.wd_reset_driver = ResetDriverWatchdog(self.pi_control)
self.wd_reset_driver.register_call(self.notify_reset_driver)
def notify_reset_driver(self):
@@ -41,9 +40,9 @@ class InterfacePiControl:
log.debug("enter InterfacePiControl.ResetDriver")
try:
fd = os.open(self.picontrol_device, os.O_WRONLY)
fd = os.open(self.pi_control, os.O_WRONLY)
except Exception as e:
log.warning(f"could not open ${self.picontrol_device} to reset driver")
log.warning(f"could not open ${self.pi_control} to reset driver")
raise e
execption = None

View File

@@ -9,7 +9,7 @@ __version__ = "1.4.0"
import logging
import sys
from argparse import ArgumentParser, Namespace, SUPPRESS
from argparse import ArgumentParser, Namespace
from configparser import ConfigParser
from enum import Enum
from os import R_OK, W_OK, access, environ, getpid, remove
@@ -262,16 +262,6 @@ parser = ArgumentParser(
prog=programname,
description="Program description",
)
# Use session bus of D-Bus for local testing and development proposes (hidden)
parser.add_argument(
"--use-session-bus",
dest="use_session_bus",
action="store_true",
default=False,
help=SUPPRESS,
)
parser.add_argument("--version", action="version", version=f"%(prog)s {program_version}")
parser.add_argument(
"-f",