Package: c8ydm
Cumulocity IoT Device Management Reference AgentCumulocity Device Management (DM) Reference Agent written in Python3 to demonstrate most of theDevice Management CapabilitiesofCumulocity IoTQuick StartThe agent can be run in a docker container or natively on a device with preferrable with linux OS (e.g raspberry pi) or any other operating system.The docker version is mainly used to simulate a device including a SSH + VNC server for Remote Access. It can be also used to simulatoe multiple instances of the agent & devices.The native version is mainly used when connecting physical devices with real capabilities and sensors attached.Here is a detailed"How-To" guidewhich provides a step-by-step instruction to get the agent running & to explore the device management features of Cumulocity IoTDocker Quick StartTo quickly run the agent you can use theprebuild docker image.docker run switschel/c8ydmIf you want docker management included just mount the docker sock to the container by adding-v /var/run/docker.sock:/var/run/docker.sockPer default Bootstrapping is used and no other information is necessary. In this case the dockercontainer Idis the device Id which should be entered whenregistering a device in cumulocity.You can find it out with:docker psIf you don't want to use the prebuild image for any reason (e.g. you want to make changes to the docker image) just clone the repo and in a linux shell of your choice use:chmod +x start.sh & ./start.shIn windows shells like PS or CMD run:start.batThe script will build a docker image and starting one instance afterwards.If you want to run the Agent without using docker you need tobuildandrunthe Agent manually.Docker Quick Start ConfigurationTo configure the agent you can mount theagent.inito the docker image by using in the docker run command:-v {{path-to-your-local-agent.ini}}:/root/.cumulocity/agent.iniAs an alternative you can useenvironment variablesto overwrite the default values in the agent.ini within the image. Here is an example to change the loglevel:-e C8YDM_AGENT_LOGLEVEL=DEBUGFor the local docker build you can use three options to change the docker image:Enable/Disable VNC as part of the docker image (1 per default)INSTALL_VNC=1 ./start.shBy default, the docker container runs in background. If you want to run it interactively:INTERACTIVE=1 ./start.shGenerate self-signed certificates and using certificate based authenticationUSE_CERTS=1 ./start.shQuick Start with Device Certificates in docker containerThe agent contains scripts for generating & uploading self-signed certificates. To use them additional informatiopn as environment variables are needed. You can use theuse_certs.envfile as a template to provide them or add the environment variables using "-e" command of docker.Here is an example env file to generate a self signed certificate and upload it to a target tenant:C8YDM_MQTT_CERT_AUTH=true
C8YDM_MQTT_URL=mqtt.eu-latest.cumulocity.com
CERT_TENANT=<tenantID>
CERT_USER=<username>
CERT_PASSWORD=<password>The easiest way is to use the --env-file comand of docker to load it. Example:docker run --env-file use_certs.env switschel/c8ydmor for the local image run after maintaining theuse_certs.env:USE_CERTS=1 ./start.shIf you have your own certificates already you have multiple options to use them. In all cases you must make use of the "device.id" property in the agent.ini to set a device ID you used to generate the certificates.Option 1:Mount the whole config folder to the docker container containing the certs and adapted agent.ini. Make sure that you set the properties accordingly and that the cert paths are pointing to the location /root/.cumulocity/certs:-v {{path-to-your-local-config-folder}}:/root/.cumulocity/Option 2:Mount the certificates and adapt the config using environment variablesOption 3:Before building the docker image locally copy the certs to "config/certs" folder, change the agent.ini,buildthe image andrunthe image.NativeTo quickly run the agent natively make sure pyhton 3.7+ and pip is installed on your computer.
Manually put theconfig fileand theDM_Agent.jsoninto the /.cumulocity folder in youruser folder.
For example: "/home/user1/.cumulocity" in Linux or "C:\Users\user1\.cumulocity" in Windows.Installationpip install c8ydmTo start the agent runc8ydm.startand to stop runc8ydm.stopFeaturesSupported Cumulocity DM FeaturesFeatureSupportedDevice CertificatesYesDevice Bootstrapping & RegistrationYesSoftware Updates (apt)YesFirmware Updates (simulated only)YesConfiguration Updates text-basedYesConfiguration file-basedYesDevice ProfilesYesNetworkYesDevice Metrics (CPU, Memory etc.)YesRemote Logfile RequestsYesLocation UpdatesYesRemote ShellYesRemote Access (SSH, VNC, Passthrough)YesHardware Metering (CPU, Memory, HDD)YesRaspberry PI SenseHATYesDocker ManagementYesConnectivity (Mobile) ManagementNoAdv. Software ManagementYes (apt)Service ManagementYes (docker)Raspberry PI & SenseHAT SupportThe DM Agent can run on a Raspberry PI (3+) with a SenseHAT.
It supports:Reading out all sensor values of the SenseHAT (Humidity, Temperature, Acceleration, Gyroscope, Compass)Display Messages on the LEDs sent via Cumulocity to the Pi (c8y_Message) via Message Widget.Generates Events when the Joystick is pressed in different direction.It is suggested to run the Agent as a Service. Usedm-agent.serviceto install it:sudo cp ./service/dm-agent.service /etc/systemd/system/
sudo systemctl enable dm-agent.service
sudo systemctl daemon-reload
sudo service dm-agent startConfigurationThe agent can be configured via the agent.ini which must be placed in{userFolder}/.cumulocityWhen running in docker container the agent.ini can be mounted to the /root/.cumulocity/agent.iniYou can find a reference agent.inihereCategoryPropertyDescriptionmqtturlThe URL of the Cumulocity MQTT endpointmqttportThe Port of the Cumulocity MQTT endpointmqtttlsTrue when using port 8883, false when using port 1883mqttcert_authtrue when you want use Device Certificates for Device Authenticationmqttclient_certPath to your cert which should be used to for Authenticationmqttclient_keyPath to your private key for Authenticationmqttping.interval.secondsInterval in seconds for the mqtt client to send pings to MQTT Broker to keep the connection alive.agentnameThe prefix name of the Device in Cumulocity. The serial will be attached with a "-" e.g. dm-example-device-1234567.agenttypeThe Device Type in Cumulocityagentmain.loop.interval.secondsThe interval in seconds sensor data will be forwarded to CumulocityagentrequiredintervalThe interval in minutes for Cumulocity to detect that the device is online/offline.agentloglevelThe log level to write and print to file/console.Environment variablesThe environment variables with "C8YDM_" prefix are mapped to configuration files.
Mapping rules:Prefix C8YDM_{{CATEGORY}} means what category the option belongs toUpper case letters are mapped to lower case lettersDouble underscore __ is mapped to .Examples:C8YDM_MQTT_CERT_AUTH => mqtt.cert_auth 
C8YDM_AGENT_MAIN__LOOP__INTERVAL__SECONDS => agent.main.loop.interval.secondsBuildThe agent can be build in multiple ways.Building via pipTo build the agent via pip just run (as a root user, otherwise add "sudo" prior all commands).pip3 install -r requirements.txtto install dependencies and afterwardspip3 install .to build the agent itself.
Please note that in debian/ubuntu you need additionally installapt install python-aptvia apt.Continue with chapterRunBuilding debian packageIn order to build the .deb yourself first install python-stdeb via apt.apt install python3-stdebAfterwards runpython3 setup.py --command-packages=stdeb.command bdist_debon the level of the setup.py.In oder to install the debian package locally runapt install ./deb_dist/python-c8ydm_0.1-1_all.debContinue with chapterRunBuilding docker imageTo build a docker image you can make use of the providedDockerfile.Example:docker build -t dm-image -f docker/Dockerfile .RunPythonBefore running the agent some manual steps need to be takenManually put theconfig fileinto {userfolder}/.cumulocityYou can run the agent by executing (as root, otherwise add "sudo")c8ydm.startin your console when you usedBuilding via pipto build and install the agent.apt / debian packageBefore running the agent some manual steps need to be takenManually put theconfig fileand theDM_Agent.jsoninto ~/.cumulocity folder. ~ stands for the current user folder. The SmartRESTTemplate will be automatically uploaded on first start.You have to install "c8y-device-proxy" via pip or using the provided deb file of theC8Y Device ProxyYou can run the agent by executing (as root, otherwise add "sudo")c8ydm.startin your console when you usedBuilding via debto build and install the agent.DockerYou can run the agent by executingdocker run -d -v /var/run/docker.sock:/var/run/docker.sock dm-imagein your console when you usedBuilding Docker Imageto build and install the agent.The config can be mounted the container. Otherwise the default config will be used. SeeDocker Quick Start ConfigurationMass deploymentYou can run multiple instances of an container via:. mass_start.sh 5where in this example 5 is the number of agent instances.DevelopDev ContainerThe project comes with VS Code devcontainer support. Make sure you useVisual Studio Codein combination with docker. Just open the project in VS Code and click on "Reopen in Dev Container".In the background the Agent will be build and started. Also a debug/run configuration is provided so you can easilly start/debug the agent within VS Code.Using certificate authenticationYou can generate certificates necessary to certficate authentication, and you can upload the generated root certificate to your tenant's trusted certificate list by executing the scripts like below:./scripts/generate_cert.sh \
--serial pyagent0001 \
--root-name iot-ca \
--cert-dir /root/.cumulocity/certs \
--cert-name device-cert

./scripts/upload_cert.sh \
--tenant-domain <tenant domain> \
--tenant-id <tenant ID> \
--username <username for the tenant> \
--password <password for the tenant> \
--cert-path /root/.cumulocity/certs/iot-ca.pem \
--cert-name <(arbitrary) displayed name of the root certificate>After this, you can connect the agent to your tenant using cert authentication (with the serialpyagent0001in this case).TestingWith the agent running in the container, execute./test.sh \
--url <tenant domain> \
--tenant <tenant ID> \
--username <username for the tenant> \
--password <password for the tenant>to run pytest.Extending the agentThe agent knows three types of classes that it will automatically load and include from the "agentmodules" directory.Sensorsclass Sensor:
   __metaclass__ = ABCMeta

   def __init__(self, serial):
     self.serial = serial

   '''
   Returns a list of SmartREST messages. Will be called every iteration of the main loop.
   '''
   @abstractmethod
   def getSensorMessages(self): passSensors are periodically polled by the main loop and published.Listenersclass Listener:
   __metaclass__ = ABCMeta

   def __init__(self, serial, agent):
     self.serial = serial
     self.agent = agent

   '''
   Callback that is executed for any operation received
   '''
   @abstractmethod
   def handleOperation(self, message): pass

   '''
   Returns a list of supported operations
   '''
   @abstractmethod
   def getSupportedOperations(self): pass

   '''
   Returns a list of supported SmartREST templates (X-Ids)
   '''
   @abstractmethod
   def getSupportedTemplates(self): passListeners are called whenever there is a message received on a subscribed topic.Initializersclass Initializer:
   __metaclass__ = ABCMeta

   def __init__(self, serial):
     self.serial = serial

   '''
   Returns a list of SmartREST messages. Will be called at the start of the agent
   '''
   @abstractmethod
   def getMessages(self): passInitializers are only called once at the start of the agent.You can take a look at the two example modules for how it can be used.Log & ConfigurationThe logfile and configuration can be found in the following directory./root/.cumulocityThese tools are provided as-is and without warranty or support. They do not constitute part of the Software AG product suite. Users are free to use, fork and modify them, subject to the license agreement. While Software AG welcomes contributions, we cannot guarantee to include every contribution in the master project.For more information you can Ask a Question in theTech Community Forums.