Greengrass Deployment configuration use environment variables

1

Hello,

I'm quite new to AWS GreenGrass and I try to create a deployment which will work for more then just one device. I work with a raspberry pi 4 which runs Greengrass and connects to some energy meters and sensors through software things that run on the raspberry pi. I created a deployment using the following AWS provided components:

  • MQTT Broker
  • MQTT Bridge
  • Auth
  • Shadow manager

Let's say the Greengrass core device is called mainDevice01 and it should subscribe through MQTT bridge to all subjects containing mainDevice01/things/#. End users can add things (energy meters, sensors,...) to mainDevice01 which will run as a piece of software on the device. From what I experience:

  • I must create a separate deployment for every mainDevice in my cluster. Correct?
  • Every new thing that is connected to a Greengrass core devices should trigger a lot of updates to the deployment. (Which shadows to collect, new MQTT bridge links,...)

I want to create a single deployment for many mainDevices which all subscribe to their respective sub-topic. I tried to use {iot:thingName} as a variable within the merge configuration of the MQTT bridge but that doesn't seem to work.

{
  "reset": [],
  "merge": {
      "ThingData": {
        "topic": "{iot:thingName}/things/#",
        "source": "IotCore",
        "target": "LocalMqtt"
      }
    }
  }
}

In the same way I would like to automatically configure the Shadow manager (if possible) to collect the shadows of a things belonging to a core device or specific group. I'm not sure if my design idea is correct this way? Any suggestions on how this should be done the correct way are more then welcome!

Warm regards,

Hacor

  • It is not clear from your question what is your intention: MQTT Bridge is used to relay messages between the client devices connecting to Moquette and the Greengrass PubSub or AWS IoT Core. Can you give an example of which topics would the client devices subscribe to and if that communication should be between the client device and IoT Core or the client device and Greengrass Pub/Sub?

Hacor
asked 2 years ago679 views
2 Answers
1
Accepted Answer

Hello

Thanks for the answer and sorry for the late reply. I found a solution and I would like to post it here for other people to help. A few things that might be interesting for my context:

  • I am completely new to AWS and by reading a lot I'm getting more and more familiar with the design concepts
  • I am a Typescript/javascript developer, so I would like to use the Greengrass Core SDK for JS
  • This SDK doesn't support IPC (local Pub/sub), so all communication of the components needs to go through the local MQTT Broker component

What I tried to do

  • I wanted to create a single deployment in the AWS console which would work for all future devices and which contains the complete component configuration
  • All core device <-> IoT <-> App traffic is routed to each device using this pattern coreThingName/things/....
  • I was trying to dynamically configure the MQTT Bridge from this deployment
  • The MERGE configuration I was trying to do is something like this:
{
  "reset": [],
  "merge": {
      "ThingQuestions": {
        "topic": "{iot:thingName}/things/request/#",
        "source": "IotCore",
        "target": "LocalMqtt"
      },
        "ThingResponses": {
        "topic": "{iot:thingName}/things/responses/#",
        "source": "LocalMqtt",
        "target": "IotCore"
      }
    }
  }
}
  • But parameters like {iot:thingName} do not seem to be supported.

The solution

  • The design guideline seems to be: the Deployment created in the console contains all global configuration and, when needed, the components on the core device can MERGE local configuration updates.
  • I discovered that the Java, C++ and Python Greengrass Core SDKs have methods to edit the component configurations locally from within a custom Greengrass component.
  • This functionality isn't implemented yet in the Javascript SDK
  • Therefor I change the MQTT Bridge configuration dynamically from within the components using the exec function running the greengrass-cli command:
/**
 * Update the configuration of an existing GG component
 */
import { exec } from 'child_process'

/**
 * 
 * @param {*} component  aws.greengrass.clientdevices.mqtt.Bridge=2.1.0  COMPONENT_NAME=VERSION
 * @param {*} config 
 * @returns 
 */
export default async function updateConfig (component, config) {
    return new Promise( (resolve, reject) => {
        exec(`/greengrass/v2/bin/greengrass-cli deployment create --merge ${component} --update-config '${JSON.stringify(config)}'`, (err, stdout, stderr) => {
            if (err) {
                reject(err)
            } else {
                resolve(stdout)
            }
        })
    })
}

I hope this helps other new Greengrass users Best regards

Hacor

Hacor
answered 2 years ago
0

For those (like myself) whose search ended up on this thread, just a quick follow-up to say that recent versions of MQTT Bridge (e.g. 2.2.6), under Nucleus (e.g. 2.11.0) configured with interpolateComponentConfiguration: "true", do support the {iot:thingName} recipe variable in the component configuration, so something like this:

{
  "reset": [
    "/mqttTopicMapping"
  ],
  "merge": {
    "mqttTopicMapping": {
      "EdgeToCloud": {
        "topic": "etoc/{iot:thingName}/#",
        "source": "LocalMqtt",
        "target": "IotCore"
      },
      "CloudToEdge": {
        "topic": "ctoe/{iot:thingName}/#",
        "source": "IotCore",
        "target": "LocalMqtt"
      }
    }
  }
}

works as expected.

profile picture
dbouras
answered 9 months ago

You are not logged in. Log in to post an answer.

A good answer clearly answers the question and provides constructive feedback and encourages professional growth in the question asker.

Guidelines for Answering Questions