Configured customer broker
This commit is contained in:
@@ -1,5 +1,8 @@
|
||||
from flask import Flask
|
||||
|
||||
from src.controllers.mqtt_forwarder import MQTTForwarder
|
||||
from src.services.mqtt_service import MQTTService
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
@@ -9,4 +12,10 @@ def hello_world():
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run()
|
||||
|
||||
local_broker = MQTTService("127.0.0.1", 1883)
|
||||
api_broker = MQTTService("192.168.15.120", 8883)
|
||||
|
||||
forwarder = MQTTForwarder(local_broker, api_broker)
|
||||
|
||||
app.run(host="0.0.0.0", port=5000, debug=False)
|
||||
|
||||
@@ -3,11 +3,12 @@ version: "3.8"
|
||||
services:
|
||||
customer-api:
|
||||
build: .
|
||||
container_name: "Flask-API"
|
||||
container_name: "customer-api"
|
||||
ports:
|
||||
- "5000:5000"
|
||||
depends_on:
|
||||
- mongo
|
||||
- mosquitto
|
||||
environment:
|
||||
- MONGO_URI=mongodb://mongo:27017/mydb
|
||||
|
||||
@@ -22,4 +23,17 @@ services:
|
||||
- "27017:27017"
|
||||
volumes:
|
||||
- ./mongo-data:/data/db
|
||||
- ./mongo-init:/docker-entrypoint-initdb.d
|
||||
- ./mongo-init:/docker-entrypoint-initdb.d
|
||||
|
||||
mosquitto:
|
||||
image: eclipse-mosquitto:latest
|
||||
container_name: "customer-broker"
|
||||
ports:
|
||||
- "1883:1883"
|
||||
- "8883:8883"
|
||||
volumes:
|
||||
- ./mosquitto/config:/mosquitto/config
|
||||
- ./mosquitto/data:/mosquitto/data
|
||||
- ./mosquitto/log:/mosquitto/log
|
||||
- ./mosquitto/certs:/mosquitto/certs
|
||||
|
||||
|
||||
25
api-customer/mosquitto/certs/mosquitto.crt
Normal file
25
api-customer/mosquitto/certs/mosquitto.crt
Normal file
@@ -0,0 +1,25 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIEMTCCAxmgAwIBAgIUSj7h3y4SaFxuD6AeIkuZytZf8uEwDQYJKoZIhvcNAQEL
|
||||
BQAwgacxCzAJBgNVBAYTAkJFMREwDwYDVQQIDAhMacODwqhnZTERMA8GA1UEBwwI
|
||||
TGnDg8KoZ2UxDTALBgNVBAoMBEhFUEwxHDAaBgNVBAsME0JvYXJkIG1hdGUgY3Vz
|
||||
dG9tZXIxFzAVBgNVBAMMDjE5Mi4xNjguMTUuMTI1MSwwKgYJKoZIhvcNAQkBFh1s
|
||||
YXVyZW50LmNyZW1hQHN0dWRlbnQuaGVwbC5iZTAeFw0yNTEyMjkxMTE5MDZaFw0y
|
||||
NjEyMjkxMTE5MDZaMIGnMQswCQYDVQQGEwJCRTERMA8GA1UECAwITGnDg8KoZ2Ux
|
||||
ETAPBgNVBAcMCExpw4PCqGdlMQ0wCwYDVQQKDARIRVBMMRwwGgYDVQQLDBNCb2Fy
|
||||
ZCBtYXRlIGN1c3RvbWVyMRcwFQYDVQQDDA4xOTIuMTY4LjE1LjEyNTEsMCoGCSqG
|
||||
SIb3DQEJARYdbGF1cmVudC5jcmVtYUBzdHVkZW50LmhlcGwuYmUwggEiMA0GCSqG
|
||||
SIb3DQEBAQUAA4IBDwAwggEKAoIBAQDgRZbs1AKWZVdsytDagCRTtUrEasxzICMG
|
||||
8yTAz71dqZR2FXgEHVLTpVp6cFBRB3EeRxFdo1S8te0SJ5L6aAvQIhQyUY3QF5f7
|
||||
83AbauhjXIzvvnN/2RJhgU5VxRg1BTze2W3Ek3KND/GNbi6Sd+gACscjef5qnpYO
|
||||
xki4qZFB/tE5nRCtZy4/7AxKGDHwy89orWrEABOP54LyFppjjzItsUkZHb++jhU6
|
||||
lztKbjBydnEX3lusNw8jm1HdUaIJTuoD5az/tsQs+UjHTaFxt128YP+Bckpcegri
|
||||
C7D+wRLsonVI6P0NcoGG+yzQz0w6i0PTgTNifKyl0jRau9y4VAh/AgMBAAGjUzBR
|
||||
MB0GA1UdDgQWBBQcpMTyO6+JlsUUXDXTS/rFmO0ohzAfBgNVHSMEGDAWgBQcpMTy
|
||||
O6+JlsUUXDXTS/rFmO0ohzAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUA
|
||||
A4IBAQC5N6HhY4VMZp0gInSDZ1RrM08w3k4/3uqHa5MmRlYVb30KPy7T8wkARfiw
|
||||
FCtVojYSBbIIZeSoXKLRlSvHQvKij1sajZeOtGyb6p6x+LMWGuNJ3h6HfAzjIu53
|
||||
f/V4agfBp7Ljxi4T71jxvGISH7UFJs3kldQ9K737w8Wvb85CqqalzM5zVzltpHb/
|
||||
nNIzKZbqxXCGhtJu8Y4gi2bW+QjxaVCtYxY6jgy5J7KhJtZDoExHCXKFOYm8u1Bd
|
||||
N4J1o6M1udA4v3lHDr0dE5j7UvP7LIbhgCoGTOXaknm+UtqoKF2FKCPF2um5ral6
|
||||
Bxv7rANBb73Aw2g06OyHLq3Fc35k
|
||||
-----END CERTIFICATE-----
|
||||
28
api-customer/mosquitto/certs/mosquitto.key
Normal file
28
api-customer/mosquitto/certs/mosquitto.key
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgRZbs1AKWZVds
|
||||
ytDagCRTtUrEasxzICMG8yTAz71dqZR2FXgEHVLTpVp6cFBRB3EeRxFdo1S8te0S
|
||||
J5L6aAvQIhQyUY3QF5f783AbauhjXIzvvnN/2RJhgU5VxRg1BTze2W3Ek3KND/GN
|
||||
bi6Sd+gACscjef5qnpYOxki4qZFB/tE5nRCtZy4/7AxKGDHwy89orWrEABOP54Ly
|
||||
FppjjzItsUkZHb++jhU6lztKbjBydnEX3lusNw8jm1HdUaIJTuoD5az/tsQs+UjH
|
||||
TaFxt128YP+BckpcegriC7D+wRLsonVI6P0NcoGG+yzQz0w6i0PTgTNifKyl0jRa
|
||||
u9y4VAh/AgMBAAECggEAINWvag8ELfa6XQA4obTfHK5POwCT3EsZNbxFZkFD7UGV
|
||||
rdAo2Rld9gSggYqOB776Lb+j6DywfEx6YA0RNL4k9Jz4rgFIrO23X7jdcfYt/dYg
|
||||
AD229UHXshTXXjFUAPc6WTomGwCnZcWuzNET2nfZrJ/nVedXe06qk5EuNnMFBE8/
|
||||
GsiSuULI32KtlTBhO5TS9PmJfj1+CByQLcYSTG8k8VN9NXEB3kjbCMKgl0BfuALj
|
||||
Iwbbbz4ffrkzMkm0wXiq+Slad/50pIOPG1LU0KOmgaSv1sTI4hZqHJNRfig5IoP/
|
||||
8E/dNJCJOAVpgoQY+SbNmaGEQjB7Fvr/qDaH67BxsQKBgQD8aZ3czUbe7VUmlLJ7
|
||||
UavshgyGsox9O1Iwn2LAfP5IP441ODoqD8Wsup/P+c/zEboRlgAw/thPpVuXuXWj
|
||||
3tO7OuKUSUp0PW3mqDakSzQggxff+OSbHvXzNgzG4OwwM7V2yKQdVml375ACkqB2
|
||||
jdhoy9Rq8IFJ6W3cPLa1TDLFGQKBgQDjdZXGMjVv8sqhuuT+vXxLGtuhBp6dn/Ck
|
||||
Mlvo/QTwADcFO5IKZwT9wt0aUOLIbTub1ZdzbrWS1YCkn13EE98W7/T+DKgc8zG/
|
||||
KOIasy/U8sOFTr8o2ozCIl2umy833fRtB8IZQOaSa9UZb6Hr62do2i50FtJKSMGM
|
||||
kMt+ZSgVVwKBgCwOh0ZV8ivRAw7T339U1wxWrXMJUSo+o27nMwZkCsIzja/OW6Ch
|
||||
1h/7Bw/3C4viqTaOlwP2R21HcIBAF799kjlY4tl9HWjCnB8pdzggBD40g4NNXyGQ
|
||||
Ot+zrHE+KxuSuva7uKGCRrBveRRp4WYwBfjssuvjhL2Q5+MMGdv1K9tpAoGAXtOU
|
||||
n04rTQKRS5+Y/EKO4NjPm3AhDGGzdyCvhJCHUG8mgP32wnN0dz6X4vK5uQkhArSn
|
||||
MS6EcDSmLvtpoecO6IcdQhSQuZEBukoXCT6OwF58+MR9mVCTwhOFrtdvdgEId7P2
|
||||
TYTrGzvtWW9at/op4GKlXyxsex+d4TY0P/t4HH0CgYEA/Bet4dUNzBaHI5mP/vLH
|
||||
ntEkqXmV0KTiv1RlhrqqYVa9Ct9Dsl2L8TkzlObQ5B0vHVHsVLMSTiUFkE9HmEa9
|
||||
Tow0xmylB0PmOfXCwMBpsgh8iNqOrf8fsyIatTbG1nl3Qnbx+fFay8mnOIRZw59+
|
||||
Bc8O+xK3JTWZ9ybWbohZH7E=
|
||||
-----END PRIVATE KEY-----
|
||||
16
api-customer/mosquitto/config/mosquitto.conf
Normal file
16
api-customer/mosquitto/config/mosquitto.conf
Normal file
@@ -0,0 +1,16 @@
|
||||
persistence true
|
||||
persistence_location /mosquitto/data/
|
||||
|
||||
log_dest file /mosquitto/log/mosquitto.log
|
||||
|
||||
listener 1883
|
||||
|
||||
allow_anonymous false
|
||||
password_file /mosquitto/config/passwords
|
||||
|
||||
listener 8883
|
||||
protocol mqtt
|
||||
|
||||
certfile /mosquitto/certs/mosquitto.crt
|
||||
keyfile /mosquitto/certs/mosquitto.key
|
||||
tls_version tlsv1.2
|
||||
0
api-customer/mosquitto/config/passwords
Normal file
0
api-customer/mosquitto/config/passwords
Normal file
@@ -1 +1,2 @@
|
||||
flask
|
||||
flask
|
||||
paho-mqtt
|
||||
0
api-customer/src/__init__.py
Normal file
0
api-customer/src/__init__.py
Normal file
0
api-customer/src/controllers/__init__.py
Normal file
0
api-customer/src/controllers/__init__.py
Normal file
43
api-customer/src/controllers/mqtt_forwarder.py
Normal file
43
api-customer/src/controllers/mqtt_forwarder.py
Normal file
@@ -0,0 +1,43 @@
|
||||
import json
|
||||
import time
|
||||
|
||||
from src.services.mqtt_service import MQTTService
|
||||
|
||||
|
||||
class MQTTForwarder:
|
||||
|
||||
client_id : str
|
||||
local_broker : MQTTService
|
||||
central_broker : MQTTService
|
||||
|
||||
def __init__(self, client_id : str, local_mqtt: MQTTService, central_mqtt: MQTTService):
|
||||
self.client_id = client_id
|
||||
self.local_broker = local_mqtt
|
||||
self.central_broker = central_mqtt
|
||||
|
||||
def start(self):
|
||||
self.local_broker.subscribe("board-mate/", self.__forward)
|
||||
|
||||
def __forward(self, msg: str):
|
||||
self.central_broker.publish(self.client_id, f"/board-mate/${self.client_id}/telemetry", msg)
|
||||
|
||||
"""def start(self):
|
||||
self.local.subscribe("board-mate/+/telemetry", self.handle_message)
|
||||
|
||||
def handle_message(self, topic: str, payload: str):
|
||||
print(f"[FORWARD] {topic} -> central")
|
||||
|
||||
message = json.loads(payload)
|
||||
message["source"] = "client-server"
|
||||
message["forwarded_at"] = int(time.time())
|
||||
|
||||
self.central.publish(
|
||||
client_id="client-forwarder",
|
||||
topic=f"clients/{self.extract_client_id(topic)}/telemetry",
|
||||
data=json.dumps(message),
|
||||
qos=1
|
||||
)
|
||||
|
||||
def extract_client_id(self, topic: str) -> str:
|
||||
# ex: board-mate/pi-123/telemetry
|
||||
return topic.split("/")[1]"""
|
||||
0
api-customer/src/services/__init__.py
Normal file
0
api-customer/src/services/__init__.py
Normal file
55
api-customer/src/services/mqtt_service.py
Normal file
55
api-customer/src/services/mqtt_service.py
Normal file
@@ -0,0 +1,55 @@
|
||||
import json
|
||||
import time
|
||||
from typing import Callable
|
||||
|
||||
import paho.mqtt.client as mqtt
|
||||
from paho.mqtt.client import Client
|
||||
|
||||
|
||||
class MQTTService:
|
||||
|
||||
client : Client
|
||||
|
||||
def __init__(self, address: str, port: int):
|
||||
self.address = address
|
||||
self.port = port
|
||||
self.client = mqtt.Client()
|
||||
|
||||
def publish(self, client_id: str, topic: str, data: str, qos: int = 0):
|
||||
|
||||
try:
|
||||
self.__connect()
|
||||
|
||||
payload = {
|
||||
"timestamp": int(time.time()),
|
||||
"data": data
|
||||
}
|
||||
result = self.client.publish(topic, json.dumps(payload), qos=qos)
|
||||
result.wait_for_publish()
|
||||
|
||||
except Exception as e:
|
||||
print("MQTT error:", e)
|
||||
self.__disconnect()
|
||||
|
||||
def subscribe(self, topic: str, handler: Callable[[str], None]):
|
||||
def on_message(client, userdata, msg):
|
||||
handler(msg.payload.decode())
|
||||
|
||||
try:
|
||||
self.__connect()
|
||||
self.client.message_callback_add(topic, on_message)
|
||||
self.client.subscribe(topic)
|
||||
except Exception as e:
|
||||
print("MQTT error:", e)
|
||||
self.__disconnect()
|
||||
|
||||
|
||||
def __connect(self):
|
||||
if not self.client.is_connected():
|
||||
self.client.connect(self.address, self.port)
|
||||
self.client.loop_start()
|
||||
|
||||
def __disconnect(self):
|
||||
if self.client.is_connected():
|
||||
self.client.disconnect()
|
||||
self.client.loop_stop()
|
||||
Reference in New Issue
Block a user