Alexa Skill als MQTT Publisher

Hier wird über die Entwicklung von Skills diskutiert.
Antworten
Benutzeravatar

Themenstarter
Faris
Beiträge: 2
Registriert: Do 6. Sep 2018, 12:55

Do 6. Sep 2018, 13:06

Hallo zusammen,

ich wende mich nun an euch, da ich nicht mehr weiter komme, bzw mich im Kreis drehe.
Ich versuche, einen Alexa-Skill zu schreiben, welcher einen Post zu einem MQTT-Thema postet, welches ich von einem Linux-System aus hoste.

Das MQTT-Topic ist von außen erreichbar (über Port 1883). Dies habe ich bereits getestet. Ich kann von jedem anderen System (bspw. über ein Python-Skript oder über Mosquitto(Linux)) Beiträge "publishen".

Nun möchte ich über eine AWS-Lambda Funktion, Beiträge publishen. Wie ein Skill erstellt und mit einer Lambda Funktion verknüpft wird weiß ich nun.
Auch hatte ich versucht, ein funktionierende Python Programm in das AWS einzubinden. Ich habe es mit dieser Ordnerstruktur versucht Paho MQTT Python (diese natürlich auch angepasst, nur leider erziele ich keinen Erfolg).
Hierzu habe ich das Exampe "alexa-skills-kit-color-expert-python" von AWS genutzt und wollte an eine gegebene Stelle ein Publish hervorrufen.

Also wenn ich es schaffe, einfach aus einem Befehl heraus einen Post zu publishen ,dann wäre ich schon glücklich.
Bei der Suche im Forum wurde ich leider nicht fündig. Im Netz gibt es das ein oder andere Tutorial, diese sind aber meist eher kompliziert für mich bzw. "sehr aufwendig".

Es wäre super, wenn mir jemand helfen könnte! :)

Danke im Voraus!
Gruß
Zuletzt geändert von Faris am Do 6. Sep 2018, 14:50, insgesamt 3-mal geändert.
0 x
Benutzeravatar

Themenstarter
Faris
Beiträge: 2
Registriert: Do 6. Sep 2018, 12:55

Do 6. Sep 2018, 14:51

Hab es jetzt hiermit geschafft, Posts zu machen. Damit ist meine Frage eigentlich schon selbst beantwortet :-D

Aber falls es jemanden interessiert, ich habe es tatsächlich mit dem Python Code von https://github.com/eclipse/paho.mqtt.python geschafft.
Hierzu habe ich im oberesten Pfad (da wo src als Ordner vorhanden ist) eine Datei Namens "publisher.py" erstellt.

Den Code habe ich aus "publish.py" und "publish_single.py" zusammengewürfelt. Eigentlich gehopst wie gesprungen, aber so klappt es nun schonmal, dass bei Aufruf der Lambda-Funktion eine Nachricht zu einem Topic gepostet wird. Hierzu muss in der letzten Zeile lediglich Host und Topic eingetragen werden.

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-



#import paho.mqtt.publish as publish

"""
This module provides some helper functions to allow straightforward publishing
of messages in a one-shot manner. In other words, they are useful for the
situation where you have a single/multiple messages you want to publish to a
broker, then disconnect and nothing else is required.
"""

import paho.mqtt.client as paho


def _do_publish(client):
"""Internal function"""

message = client._userdata.pop()

if isinstance(message, dict):
client.publish(**message)
elif isinstance(message, tuple):
client.publish(*message)
else:
raise ValueError('message must be a dict or a tuple')


def _on_connect(client, userdata, flags, rc):
"""Internal callback"""
#pylint: disable=invalid-name, unused-argument

if rc == 0:
if len(userdata) > 0:
_do_publish(client)
else:
raise mqtt.MQTTException(paho.connack_string(rc))


def _on_publish(client, userdata, mid):
"""Internal callback"""
#pylint: disable=unused-argument

if len(userdata) == 0:
client.disconnect()
else:
_do_publish(client)


def multiple(msgs, hostname="localhost", port=1883, client_id="", keepalive=60,
will=None, auth=None, tls=None, protocol=paho.MQTTv311,
transport="tcp"):
"""Publish multiple messages to a broker, then disconnect cleanly.

This function creates an MQTT client, connects to a broker and publishes a
list of messages. Once the messages have been delivered, it disconnects
cleanly from the broker.

msgs : a list of messages to publish. Each message is either a dict or a
tuple.

If a dict, only the topic must be present. Default values will be
used for any missing arguments. The dict must be of the form:

msg = {'topic':"<topic>", 'payload':"<payload>", 'qos':<qos>,
'retain':<retain>}
topic must be present and may not be empty.
If payload is "", None or not present then a zero length payload
will be published.
If qos is not present, the default of 0 is used.
If retain is not present, the default of False is used.

If a tuple, then it must be of the form:
("<topic>", "<payload>", qos, retain)

hostname : a string containing the address of the broker to connect to.
Defaults to localhost.

port : the port to connect to the broker on. Defaults to 1883.

client_id : the MQTT client id to use. If "" or None, the Paho library will
generate a client id automatically.

keepalive : the keepalive timeout value for the client. Defaults to 60
seconds.

will : a dict containing will parameters for the client: will = {'topic':
"<topic>", 'payload':"<payload">, 'qos':<qos>, 'retain':<retain>}.
Topic is required, all other parameters are optional and will
default to None, 0 and False respectively.
Defaults to None, which indicates no will should be used.

auth : a dict containing authentication parameters for the client:
auth = {'username':"<username>", 'password':"<password>"}
Username is required, password is optional and will default to None
if not provided.
Defaults to None, which indicates no authentication is to be used.

tls : a dict containing TLS configuration parameters for the client:
dict = {'ca_certs':"<ca_certs>", 'certfile':"<certfile>",
'keyfile':"<keyfile>", 'tls_version':"<tls_version>",
'ciphers':"<ciphers">}
ca_certs is required, all other parameters are optional and will
default to None if not provided, which results in the client using
the default behaviour - see the paho.mqtt.client documentation.
Alternatively, tls input can be an SSLContext object, which will be
processed using the tls_set_context method.
Defaults to None, which indicates that TLS should not be used.

transport : set to "tcp" to use the default setting of transport which is
raw TCP. Set to "websockets" to use WebSockets as the transport.
"""

if not isinstance(msgs, list):
raise ValueError('msgs must be a list')

client = paho.Client(client_id=client_id,
userdata=msgs, protocol=protocol, transport=transport)

client.on_publish = _on_publish
client.on_connect = _on_connect

if auth:
username = auth.get('username')
if username:
password = auth.get('password')
client.username_pw_set(username, password)
else:
raise KeyError("The 'username' key was not found, this is "
"required for auth")

if will is not None:
client.will_set(**will)

if tls is not None:
if isinstance(tls, dict):
client.tls_set(**tls)
else:
# Assume input is SSLContext object
client.tls_set_context(tls)

client.connect(hostname, port, keepalive)
client.loop_forever()


def single(topic, payload=None, qos=0, retain=False, hostname="localhost",
port=1883, client_id="", keepalive=60, will=None, auth=None,
tls=None, protocol=paho.MQTTv311, transport="tcp"):
"""Publish a single message to a broker, then disconnect cleanly.

This function creates an MQTT client, connects to a broker and publishes a
single message. Once the message has been delivered, it disconnects cleanly
from the broker.

topic : the only required argument must be the topic string to which the
payload will be published.

payload : the payload to be published. If "" or None, a zero length payload
will be published.

qos : the qos to use when publishing, default to 0.

retain : set the message to be retained (True) or not (False).

hostname : a string containing the address of the broker to connect to.
Defaults to localhost.

port : the port to connect to the broker on. Defaults to 1883.

client_id : the MQTT client id to use. If "" or None, the Paho library will
generate a client id automatically.

keepalive : the keepalive timeout value for the client. Defaults to 60
seconds.

will : a dict containing will parameters for the client: will = {'topic':
"<topic>", 'payload':"<payload">, 'qos':<qos>, 'retain':<retain>}.
Topic is required, all other parameters are optional and will
default to None, 0 and False respectively.
Defaults to None, which indicates no will should be used.

auth : a dict containing authentication parameters for the client:
auth = {'username':"<username>", 'password':"<password>"}
Username is required, password is optional and will default to None
if not provided.
Defaults to None, which indicates no authentication is to be used.

tls : a dict containing TLS configuration parameters for the client:
dict = {'ca_certs':"<ca_certs>", 'certfile':"<certfile>",
'keyfile':"<keyfile>", 'tls_version':"<tls_version>",
'ciphers':"<ciphers">}
ca_certs is required, all other parameters are optional and will
default to None if not provided, which results in the client using
the default behaviour - see the paho.mqtt.client documentation.
Defaults to None, which indicates that TLS should not be used.
Alternatively, tls input can be an SSLContext object, which will be
processed using the tls_set_context method.

transport : set to "tcp" to use the default setting of transport which is
raw TCP. Set to "websockets" to use WebSockets as the transport.
"""

msg = {'topic':topic, 'payload':payload, 'qos':qos, 'retain':retain}

multiple([msg], hostname, port, client_id, keepalive, will, auth, tls,
protocol, transport)

#######################################################################

single("XXX", "hallo von lambda aws", hostname="XXX")
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""


Nun ist die Konnektivität hergestellt und ich kann einen Code schreiben, welcher Anfragen unterscheidet und auf dieser Basis verschiedene MQTT-Nachrichten postet.

Gruß
1 x
Antworten

Zurück zu „Fähigkeiten (Skills) entwickeln“

  • Information