diff --git a/docker/edge/docker-compose.yml b/docker/edge/docker-compose.yml index 188f974..a4c6a1f 100644 --- a/docker/edge/docker-compose.yml +++ b/docker/edge/docker-compose.yml @@ -6,16 +6,17 @@ networks: x-op-service-default: &service_default restart: always init: true + tty: true services: device-http: <<: *service_default build: - context: ../simulators - dockerfile: Dockerfile.http - image: daniviga/freedcs-device-http + context: ../simulator + dockerfile: Dockerfile + image: daniviga/freedcs-device-simulator environment: - IOT_HOST: "http://192.168.10.123:8000" + IOT_HTTP: "http://192.168.10.123:8000" # IOT_SERIAL: "abcd1234" # IOT_DELAY: 10 IOT_DEBUG: 1 @@ -25,14 +26,15 @@ services: device-mqtt: <<: *service_default build: - context: ../simulators - dockerfile: Dockerfile.mqtt - image: daniviga/freedcs-device-mqtt + context: ../simulator + dockerfile: Dockerfile + image: daniviga/freedcs-device-simulator environment: - IOT_HOST: "http://192.168.10.123:8000" - IOT_MQTT_HOST: "192.168.10.123:1883" + IOT_HTTP: "http://192.168.10.123:8000" + IOT_MQTT: "192.168.10.123:1883" # IOT_SERIAL: "abcd1234" # IOT_DELAY: 10 IOT_DEBUG: 1 + command: ["/opt/freedcs/device_simulator.py", "-t", "mqtt"] networks: - localnet diff --git a/docker/simulator/Dockerfile b/docker/simulator/Dockerfile new file mode 100644 index 0000000..5ec0069 --- /dev/null +++ b/docker/simulator/Dockerfile @@ -0,0 +1,7 @@ +FROM python:3.8-alpine + +RUN pip3 install urllib3 paho-mqtt +COPY ./device_simulator.py /opt/freedcs/device_simulator.py + +ENTRYPOINT ["python3"] +CMD ["/opt/freedcs/device_simulator.py"] diff --git a/docker/simulator/device_simulator.py b/docker/simulator/device_simulator.py new file mode 100644 index 0000000..7fff546 --- /dev/null +++ b/docker/simulator/device_simulator.py @@ -0,0 +1,115 @@ +#!/usr/bin/env python3 + +import os +import json +import string +import random +import datetime +import urllib3 +import argparse + +from time import sleep +import paho.mqtt.publish as publish + +DEBUG = bool(os.environ.get('IOT_DEBUG', False)) +http = urllib3.PoolManager() + + +def post_json(endpoint, 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', + endpoint + 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(endpoint, 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=endpoint.split(':')[0], + port=int(endpoint.split(':')[1]), + client_id=serial, + # auth=auth FIXME + ) + + +def main(): + parser = argparse.ArgumentParser( + description='IoT simulator oprions') + + parser.add_argument('-e', '--endpoint', + default=os.environ.get('IOT_HTTP', + 'http://127.0.0.1:8000'), + help='IoT HTTP endpoint') + parser.add_argument('-m', '--mqtt', + default=os.environ.get('IOT_MQTT', + '127.0.0.1:1883'), + help='IoT MQTT endpoint') + parser.add_argument('-t', '--transport', + choices=['mqtt', 'http'], + default=os.environ.get('IOT_TL', 'http'), + help='IoT transport layer') + parser.add_argument('-s', '--serial', + default=os.environ.get('IOT_SERIAL'), + help='IoT device serial number') + parser.add_argument('-d', '--delay', metavar='s', type=int, + default=os.environ.get('IOT_DELAY', 10), + help='Delay between requests') + args = parser.parse_args() + + subscribe = '/api/device/subscribe/' + telemetry = '/telemetry/' + + if args.serial is None: + args.serial = ''.join( + random.choices(string.ascii_lowercase + string.digits, k=8)) + + data = {'serial': args.serial} + post_json(args.endpoint, subscribe, data) + + data = { + 'device': args.serial, + 'clock': int(datetime.datetime.now().timestamp()), + } + + while True: + payload = { + 'id': 'device_simulator', + 'light': random.randint(300, 500), + 'temperature': { + 'celsius': round(random.uniform(20, 28), 1)} + } + if args.transport == 'http': + post_json(args.endpoint, telemetry, {**data, 'payload': payload}) + elif args.transport == 'mqtt': + publish_json(args.mqtt, {**data, 'payload': payload}) + else: + raise NotImplementedError + sleep(args.delay) + + +if __name__ == "__main__": + main() diff --git a/docker/simulators/Dockerfile.http b/docker/simulators/Dockerfile.http deleted file mode 100644 index ec666be..0000000 --- a/docker/simulators/Dockerfile.http +++ /dev/null @@ -1,6 +0,0 @@ -FROM python:3.8-alpine - -RUN pip3 install urllib3 -COPY ./simulator_http.py /opt/freedcs/simulator_http.py - -ENTRYPOINT ["python3", "/opt/freedcs/simulator_http.py"] diff --git a/docker/simulators/Dockerfile.mqtt b/docker/simulators/Dockerfile.mqtt deleted file mode 100644 index 3f890bd..0000000 --- a/docker/simulators/Dockerfile.mqtt +++ /dev/null @@ -1,6 +0,0 @@ -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_http.py b/docker/simulators/simulator_http.py deleted file mode 100644 index bcbfd29..0000000 --- a/docker/simulators/simulator_http.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 - -import os -import json -import string -import random -import datetime -import urllib3 -from time import sleep - -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 main(): - host = os.environ.get('IOT_HOST', 'http://127.0.0.1:8000') - subscribe = '/api/device/subscribe/' - telemetry = '/telemetry/' - 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_http_simulator', - 'light': random.randint(300, 500), - 'temperature': { - 'celsius': round(random.uniform(20, 28), 1)} - } - post_json(host, telemetry, {**data, 'payload': payload}) - sleep(delay) - - -if __name__ == "__main__": - main() diff --git a/docker/simulators/simulator_mqtt.py b/docker/simulators/simulator_mqtt.py deleted file mode 100644 index 733db13..0000000 --- a/docker/simulators/simulator_mqtt.py +++ /dev/null @@ -1,88 +0,0 @@ -#!/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()