diff options
Diffstat (limited to 'recipes-demo/agl-vss-helper')
5 files changed, 251 insertions, 0 deletions
diff --git a/recipes-demo/agl-vss-helper/agl-vss-helper.bb b/recipes-demo/agl-vss-helper/agl-vss-helper.bb new file mode 100644 index 000000000..88e14511a --- /dev/null +++ b/recipes-demo/agl-vss-helper/agl-vss-helper.bb @@ -0,0 +1,35 @@ +DESCRIPTION = "AGL VSS helper daemon" +LICENSE = "MIT" +LIC_FILES_CHKSUM = "file://${COMMON_LICENSE_DIR}/MIT;md5=0835ade698e0bcf8506ecda2f7b4f302" + +SRC_URI = "file://agl-vss-helper.py \ + file://agl-vss-helper.yaml \ + file://agl-vss-helper.token \ + file://agl-vss-helper.service \ +" + +inherit systemd + +SYSTEMD_SERVICE:${PN} = "${BPN}.service" + +do_configure[noexec] = "1" +do_compile[noexec] = "1" + +do_install() { + install -d ${D}${sbindir} + install -m 0755 ${WORKDIR}/${BPN}.py ${D}${sbindir} + install -d ${D}${sysconfdir}/xdg/AGL/${BPN} + install -m 0644 ${WORKDIR}/${BPN}.yaml ${D}${sysconfdir}/xdg/AGL/ + install -m 0644 ${WORKDIR}/${BPN}.token ${D}${sysconfdir}/xdg/AGL/${BPN}/ + install -D -m 0644 ${WORKDIR}/${BPN}.service ${D}${systemd_system_unitdir}/${BPN}.service +} + +RDEPENDS:${PN} = " \ + python3 \ + python3-asyncio \ + python3-systemd \ + kuksa-databroker \ + kuksa-databroker-agl \ + kuksa-client \ + kuksa-certificates-agl-ca \ +" diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.py b/recipes-demo/agl-vss-helper/files/agl-vss-helper.py new file mode 100644 index 000000000..73ac6b9df --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python3 +# Copyright (c) 2022 Aakash Solanki, tech2aks@gmail.com +# Copyright (c) 2024 Scott Murray <scott.murray@konsulko.com> +# +# SPDX-License-Identifier: MIT + +import sys +from pathlib import Path +import yaml +import asyncio +import concurrent.futures +from kuksa_client.grpc.aio import VSSClient +from kuksa_client.grpc import Datapoint +from systemd.daemon import notify + +# Defaults +hostname = "localhost" +port = 55555 +config_filename = "/etc/xdg/AGL/agl-vss-helper.yaml" +token_filename = "/etc/xdg/AGL/agl-vss-helper/agl-vss-helper.token" +ca_cert_filename = "/etc/kuksa-val/CA.pem" +tls_server_name = "localhost" +verbose = False + +async def main(): + client = VSSClient(hostname, + port, + root_certificates=Path(ca_cert_filename), + tls_server_name=tls_server_name, + token=token, + ensure_startup_connection=True) + await client.connect() + print(f"Connected to KUKSA.val databroker at {hostname}:{port}") + if "initialize" in config and isinstance(config["initialize"], list): + for entry in config["initialize"]: + if "signal" in entry and "value" in entry: + if verbose: + print(f"Setting {entry['signal']} to {entry['value']}") + await client.set_current_values({ entry["signal"] : Datapoint(entry["value"]) }) + + notify("READY=1") + + if "mock" in config and isinstance(config["mock"], list): + if len(config["mock"]) != 0: + print(f"Mocking actuators:") + for signal in config["mock"]: + print(f" {signal}") + async for updates in client.subscribe_target_values(config["mock"]): + for signal in updates: + if updates[signal] is not None: + if verbose: + print(f"Actuating {signal} to {updates[signal].value}") + await client.set_current_values({ signal : Datapoint(updates[signal].value) }) + + +# +# Initialization +# + +try: + config_file = open(config_filename, "r") + config = yaml.safe_load(config_file) +except yaml.YAMLError as exc: + print(f"Could not parse configuration: ${exc}") +except: + print(f"Could not read configuration") + +if "verbose" in config and isinstance(config["verbose"], bool): + verbose = config["verbose"] +if "hostname" in config and isinstance(config["hostname"], string): + hostname = config["hostname"] +if "port" in config and isinstance(config["port"], int): + port = config["port"] +if "use-tls" in config and isinstance(config["use-tls"], bool): + use_tls = config["use-tls"] +if "token-file" in config and isinstance(config["token-file"], string): + token_filename = config["token-file"] +if "ca-certificate" in config and isinstance(config["ca-certificate"], string): + ca_cert_filename = config["ca-certificate"] + +if token_filename != "": + if verbose: + print(f"Reading authorization token {token_filename}") + token_file = open(token_filename, "r") + token = token_file.read() +else: + token = "" + +print("Starting") +try: + asyncio.run(main()) +except KeyboardInterrupt: + print("Exiting") + +notify("STOPPING=1") +sys.exit(0) diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.service b/recipes-demo/agl-vss-helper/files/agl-vss-helper.service new file mode 100644 index 000000000..0199b6cde --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.service @@ -0,0 +1,11 @@ +[Unit] +Wants=network.target kuksa-databroker.service +After=network.target kuksa-databroker.service + +[Service] +Type=notify +ExecStart=/usr/bin/python3 -u /usr/sbin/agl-vss-helper.py +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.token b/recipes-demo/agl-vss-helper/files/agl-vss-helper.token new file mode 100644 index 000000000..110d3c413 --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.token @@ -0,0 +1 @@ +eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJsb2NhbCBkZXYiLCJpc3MiOiJjcmVhdGVUb2tlbi5weSIsImF1ZCI6WyJrdWtzYS52YWwiXSwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjE3NjcyMjU1OTksInNjb3BlIjoiYWN0dWF0ZSBwcm92aWRlIn0.x-bUZwDCC663wGYrWCYjQZwQWhN1CMuKgxuIN5dUF_izwMutiqF6Xc-tnXgZa93BbT3I74WOMk4awKHBUSTWekGs3-qF6gajorbat6n5180TOqvNu4CXuIPZN5zpngf4id3smMkKOT699tPnSEbmlkj4vk-mIjeOAU-FcYA-VbkKBTsjvfFgKa2OdB5h9uZARBg5Rx7uBN3JsH1I6j9zoLid184Ewa6bhU2qniFt5iPsGJniNsKsRrrndN1KzthO13My44s56yvwSHIOrgDGbXdja_eLuOVOq9pHCjCtorPScgEuUUE4aldIuML-_j397taNP9Y3VZYVvofEK7AuiePTbzwxrZ1RAjK74h1-4ued3A2gUTjr5BsRlc9b7eLZzxLJkrqdfGAzBh_rtrB7p32TbvpjeFP30NW6bB9JS43XACUUm_S_RcyI7BLuUdnFyQDQr6l6sRz9XayYXceilHdCxbAVN0HVnBeui5Bb0mUZYIRZeY8k6zcssmokANTD8ZviDMpKlOU3t5AlXJ0nLkgyMhV9IUTwPUv6F8BTPc-CquJCUNbTyo4ywTSoODWbm3PmQ3Y46gWF06xqnB4wehLscBdVk3iAihQp3tckGhMnx5PI_Oy7utIncr4pRCMos63TnBkfrl7d43cHQTuK0kO76EWtv4ODEHgLvEAv4HA
\ No newline at end of file diff --git a/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml b/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml new file mode 100644 index 000000000..21b5ce9a0 --- /dev/null +++ b/recipes-demo/agl-vss-helper/files/agl-vss-helper.yaml @@ -0,0 +1,108 @@ +initialize: +- signal: Vehicle.Speed + value: 0 +- signal: Vehicle.Powertrain.CombustionEngine.Speed + value: 600 +- signal: Vehicle.Powertrain.FuelSystem.RelativeLevel + value: 70 +- signal: Vehicle.Powertrain.FuelSystem.Range + value: 300000 +- signal: Vehicle.Powertrain.CombustionEngine.ECT + value: 70 +- signal: Vehicle.Body.Lights.DirectionIndicator.Left.IsSignaling + value: false +- signal: Vehicle.Body.Lights.DirectionIndicator.Right.IsSignaling + value: false +- signal: Vehicle.Powertrain.Transmission.SelectedGear + value: 127 +- signal: Vehicle.Body.Lights.Beam.Low.IsOn + value: true +- signal: Vehicle.Body.Lights.Beam.High.IsOn + value: false +- signal: Vehicle.Body.Lights.Parking.IsOn + value: false +- signal: Vehicle.Body.Lights.Hazard.IsSignaling + value: false +- signal: Vehicle.TraveledDistance + value: 1763 +- signal: Vehicle.TraveledDistanceSinceStart + value: 0 +- signal: Vehicle.Body.Trunk.Rear.IsLocked + value: true +- signal: Vehicle.Body.Trunk.Rear.IsOpen + value: false +- signal: Vehicle.Powertrain.Transmission.PerformanceMode + value: "NORMAL" +- signal: Vehicle.Cabin.HVAC.AmbientAirTemperature + value: 22 +- signal: Vehicle.Exterior.AirTemperature + value: 24 +- signal: Vehicle.Chassis.Axle.Row1.Wheel.Left.Tire.Pressure + value: 220 +- signal: Vehicle.Chassis.Axle.Row1.Wheel.Right.Tire.Pressure + value: 216 +- signal: Vehicle.Chassis.Axle.Row2.Wheel.Left.Tire.Pressure + value: 217 +- signal: Vehicle.Chassis.Axle.Row2.Wheel.Right.Tire.Pressure + value: 222 +- signal: Vehicle.OBD.Status.IsMILOn + value: false +- signal: Vehicle.Cabin.Infotainment.HMI.DistanceUnit + value: "KILOMETERS" +- signal: Vehicle.Cabin.Infotainment.HMI.TemperatureUnit + value: "C" +- signal: Vehicle.Cabin.Infotainment.HMI.TirePressureUnit + value: "KPA" +- signal: Vehicle.ADAS.CruiseControl.IsEnabled + value: false +- signal: Vehicle.ADAS.CruiseControl.IsActive + value: false +- signal: Vehicle.ADAS.CruiseControl.SpeedSet + value: false +- signal: Vehicle.ADAS.CruiseControl.IsError + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsCharging + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableConnected + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsChargingCableLocked + value: false +- signal: Vehicle.Powertrain.TractionBattery.Charging.IsDischarging + value: false +#- signal: Vehicle.CurrentLocation.Latitude +# value: +#- signal: Vehicle.CurrentLocation.Longitude +# value: +# +# AGL specific signals +# +- signal: Vehicle.Cabin.Infotainment.Navigation.State + value: "STOPPED" +- signal: Vehicle.Cabin.Infotainment.Navigation.ElapsedDistance + value: 0.0 +#- signal: Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Latitude +# value: +#- signal: Vehicle.Cabin.Infotainment.Navigation.DestinationSet.Longitude +# value: +- signal: Vehicle.Cabin.SteeringWheel.Switches.Info + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeUp + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeDown + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.VolumeMute + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Next + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Previous + value: false +- signal: Vehicle.Cabin.SteeringWheel.Switches.Mode + value: false + +mock: +- Vehicle.Cabin.Infotainment.HMI.DistanceUnit +- Vehicle.Cabin.Infotainment.HMI.TemperatureUnit +- Vehicle.Cabin.Infotainment.HMI.TirePressureUnit +- Vehicle.ADAS.CruiseControl.IsEnabled +- Vehicle.ADAS.CruiseControl.IsActive +- Vehicle.ADAS.CruiseControl.SpeedSet |