From b26515dcf2afc510cc59782f99965f10b96be433 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Thu, 16 May 2024 18:24:25 -0400 Subject: Add gateway demo Changes: - Add recipe for AGL VSS to MQTT proxy daemon - Update agl-vcar.dbc CAN database definition to add signals useful for demoing the proxy (per V2C EG discussion). - Add a patch to kuksa-dbc-feeder to allow sensor signal updates to generate CAN messages in output mode. - Add VSS vspec variants to define the desired CAN input and output support for the various kuksa-dbc-feeder instances in the default and full gateway demos. - Add configurations for kuksa-dbc-feeder for the running the default gateway demo with CAN output from a demo control panel instance on a single CAN interface, as well as a fuller setup with a second kuksa-dbc-feeder running against a second CAN interface on the gateway to handle the demo steering wheel and HVAC support. - Add gateway demo specific configuration files for various KUKSA.val databroker clients to override the databroker location. - Add agl-gateway-demo and agl-gateway-demo-preconfigured images for the default and full demos. - Add *-preconfigured-gateway image flavors for the Flutter IVI, IC, and KVM demo images that support running with the databroker on the gateway. NOTES: - The *-preconfigured-gateway images assume the gateway has an IP address of 192.168.10.4. - Required changes to the agl-demo-control-panel application and the addition of a agl-ivi-demo-control-panel-preconfigured-gateway image will come in a subsequent change. Bug-AGL: SPEC-5107, SPEC-5138 Change-Id: I9797aa72737af7af3d791a5151198f80b6d90e0d Signed-off-by: Scott Murray Reviewed-on: https://gerrit.automotivelinux.org/gerrit/c/AGL/meta-agl-demo/+/29921 ci-image-boot-test: Jenkins Job builder account ci-image-build: Jenkins Job builder account Tested-by: Jenkins Job builder account --- .../0004-Enable-val2dbc-for-sensor-values.patch | 142 +++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0004-Enable-val2dbc-for-sensor-values.patch (limited to 'recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0004-Enable-val2dbc-for-sensor-values.patch') diff --git a/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0004-Enable-val2dbc-for-sensor-values.patch b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0004-Enable-val2dbc-for-sensor-values.patch new file mode 100644 index 000000000..7f22a90ad --- /dev/null +++ b/recipes-connectivity/kuksa-val/kuksa-dbc-feeder/0004-Enable-val2dbc-for-sensor-values.patch @@ -0,0 +1,142 @@ +From d6f1aaa7f26aa52f4b219f60e704d5ab2954f082 Mon Sep 17 00:00:00 2001 +From: Scott Murray +Date: Wed, 3 Apr 2024 02:09:11 +0900 +Subject: [PATCH] Enable val2dbc for sensor values + +Rework to allow val2dbc mode to write out sensor values in +addition to actuator target values. + +Upstream-Status: pending + +Signed-off-by: Scott Murray +--- + dbc2val/dbcfeeder.py | 8 ++++++-- + .../dbcfeederlib/databrokerclientwrapper.py | 18 ++++++++++++------ + dbc2val/dbcfeederlib/dbc2vssmapper.py | 14 +++++++++----- + dbc2val/dbcfeederlib/serverclientwrapper.py | 2 +- + 4 files changed, 28 insertions(+), 14 deletions(-) + +diff --git a/dbc2val/dbcfeeder.py b/dbc2val/dbcfeeder.py +index e7fd319..5e0df2f 100755 +--- a/dbc2val/dbcfeeder.py ++++ b/dbc2val/dbcfeeder.py +@@ -322,15 +322,19 @@ class Feeder: + log.debug("vss-Update callback!") + dbc_ids = set() + for update in updates: ++ value = None + if update.entry.value is not None: +- # This shall currently never happen as we do not subscribe to this + log.warning(f"Current value for {update.entry.path} is now: " + f"{update.entry.value.value} of type {type(update.entry.value.value)}") ++ value = update.entry.value.value + + if update.entry.actuator_target is not None: + log.debug(f"Target value for {update.entry.path} is now: {update.entry.actuator_target} " + f"of type {type(update.entry.actuator_target.value)}") +- new_dbc_ids = self._mapper.handle_update(update.entry.path, update.entry.actuator_target.value) ++ value = update.entry.actuator_target.value ++ ++ if value != None: ++ new_dbc_ids = self._mapper.handle_update(update.entry.path, value) + dbc_ids.update(new_dbc_ids) + + can_ids = set() +diff --git a/dbc2val/dbcfeederlib/databrokerclientwrapper.py b/dbc2val/dbcfeederlib/databrokerclientwrapper.py +index 35836e9..46ae330 100644 +--- a/dbc2val/dbcfeederlib/databrokerclientwrapper.py ++++ b/dbc2val/dbcfeederlib/databrokerclientwrapper.py +@@ -200,14 +200,20 @@ class DatabrokerClientWrapper(clientwrapper.ClientWrapper): + def supports_subscription(self) -> bool: + return True + +- async def subscribe(self, vss_names: List[str], callback): ++ async def subscribe(self, vss_entries: dict[str, str], callback): + """Creates a subscription and calls the callback when data received""" + entries = [] +- for name in vss_names: +- # Always subscribe to target +- subscribe_entry = SubscribeEntry(name, View.FIELDS, [Field.ACTUATOR_TARGET]) +- log.info(f"Subscribe entry: {subscribe_entry}") +- entries.append(subscribe_entry) ++ for name, signal_type in vss_entries.items(): ++ if signal_type == "actuator": ++ subscribe_entry = SubscribeEntry(name, View.FIELDS, [Field.ACTUATOR_TARGET]) ++ log.info(f"Subscribe entry: {subscribe_entry}") ++ entries.append(subscribe_entry) ++ if signal_type == "sensor": ++ subscribe_entry = SubscribeEntry(name, View.FIELDS, [Field.VALUE]) ++ log.info(f"Subscribe entry: {subscribe_entry}") ++ entries.append(subscribe_entry) ++ if not entries: ++ return + + # If there is a path VSSClient will request a secure connection + if self._tls and self._root_ca_path: +diff --git a/dbc2val/dbcfeederlib/dbc2vssmapper.py b/dbc2val/dbcfeederlib/dbc2vssmapper.py +index 5142a5e..8f04cdd 100644 +--- a/dbc2val/dbcfeederlib/dbc2vssmapper.py ++++ b/dbc2val/dbcfeederlib/dbc2vssmapper.py +@@ -61,12 +61,13 @@ class VSSMapping: + parser: Parser = Parser() + + def __init__(self, vss_name: str, dbc_name: str, transform: dict, interval_ms: int, +- on_change: bool, datatype: str, description: str): ++ on_change: bool, signal_type: str, datatype: str, description: str): + self.vss_name = vss_name + self.dbc_name = dbc_name + self.transform = transform + self.interval_ms = interval_ms + self.on_change = on_change ++ self.signal_type = signal_type + self.datatype = datatype + self.description = description + # For time comparison (interval_ms) we store last value used for comparison. Unit seconds. +@@ -282,7 +283,7 @@ class Mapper: + log.info(f"Using default interval 1000 ms for {expanded_name}") + interval = 1000 + mapping_entry = VSSMapping(expanded_name, dbc_name, transform, interval, on_change, +- node["datatype"], node["description"]) ++ node["type"], node["datatype"], node["description"]) + if dbc_name not in self.dbc2val_mapping: + self.dbc2val_mapping[dbc_name] = [] + self.dbc2val_mapping[dbc_name].append(mapping_entry) +@@ -306,7 +307,7 @@ class Mapper: + log.warning(f"interval_ms attribute ignored for {expanded_name}") + + mapping_entry = VSSMapping(expanded_name, dbc_name, transform, interval, on_change, +- node["datatype"], node["description"]) ++ node["type"], node["datatype"], node["description"]) + if dbc_name not in self.val2dbc_mapping: + self.val2dbc_mapping[expanded_name] = [] + self.val2dbc_mapping[expanded_name].append(mapping_entry) +@@ -380,9 +381,12 @@ class Mapper: + """Return a set of all dbc names used for reception""" + return self.dbc2val_mapping.keys() + +- def get_val2dbc_entries(self) -> KeysView: ++ def get_val2dbc_entries(self) -> Dict[str, str]: + """Return a set of all vss names used for reception""" +- return self.val2dbc_mapping.keys() ++ entries: Dict[str, str] = {} ++ for name, mappings in self.val2dbc_mapping.items(): ++ entries[name] = mappings[0].signal_type ++ return entries + + def get_vss_names(self) -> Set[str]: + """Get all VSS names used in mappings, both vss2dbc and dbc2vss""" +diff --git a/dbc2val/dbcfeederlib/serverclientwrapper.py b/dbc2val/dbcfeederlib/serverclientwrapper.py +index 63bc12e..ca11daf 100644 +--- a/dbc2val/dbcfeederlib/serverclientwrapper.py ++++ b/dbc2val/dbcfeederlib/serverclientwrapper.py +@@ -125,6 +125,6 @@ class ServerClientWrapper(clientwrapper.ClientWrapper): + log.info("Feature not implemented") + return False + +- async def subscribe(self, vss_names: List[str], callback): ++ async def subscribe(self, vss_entries: dict[str, str], callback): + log.error("Feature not implemented") + return +-- +2.34.1 + -- cgit 1.2.3-korg