- Some better logging
- Split pairing into seperate class
This commit is contained in:
parent
a7fa0e665d
commit
cbffbc92a6
8 changed files with 124 additions and 33 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
||||||
/data
|
/data
|
||||||
|
__pycache__
|
Binary file not shown.
Binary file not shown.
|
@ -70,6 +70,19 @@ class MaDbHelper:
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def getAllUsers(self):
|
||||||
|
query = "SELECT username FROM `vmq_auth_acl`;"
|
||||||
|
|
||||||
|
self.mysqlCur.execute(
|
||||||
|
query
|
||||||
|
)
|
||||||
|
|
||||||
|
users = []
|
||||||
|
for user in self.mysqlCur:
|
||||||
|
users.append(user[0])
|
||||||
|
|
||||||
|
return users
|
||||||
|
|
||||||
def _updateUser(self, username, password, publishAclPatterns, subscribeAclPatterns):
|
def _updateUser(self, username, password, publishAclPatterns, subscribeAclPatterns):
|
||||||
|
|
||||||
query = """
|
query = """
|
||||||
|
|
|
@ -1,59 +1,69 @@
|
||||||
import paho.mqtt.client as mqtt
|
import paho.mqtt.client as mqtt
|
||||||
from dbHelper import MaDbHelper
|
from dbHelper import MaDbHelper
|
||||||
import random
|
from pairingHandler import MaPairingHandler
|
||||||
import string
|
import logging, coloredlogs
|
||||||
|
|
||||||
|
coloredlogs.install(level='INFO', fmt='%(asctime)s - [%(levelname)s] %(message)s')
|
||||||
|
|
||||||
class MlmAccess:
|
class MlmAccess:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
logging.info("=== MlmAccess ===")
|
||||||
|
|
||||||
self._initDb()
|
self._initDb()
|
||||||
self._initMqtt()
|
self._initMqtt()
|
||||||
|
|
||||||
|
self._pairingHanlder = MaPairingHandler(self._mqtt, self._db)
|
||||||
|
|
||||||
|
self._mqtt.loop_forever()
|
||||||
|
|
||||||
def _initDb(self):
|
def _initDb(self):
|
||||||
self.db = MaDbHelper()
|
logging.info("Initializing Database")
|
||||||
|
self._db = MaDbHelper()
|
||||||
initUsers = [
|
initUsers = [
|
||||||
("backend", "backend", ["mlmAccess/#"], ["mlmAccess/#"]),
|
("backend", "backend", ["mlmAccess/#"], ["mlmAccess/#"]),
|
||||||
("pair-actor", "pair-actor", ["mlmAccess/pair/request/actor"], ["mlmAccess/pair/response/actor"])
|
("pair-actor", "pair-actor", ["mlmAccess/pair/request/actor"], ["mlmAccess/pair/response/actor"])
|
||||||
]
|
]
|
||||||
|
|
||||||
for username, password, publishAclPatterns, subscribeAclPatterns in initUsers:
|
for username, password, publishAclPatterns, subscribeAclPatterns in initUsers:
|
||||||
if not self.db.addUser(username, password, publishAclPatterns, subscribeAclPatterns):
|
if not self._db.addUser(username, password, publishAclPatterns, subscribeAclPatterns):
|
||||||
self.db.updateUser(username, password, publishAclPatterns, subscribeAclPatterns)
|
self._db.updateUser(username, password, publishAclPatterns, subscribeAclPatterns)
|
||||||
|
|
||||||
def _initMqtt(self):
|
def _initMqtt(self):
|
||||||
self.mqtt = client = mqtt.Client(client_id="backend")
|
logging.info("Initializing MQTT")
|
||||||
self.mqtt.username_pw_set("backend", "backend")
|
self._mqtt = client = mqtt.Client(client_id="backend")
|
||||||
|
self._mqtt.username_pw_set("backend", "backend")
|
||||||
|
|
||||||
self.mqtt.on_connect = self._mqttOnConnect
|
self._mqtt.on_connect = self._mqttOnConnect
|
||||||
self.mqtt.on_message = self._mqttOnMessage
|
self._mqtt.on_message = self._mqttOnMessage
|
||||||
|
|
||||||
print("connecting to broker")
|
self._mqtt.connect("localhost", 1883, 60)
|
||||||
print(self.mqtt.connect("localhost", 1883, 60))
|
|
||||||
|
|
||||||
self.mqtt.loop_forever()
|
|
||||||
|
|
||||||
def _handleActorPairRequest(self, id):
|
|
||||||
print(f"Pair request for type actor with ID {id}")
|
|
||||||
if not self.db.userExists(f"actor-{id}"):
|
|
||||||
password = ''.join(random.choices(string.ascii_uppercase + string.digits, k=10))
|
|
||||||
self.db.addUser(f"actor-{id}", password, [f"mlmAccess/actor/{id}/status"], [f"mlmAccess/actor/{id}/action"])
|
|
||||||
|
|
||||||
self.mqtt.publish("mlmAccess/pair/response/actor", password)
|
|
||||||
else:
|
|
||||||
self.mqtt.publish("mlmAccess/pair/response/actor", "")
|
|
||||||
|
|
||||||
def _mqttOnConnect(self, client, userdata, flags, rc):
|
def _mqttOnConnect(self, client, userdata, flags, rc):
|
||||||
print("Connected with result code "+str(rc))
|
|
||||||
|
|
||||||
if rc != 0:
|
if rc != 0:
|
||||||
print("")
|
logging.error(f"Error connecting to MQTT broker: {rc}")
|
||||||
|
return
|
||||||
|
|
||||||
print(client.subscribe("mlmAccess/pair/request/actor"))
|
logging.info("Successfully connected to MQTT broker")
|
||||||
|
|
||||||
|
logging.info("Subscribing to actor subjects:")
|
||||||
|
for user in self._db.getAllUsers():
|
||||||
|
if user.startswith("actor-"):
|
||||||
|
actorSubject = f"mlmAccess/actor/{user.replace('actor-', '')}/status"
|
||||||
|
logging.info(f"* {actorSubject}")
|
||||||
|
client.subscribe(actorSubject)
|
||||||
|
|
||||||
|
# call hooks of child objects
|
||||||
|
self._pairingHanlder._mqttOnConnect(client, userdata, flags, rc)
|
||||||
|
|
||||||
def _mqttOnMessage(self, client, userdata, message):
|
def _mqttOnMessage(self, client, userdata, message):
|
||||||
if message.topic == "mlmAccess/pair/request/actor":
|
topic = message.topic
|
||||||
self._handleActorPairRequest(str(message.payload.decode("utf-8")))
|
topic = topic.replace("mlmAccess/", "")
|
||||||
|
messageContent = str(message.payload.decode("utf-8"))
|
||||||
|
|
||||||
|
logging.info(f"Message on topic {topic}: {messageContent}")
|
||||||
|
|
||||||
|
if topic.startswith("pair"):
|
||||||
|
self._pairingHanlder.handlePairingRequest(topic, messageContent)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
MlmAccess()
|
MlmAccess()
|
26
backend/pairingHandler.py
Normal file
26
backend/pairingHandler.py
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import random, string, logging
|
||||||
|
|
||||||
|
class MaPairingHandler:
|
||||||
|
def __init__(self, mqtt, db):
|
||||||
|
self._mqtt = mqtt
|
||||||
|
self._db = db
|
||||||
|
|
||||||
|
def handlePairingRequest(self, topic, message):
|
||||||
|
if "actor" in topic:
|
||||||
|
self._handleActorPairRequest(message)
|
||||||
|
else:
|
||||||
|
logging.warn(f"Invalid pairing request: {topic}, {message}, Device type not know.")
|
||||||
|
|
||||||
|
def _handleActorPairRequest(self, id):
|
||||||
|
logging.info(f"Pair request for type actor with ID {id}")
|
||||||
|
if not self._db.userExists(f"actor-{id}"):
|
||||||
|
logging.info(f"Pair request {id} accepted")
|
||||||
|
password = ''.join(random.choices(string.ascii_uppercase + string.ascii_lowercase + string.digits, k=20))
|
||||||
|
self._db.addUser(f"actor-{id}", password, [f"mlmAccess/actor/{id}/status"], [f"mlmAccess/actor/{id}/action"])
|
||||||
|
self._mqtt.publish("mlmAccess/pair/response/actor", password)
|
||||||
|
else:
|
||||||
|
logging.warning(f"Rejecting pair request for ID {id}: ID already exists")
|
||||||
|
self._mqtt.publish("mlmAccess/pair/response/actor", "")
|
||||||
|
|
||||||
|
def _mqttOnConnect(self, client, userdata, flags, rc):
|
||||||
|
client.subscribe("mlmAccess/pair/request/actor")
|
41
mock-actor/mock-actor-pair.py
Normal file
41
mock-actor/mock-actor-pair.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import paho.mqtt.client as mqtt
|
||||||
|
import logging, coloredlogs
|
||||||
|
|
||||||
|
coloredlogs.install(level='INFO', fmt='%(asctime)s - [%(levelname)s] %(message)s')
|
||||||
|
|
||||||
|
PAIR_ID = "106"
|
||||||
|
|
||||||
|
def on_connect(client, userdata, flags, rc):
|
||||||
|
global PAIR_ID
|
||||||
|
|
||||||
|
if rc != 0:
|
||||||
|
logging.error(f"Error connecting to MQTT broker: {rc}")
|
||||||
|
return
|
||||||
|
|
||||||
|
logging.info("Successfully connected to MQTT broker")
|
||||||
|
|
||||||
|
client.subscribe("mlmAccess/pair/response/actor")
|
||||||
|
|
||||||
|
logging.info("Requesting pairing")
|
||||||
|
client.publish("mlmAccess/pair/request/actor", PAIR_ID)
|
||||||
|
|
||||||
|
def on_message(client, userdata, message):
|
||||||
|
messageContent = str(message.payload.decode("utf-8"))
|
||||||
|
|
||||||
|
if len(messageContent) > 0:
|
||||||
|
logging.info(f"Pairing was successfull! The password is: {messageContent}")
|
||||||
|
exit(0)
|
||||||
|
else:
|
||||||
|
logging.error("Pairing was not successfull!")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
client = mqtt.Client(client_id="pair-actor")
|
||||||
|
client.username_pw_set("pair-actor", "pair-actor")
|
||||||
|
|
||||||
|
client.on_connect = on_connect
|
||||||
|
client.on_message = on_message
|
||||||
|
|
||||||
|
logging.info("Initializing MQTT")
|
||||||
|
client.connect("localhost", 1883, 60)
|
||||||
|
|
||||||
|
client.loop_forever()
|
|
@ -6,9 +6,9 @@ def on_connect(client, userdata, flags, rc):
|
||||||
# Subscribing in on_connect() means that if we lose the connection and
|
# Subscribing in on_connect() means that if we lose the connection and
|
||||||
# reconnect then subscriptions will be renewed.
|
# reconnect then subscriptions will be renewed.
|
||||||
print("Subscribing to topic","mlmAccess/pair/response/actor")
|
print("Subscribing to topic","mlmAccess/pair/response/actor")
|
||||||
print(client.subscribe("mlmAccess/pair/response/actor"))
|
print(client.subscribe("mlmAccess/actor/102/action"))
|
||||||
print("Publishing message to topic","mlmAccess/pair/request/actor")
|
print("Publishing message to topic","mlmAccess/pair/request/actor")
|
||||||
print(client.publish("mlmAccess/pair/request/actor", "101"))
|
print(client.publish("mlmAccess/actor/102/status", "0", retain=True))
|
||||||
|
|
||||||
def on_message(client, userdata, message):
|
def on_message(client, userdata, message):
|
||||||
print("message received " ,str(message.payload.decode("utf-8")))
|
print("message received " ,str(message.payload.decode("utf-8")))
|
||||||
|
@ -16,8 +16,8 @@ def on_message(client, userdata, message):
|
||||||
print("message qos=",message.qos)
|
print("message qos=",message.qos)
|
||||||
print("message retain flag=",message.retain)
|
print("message retain flag=",message.retain)
|
||||||
|
|
||||||
client = mqtt.Client(client_id="pair-actor")
|
client = mqtt.Client(client_id="actor-102")
|
||||||
client.username_pw_set("pair-actor", "pair-actor")
|
client.username_pw_set("actor-102", "YWT2JPOEZH")
|
||||||
|
|
||||||
client.on_connect = on_connect
|
client.on_connect = on_connect
|
||||||
client.on_message = on_message
|
client.on_message = on_message
|
||||||
|
|
Loading…
Reference in a new issue