From 417a339cf5f86f5b90f8b72eab8ede517e269d10 Mon Sep 17 00:00:00 2001 From: reubenmiller Date: Tue, 3 Mar 2026 22:40:38 +0100 Subject: [PATCH] feat: add an experimental flow params plugin --- nfpm.yaml | 5 +++ src/inventory-scripts/70_FlowParams | 24 +++++++++++++++ src/parameter_update.sh | 18 +++++++++-- src/plugins/flow_params | 47 +++++++++++++++++++++++++++++ 4 files changed, 91 insertions(+), 3 deletions(-) create mode 100755 src/inventory-scripts/70_FlowParams create mode 100755 src/plugins/flow_params diff --git a/nfpm.yaml b/nfpm.yaml index 789fc9f..e39c12e 100644 --- a/nfpm.yaml +++ b/nfpm.yaml @@ -37,6 +37,11 @@ contents: file_info: mode: 0755 + - src: ./src/inventory-scripts/70_FlowParams + dst: /usr/share/tedge-inventory/scripts.d/ + file_info: + mode: 0755 + - src: ./src/c8y_ParameterUpdate.template dst: /etc/tedge/operations/c8y/ file_info: diff --git a/src/inventory-scripts/70_FlowParams b/src/inventory-scripts/70_FlowParams new file mode 100755 index 0000000..f2c143e --- /dev/null +++ b/src/inventory-scripts/70_FlowParams @@ -0,0 +1,24 @@ +#!/bin/sh +set -e + +# NOTE: The flow should probably be in charge of publishing its own values rather than relying on this mechanism to get and update the values +# in the cloud + +TEDGE_CONFIG_DIR=${TEDGE_CONFIG_DIR:-/etc/tedge} +MAPPERS_DIR="$TEDGE_CONFIG_DIR/mappers" + +find "$MAPPERS_DIR" -name params.toml | while read -r PARAMS_FILE; do + VALUES=$(jq --raw-input '[ inputs + | gsub("\r$"; "") + | split(" = "; "") + | select(length == 2) + | {(.[0]): (.[1] | fromjson)} +] | add' "$PARAMS_FILE") + + FLOW_DIR_RELATIVE=$(dirname "${PARAMS_FILE#"$MAPPERS_DIR"/}") + MAPPER=$(echo "$FLOW_DIR_RELATIVE" | cut -d/ -f1) + NAME=$(echo "$FLOW_DIR_RELATIVE" | cut -d/ -f3-) + if [ -n "$NAME" ]; then + tedge mqtt pub --retain "te/device/main///twin/flow_params_${MAPPER}_$NAME" "$VALUES" + fi +done diff --git a/src/parameter_update.sh b/src/parameter_update.sh index dd50032..2c4fbc8 100755 --- a/src/parameter_update.sh +++ b/src/parameter_update.sh @@ -17,12 +17,24 @@ set_parameters() { TYPE="$1" PARAMETERS="$2" - if [ ! -x "$PARAMETER_PLUGINS/$TYPE" ]; then - echo "Could not find a matching parameter plugin. path=$PARAMETER_PLUGINS/$TYPE" >&2 + case "$TYPE" in + flow_params_*) + # Special case where a single parameter plugin is responsible for managing all flow parameters + # since flows can't write the values to file themselves + COMMON_TYPE=flow_params + ;; + *) + COMMON_TYPE="$TYPE" + ;; + esac + + if [ ! -x "$PARAMETER_PLUGINS/$COMMON_TYPE" ]; then + echo "Could not find a matching parameter plugin. path=$PARAMETER_PLUGINS/$COMMON_TYPE" >&2 exit 1 fi - "$PARAMETER_PLUGINS/$TYPE" set "$PARAMETERS" + echo "Running plugin: \"$PARAMETER_PLUGINS/$COMMON_TYPE\" set \"$PARAMETERS\" \"$TYPE\"" >&2 + "$PARAMETER_PLUGINS/$COMMON_TYPE" set "$PARAMETERS" "$TYPE" } case "$COMMAND" in diff --git a/src/plugins/flow_params b/src/plugins/flow_params new file mode 100755 index 0000000..e322dce --- /dev/null +++ b/src/plugins/flow_params @@ -0,0 +1,47 @@ +#!/bin/sh +set -e +COMMAND="$1" +shift + +TEDGE_CONFIG_DIR="${TEDGE_CONFIG_DIR:-/etc/tedge}" + +update_parameters() { + MESSAGE="$1" + MESSAGE_TYPE="$2" + + # Write to the params. + MAPPER=$(echo "$MESSAGE_TYPE" | cut -d_ -f3) + NAME=$(echo "$MESSAGE_TYPE" | cut -d_ -f4-) + + FLOW_DIR="$TEDGE_CONFIG_DIR/mappers/$MAPPER/flows/$NAME" + if [ ! -d "$FLOW_DIR" ]; then + echo "Flow directory does not exist. path=$FLOW_DIR" >&2 + exit 1 + fi + + # convert json to key/value and write it to the params.toml file + echo "Writing to the flows params.toml file. path=$FLOW_DIR/params.toml" >&2 + echo "$MESSAGE" | jq -r 'to_entries|map("\(.key) = \(.value|tojson)")|.[]' | sudo tedge-write "$FLOW_DIR/params.toml" + + # Note: manually update the digital twin property though normally this is done by the Device Parameter microservice + # as sending the 408 message is actually harder than just updating the digital twin value + tedge mqtt pub -r "te/device/main///twin/$MESSAGE_TYPE" "${MESSAGE}" +} + +get() { + echo "{}" +} + +case "$COMMAND" in + init) + ;; + set) + update_parameters "$@" + ;; + get) + ;; + *) + echo "Unknown command. name=$COMMAND" >&2 + exit 1 + ;; +esac