diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 19a9a53..b8ffa96 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -7,7 +7,7 @@ volumes: pgdata: x-op-service-default: &service_default - restart: unless-stopped + restart: always # unless-stopped init: true services: @@ -44,15 +44,15 @@ services: # - net # ports: # - "1883:1883" - # - "9001:9001" + # # - "9001:9001" # mqtt via websocket rabbitmq: <<: *service_default image: rabbitmq:3-management-alpine - environment: - # RABBITMQ_DEFAULT_VHOST: "freedcs" - RABBITMQ_DEFAULT_USER: "freedcs" - RABBITMQ_DEFAULT_PASS: "password" + # environment: # we use unauth access atm + # RABBITMQ_DEFAULT_VHOST: "freedcs" + # RABBITMQ_DEFAULT_USER: "freedcs" + # RABBITMQ_DEFAULT_PASS: "password" volumes: - ./rabbitmq/enabled_plugins:/etc/rabbitmq/enabled_plugins networks: diff --git a/docker/edge/docker-compose.yml b/docker/edge/docker-compose.yml index 25d509e..188f974 100644 --- a/docker/edge/docker-compose.yml +++ b/docker/edge/docker-compose.yml @@ -4,12 +4,15 @@ networks: localnet: x-op-service-default: &service_default - restart: unless-stopped + restart: always init: true services: device-http: <<: *service_default + build: + context: ../simulators + dockerfile: Dockerfile.http image: daniviga/freedcs-device-http environment: IOT_HOST: "http://192.168.10.123:8000" @@ -18,3 +21,18 @@ services: IOT_DEBUG: 1 networks: - localnet + + device-mqtt: + <<: *service_default + build: + context: ../simulators + dockerfile: Dockerfile.mqtt + image: daniviga/freedcs-device-mqtt + environment: + IOT_HOST: "http://192.168.10.123:8000" + IOT_MQTT_HOST: "192.168.10.123:1883" + # IOT_SERIAL: "abcd1234" + # IOT_DELAY: 10 + IOT_DEBUG: 1 + networks: + - localnet diff --git a/docker/simulators/Dockerfile.mqtt b/docker/simulators/Dockerfile.mqtt new file mode 100644 index 0000000..3f890bd --- /dev/null +++ b/docker/simulators/Dockerfile.mqtt @@ -0,0 +1,6 @@ +FROM python:3.8-alpine + +RUN pip3 install paho-mqtt urllib3 +COPY ./simulator_mqtt.py /opt/freedcs/simulator_mqtt.py + +ENTRYPOINT ["python3", "/opt/freedcs/simulator_mqtt.py"] diff --git a/docker/simulators/simulator_mqtt.py b/docker/simulators/simulator_mqtt.py new file mode 100644 index 0000000..733db13 --- /dev/null +++ b/docker/simulators/simulator_mqtt.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 + +import os +import json +import string +import random +import datetime +import urllib3 +from time import sleep +import paho.mqtt.publish as publish + +DEBUG = bool(os.environ.get('IOT_DEBUG', False)) +http = urllib3.PoolManager() + + +def post_json(host, url, data): + json_data = json.dumps(data) + + if DEBUG: + print(json_data) + + encoded_data = json_data.encode('utf8') + + while True: + try: + r = http.request( + 'POST', + host + url, + body=encoded_data, + headers={'content-type': 'application/json'}) + return r + except urllib3.exceptions.MaxRetryError: + pass + + sleep(10) # retry in 10 seconds + + +def publish_json(host, data): + json_data = json.dumps(data) + serial = data['device'] + + if DEBUG: + print(json_data) + + encoded_data = json_data.encode('utf8') + + publish.single( + topic=serial, + payload=encoded_data, + hostname=host.split(':')[0], + port=int(host.split(':')[1]), + client_id=serial, + # auth=auth FIXME + ) + + +def main(): + host = os.environ.get('IOT_HOST', 'http://127.0.0.1:8000') + mqtt_host = os.environ.get('IOT_MQTT_HOST', '127.0.0.1:1883') + subscribe = '/api/device/subscribe/' + delay = int(os.environ.get('IOT_DELAY', 10)) + serial = os.environ.get('IOT_SERIAL') + + if serial is None: + serial = ''.join( + random.choices(string.ascii_lowercase + string.digits, k=8)) + + data = {'serial': serial} + post_json(host, subscribe, data) + + data = { + 'device': serial, + 'clock': int(datetime.datetime.now().timestamp()), + } + + while True: + payload = { + 'id': 'device_mqtt_simulator', + 'light': random.randint(300, 500), + 'temperature': { + 'celsius': round(random.uniform(20, 28), 1)} + } + publish_json(mqtt_host, {**data, 'payload': payload}) + sleep(delay) + + +if __name__ == "__main__": + main()