I want to send a message in a JSON format from a IOT device using MQTT. The idea is to have several different values in that message and in some way extract those values and update multiple attributes of an asset from a single message. I have been able to update a single attribute by connecting to Openremotes MQTT API and posting to a topic in this format {realm}/{clientId}/attribute/{attributeName}/{assetId}
. I tried creating a MQTT Agent and subscribing to a topic such as “device/data” but I dont think I have configured it right because it seems that I cant post to that topic, as it seems the broker is denying it.
Im just in a testing phase of setting this up so Im doing it by a simple python script right now, this is what I have working for publishing to a single attribute (just showing what Ive got, I also have a script for publishing a JSON object with some different values):
"SEND MESSAGE EXAMPLE"
import ssl
import json
import time
import paho.mqtt.client as mqtt
#settings
BROKER_ADRESS = "localhost"
BROKER_PORT = 8883 #8883 for TLS
CLIENT_ID = "mqtt-client" #match the client id in keycloak, need to create it there, and following roles: mqtt-user, mqtt-publisher, mqtt-subscriber (mqtt-user to be able to communicate with broker) #pylint: disable=line-too-long
#https://docs.openremote.io/docs/user-guide/manager-apis#mqtt-api-mqtt-broker how to communicate with api and format the topic #pylint: disable=line-too-long
USERNAME = "custom:mqtt-client" #realm:clientid (not a service user created in the localhost/manager but in https://localhost/auth/admin/master/console/#/custom/roles) #pylint: disable=line-too-long
PASSWORD = "verysecret" #client secret for keycloak mqtt-user
REALM = "custom"
ATTRIBUTE_NAME = "IncrementValue" #the created attribute
ASSET_ID = "someid" #id for the asset
#topic format: {realm}/{clientId}/attribute/{attributeName}/{assetId} to use api as can be read in link above #pylint: disable=line-too-long
topic = f"{REALM}/{CLIENT_ID}/writeattributevalue/{ATTRIBUTE_NAME}/{ASSET_ID}"
#MQTT client setup
client = mqtt.Client(client_id=CLIENT_ID)
client.username_pw_set(username=USERNAME, password=PASSWORD)
#for TLS (might need to be improved but this works for now with CERT_NONE)
client.tls_set(cert_reqs=ssl.CERT_NONE)
client.tls_insecure_set(True)
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Connected successfully.")
elif rc == 5:
print("Connection refused: Not authorized")
else:
print(f"Connection failed with code {rc}")
def on_publish(client, userdata, mid):
print("Message published.")
def on_disconnect(client, userdata, rc):
print("Disconnected from broker.")
client.on_connect = on_connect
client.on_publish = on_publish
client.on_disconnect = on_disconnect
client.connect(BROKER_ADRESS, BROKER_PORT)
client.loop_start()
VALUE = 1
try:
while True:
payload = json.dumps(VALUE)
result = client.publish(topic, payload)
status = result[0]
if status == 0:
print(f"Published '{VALUE}' to topic '{topic}'")
else:
print(f"Failed to publish message to topic {topic}")
VALUE += 1
time.sleep(2)
except KeyboardInterrupt:
print("Publishing loop stopped.")
finally:
client.loop_stop()
client.disconnect()
I would greatly appreciate any help or information on how to solve my issue, which is to send multiple values in a single message and update multiple attributes of a asset. Im not quite sure how I should set up Openremote or what API to call to be able to send a message like this (if its even possible), nor how I should handle the message (variables in the JSON message) in my asset to get the value I want in the right attribute.
Best regards,
wokular