chore: add template files
Deploy bin / deploy (push) Successful in 2s
Deploy service MASTER / deploy (push) Successful in 2s

This commit is contained in:
Benjamin Labrecque
2026-07-02 17:10:01 +02:00
parent 534b57dca3
commit 8df0bad70a
9 changed files with 196 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
[project]
name = "agebd-{{ service_name_lower }}"
version = "0.1.0"
description = "AGEBD-{{ service_name }} Service"
requires-python = ">=3.9"
dependencies = [
"agebd==1.2.0",
]
[dependency-groups]
dev = [
"pytest>=8.4.2",
"ruff>=0.15.20",
]
# This tells uv where to look for 'agebd' during LOCAL dev work
[tool.uv.sources]
# Path is relative to where agebd package is deployed on hla
# machines (see CI/CD in .gitea/workflows)
agebd = { path = "../../../../../packages/{{ '{{ agebd_env }}' }}/agebd", editable = true }
[tool.ruff]
include = [
"src/**/*.py",
]
line-length = 100
[tool.ruff.lint]
# use isort to sort imports
extend-select = ["I"]
[tool.ruff.lint.isort]
known-first-party = ["agebd"]
+108
View File
@@ -0,0 +1,108 @@
from time import sleep
import typer
from epics import dbr
from agebd.enums import LogLevel
from agebd.pv import LocalPVLink
from agebd.pv import PVLink as PV
from agebd.runner import CallbackRunner
from agebd.service.base import BaseService
from agebd.service.pvs import BasePVs
from agebd.utils import get_pv_class, init_logging, printgetversion
__version__ = printgetversion(__file__)
PV = get_pv_class()
class PVs(BasePVs):
# Option 1:
## Service specific PVs from dedicated IOC
my_pv1 = PV("MY_PV1")
## Service specific PVs from other IOCs
# ...
def __init__(self, service_name: str, pv_factory):
super().__init__(service_name, pv_factory)
PV = pv_factory
# TODO: can we do this cleaner? Maybe mechanism for
# settings initial values in dev mode (e.g. ini file)
if isinstance(self.onoff, LocalPVLink):
self.onoff.value = True
# Option 2:
## Service specific PVs from dedicated IOC
self.my_pv2 = PV("MY_PV2")
## Service specific PVs from other IOCs
# ...
# TODO: class attribute names usually lowercase
# usually it is advisable to trigger the mainloop of a service on changes of certain PVs:
self.CallbackPV = PV("...", auto_monitor=dbr.DBE_VALUE)
class Service(BaseService[PVs]):
def __init__(
self, name: str, pvs: PVs, version: str = __version__, sleep_interval: float = 0.1
):
super().__init__(name, pvs, version, sleep_interval)
# TODO: What is this for?
self.path = "sls/bd/bin"
def update(self):
# when callback is fired, this code will be executed
if self.CallbackFired:
#######################################################################################
#######################################################################################
# here goes all the code that your service
# is supposed to be running when the callback is fired
sleep(1)
#######################################################################################
#######################################################################################
# callback done
self.CallbackFired = 0
#######################################################################################
#######################################################################################
# here goes all the code that your service
# is supposed to be running in any case, e.g.,
# update some pvs/vals
self.pvs.my_pv1.put("MY_PV1 value")
self.pvs.my_pv2.put("MY_PV2 value")
self.val1 = self.pvs.my_pv1.get()
self.val2 = self.pvs.my_pv2.get()
print(self.val1)
print(self.val2)
# maybe sleep to limit the update loop execution rate
sleep(1)
#######################################################################################
#######################################################################################
def main(
log_level: LogLevel = typer.Option(
LogLevel.INFO,
"--log-level",
"-l",
# Looks at the OS env variable first. If empty, falls back to "INFO"
envvar="SLS_SERVICE_LOG_LEVEL",
# help="Set log level: DEBUG, INFO, WARNING, ERROR, CRITICAL",
case_sensitive=False,
),
):
init_logging(log_level)
service_name = "{{ service_name }}"
pvs = PVs(service_name=service_name, pv_factory=PV)
service = Service(name=service_name, pvs=pvs)
runner = CallbackRunner(service=service)
runner.start()
if __name__ == "__main__":
typer.run(main)
View File
@@ -0,0 +1,4 @@
file {{ service_name }}.template {
pattern { DEVICE }
{ AGEBD-{{ service_name }} }
}
@@ -0,0 +1,6 @@
cpu_architecture: x86_64
epics_version: 7.0.8
ioc_host: {{ ioc_host }}
ioc_port: {{ ioc_port }}
os: RHEL8
os_id: rhel
+27
View File
@@ -0,0 +1,27 @@
# This is a template for preaparing an IOC providing BD Service specific PVs
# Access Security Groups:
# DEFAULT - logt wenn EGU oder so veraendert werden
# LOG - logt wenn neuer wert geschrieben wird
# PROTECTED - verhindert versuchte caputs auf alle fields ausser VAL
# READONLY - verhindert versuchte caputs und aktiviert caputlog
# Input links can specify CA, CP, or CPP.
# If the input link specifies CA, it will be forced to be a Channel Access link.
# If the input link specifies CP, it will also be forced to be a Channel Access link; in addition, it will cause the record containing the input link to process whenever a monitor is posted, no matter what the record's SCAN field specifies.
# If the input link specifies CPP, it means the same thing as CP, except that the record will be processed if and only if the record itself specifies passive in its SCAN field. Output links can specify CA, which will simply cause them to be Channel Access links.
#
record(ao, "$(DEVICE):AO") {
field(DESC, "Analog Output Record (ao)")
field(ASG, "PROTECTED")
field(VAL, "0")
field(PINI, "YES")
}
record(bo, "$(DEVICE):BO") {
field(DESC, "Binary Output Record (bo)")
field(ASG, "READONLY")
field(ZSV, "MINOR")
field(OSV, "NO_ALARM")
field(VAL, "1")
field(PINI, "YES")
}
+1
View File
@@ -0,0 +1 @@
epicsEnvSet("ENGINEER", "{{ user }}")
+1
View File
@@ -0,0 +1 @@
# TODO
@@ -0,0 +1,16 @@
[Unit]
Description=AGEBD-SERVICE-{{ service_name }}
After=network.target
[Service]
Environment=AGEBD_ENV={{ '{{ agebd_env }}' }}
ExecStart=/sls/bd/hla/bin/start_service.sh {{ service_id }} {{ service_name }}
estart=no
[Install]
WantedBy=default.target
# https://www.freedesktop.org/software/systemd/man/latest/systemd.service.html
# systemctl --user daemon-reload
# systemctl --user enable /sls/bd/bin/systemd/AGEBD-SERVICE-{{ service_name }}.service
# systemctl --user start AGEBD-SERVICE-{{ service_name }}