diff --git a/README.md b/README.md index e9a2426..5be5026 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,8 @@ This project is for educational purposes only. It does not implement any authentication and/or encryption protocol, so it is not suitable for real production. +![Application Schema](./docs/application_chart.png) + ## Installation ### Requirements diff --git a/arduino/tempLightSensor/tempLightSensor.ino b/arduino/tempLightSensor/tempLightSensor.ino index 5891ca1..63c6d8a 100644 --- a/arduino/tempLightSensor/tempLightSensor.ino +++ b/arduino/tempLightSensor/tempLightSensor.ino @@ -55,7 +55,7 @@ struct netConfig { } config; char serial[9]; -const String apiURL = "/api/device/subscribe/"; +const String dpsURL = "/dps/device/subscribe/"; const String telemetryURL = "/telemetry/"; void setup(void) { @@ -63,7 +63,7 @@ void setup(void) { analogReference(EXTERNAL); - StaticJsonDocument<20> api; + StaticJsonDocument<20> dps; byte mac[6]; int eeAddress = 0; @@ -110,8 +110,8 @@ void setup(void) { Serial.println("DEBUG: clock updated via NTP."); #endif - api["serial"] = serial; - postData(config, apiURL, api); + dps["serial"] = serial; + postData(config, dpsURL, dps); telemetry["device"] = serial; // payload["id"] = serverName; diff --git a/bite/bite/local_settings.py.sample b/bite/bite/local_settings.py.sample new file mode 100644 index 0000000..1c573b2 --- /dev/null +++ b/bite/bite/local_settings.py.sample @@ -0,0 +1,20 @@ +DATABASES = { + 'default': { + 'ENGINE': 'django.db.backends.postgresql', + 'NAME': 'bite', + 'USER': 'bite', + 'PASSWORD': 'password', + 'HOST': 'localhost', + 'PORT': '5432', + } +} + +MQTT_BROKER = { + 'HOST': 'localhost', + 'PORT': '1883', +} + +KAFKA_BROKER = { + 'HOST': 'localhost', + 'PORT': '29092', +} diff --git a/bite/bite/settings.py b/bite/bite/settings.py index 8fc4ea3..8014f2c 100644 --- a/bite/bite/settings.py +++ b/bite/bite/settings.py @@ -61,7 +61,7 @@ INSTALLED_APPS = [ # 'health_check.storage', 'rest_framework', 'bite', - 'api', + 'dps', 'telemetry', ] @@ -167,11 +167,12 @@ KAFKA_BROKER = { 'PORT': '9092', } -# If no local_settings.py is availble in the current folder let's try to -# load it from the application root +try: + from bite.local_settings import * +except ImportError: + pass + try: from bite.production import * except ImportError: - # If a local_setting.py does not exist - # settings in this file only will be used pass diff --git a/bite/bite/urls.py b/bite/bite/urls.py index 878546a..b5ee9a7 100644 --- a/bite/bite/urls.py +++ b/bite/bite/urls.py @@ -37,13 +37,13 @@ from django.contrib import admin from django.conf import settings from django.urls import include, path -from api import urls as api_urls +from dps import urls as dps_urls from telemetry import urls as telemetry_urls urlpatterns = [ path('admin/', admin.site.urls), path('ht/', include('health_check.urls')), - path('api/', include(api_urls)), + path('dps/', include(dps_urls)), path('telemetry/', include(telemetry_urls)), ] diff --git a/bite/api/__init__.py b/bite/dps/__init__.py similarity index 100% rename from bite/api/__init__.py rename to bite/dps/__init__.py diff --git a/bite/api/admin.py b/bite/dps/admin.py similarity index 97% rename from bite/api/admin.py rename to bite/dps/admin.py index 9a83191..bd56cb9 100644 --- a/bite/api/admin.py +++ b/bite/dps/admin.py @@ -18,7 +18,7 @@ # along with this program. If not, see . from django.contrib import admin -from api.models import Device, WhiteList +from dps.models import Device, WhiteList @admin.register(Device) diff --git a/bite/api/apps.py b/bite/dps/apps.py similarity index 94% rename from bite/api/apps.py rename to bite/dps/apps.py index 63e4e00..5090321 100644 --- a/bite/api/apps.py +++ b/bite/dps/apps.py @@ -20,5 +20,5 @@ from django.apps import AppConfig -class ApiConfig(AppConfig): - name = 'api' +class DPSConfig(AppConfig): + name = 'dps' diff --git a/bite/api/migrations/0001_initial.py b/bite/dps/migrations/0001_initial.py similarity index 94% rename from bite/api/migrations/0001_initial.py rename to bite/dps/migrations/0001_initial.py index 0276db1..269131a 100644 --- a/bite/api/migrations/0001_initial.py +++ b/bite/dps/migrations/0001_initial.py @@ -1,6 +1,6 @@ # Generated by Django 3.1.3 on 2021-03-19 08:08 -import api.models +import dps.models from django.db import migrations, models import uuid @@ -16,7 +16,7 @@ class Migration(migrations.Migration): migrations.CreateModel( name='Device', fields=[ - ('serial', models.CharField(max_length=128, unique=True, validators=[api.models.device_validation])), + ('serial', models.CharField(max_length=128, unique=True, validators=[dps.models.device_validation])), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, primary_key=True, serialize=False)), ('creation_time', models.DateTimeField(auto_now_add=True)), ('updated_time', models.DateTimeField(auto_now=True)), diff --git a/bite/api/migrations/__init__.py b/bite/dps/migrations/__init__.py similarity index 100% rename from bite/api/migrations/__init__.py rename to bite/dps/migrations/__init__.py diff --git a/bite/api/models.py b/bite/dps/models.py similarity index 100% rename from bite/api/models.py rename to bite/dps/models.py diff --git a/bite/api/serializers.py b/bite/dps/serializers.py similarity index 96% rename from bite/api/serializers.py rename to bite/dps/serializers.py index 876f195..91ad6d4 100644 --- a/bite/api/serializers.py +++ b/bite/dps/serializers.py @@ -18,7 +18,7 @@ # along with this program. If not, see . from rest_framework import serializers -from api.models import Device, device_validation +from dps.models import Device, device_validation class DeviceSerializer(serializers.ModelSerializer): diff --git a/bite/api/tests.py b/bite/dps/tests.py similarity index 81% rename from bite/api/tests.py rename to bite/dps/tests.py index 1b787c4..2a030e1 100644 --- a/bite/api/tests.py +++ b/bite/dps/tests.py @@ -18,10 +18,10 @@ # along with this program. If not, see . from django.test import TestCase, Client -from api.models import Device, WhiteList +from dps.models import Device, WhiteList -class ApiTestCase(TestCase): +class DPSTestCase(TestCase): c = Client() def setUp(self): @@ -29,17 +29,17 @@ class ApiTestCase(TestCase): Device.objects.create(serial='test1234') def test_no_whitelist(self): - response = self.c.post('/api/device/subscribe/', + response = self.c.post('/dps/device/provision/', {'serial': 'test12345'}) self.assertEqual(response.status_code, 400) - def test_subscribe_post(self): + def test_provision_post(self): WhiteList.objects.create(serial='test12345') - response = self.c.post('/api/device/subscribe/', + response = self.c.post('/dps/device/provision/', {'serial': 'test12345'}) self.assertEqual(response.status_code, 201) - def test_subscribe_get(self): - response = self.c.get('/api/device/list/') + def test_provision_get(self): + response = self.c.get('/dps/device/list/') self.assertEqual( response.json()[0]['serial'], 'test1234') diff --git a/bite/api/tests/sample.json b/bite/dps/tests/sample.json similarity index 100% rename from bite/api/tests/sample.json rename to bite/dps/tests/sample.json diff --git a/bite/api/urls.py b/bite/dps/urls.py similarity index 88% rename from bite/api/urls.py rename to bite/dps/urls.py index cdcae17..6272de4 100644 --- a/bite/api/urls.py +++ b/bite/dps/urls.py @@ -33,13 +33,13 @@ Including another URLconf 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.urls import path -from api.views import APISubscribe +from dps.views import DPS urlpatterns = [ - path('device/subscribe/', - APISubscribe.as_view({'post': 'create'}), - name='device-subscribe'), + path('device/provision/', + DPS.as_view({'post': 'create'}), + name='device-provision'), path('device/list/', - APISubscribe.as_view({'get': 'list'}), + DPS.as_view({'get': 'list'}), name='device-list'), ] diff --git a/bite/api/views.py b/bite/dps/views.py similarity index 89% rename from bite/api/views.py rename to bite/dps/views.py index 4705e69..3c31e7c 100644 --- a/bite/api/views.py +++ b/bite/dps/views.py @@ -19,10 +19,10 @@ from rest_framework.viewsets import ModelViewSet -from api.models import Device -from api.serializers import DeviceSerializer +from dps.models import Device +from dps.serializers import DeviceSerializer -class APISubscribe(ModelViewSet): +class DPS(ModelViewSet): queryset = Device.objects.all() serializer_class = DeviceSerializer diff --git a/bite/telemetry/management/commands/dispatcher.py b/bite/telemetry/management/commands/dispatcher.py index a97beb6..abed5ae 100644 --- a/bite/telemetry/management/commands/dispatcher.py +++ b/bite/telemetry/management/commands/dispatcher.py @@ -31,7 +31,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist -from api.models import Device +from dps.models import Device class Command(BaseCommand): diff --git a/bite/telemetry/management/commands/handler.py b/bite/telemetry/management/commands/handler.py index f06a753..2502ee5 100644 --- a/bite/telemetry/management/commands/handler.py +++ b/bite/telemetry/management/commands/handler.py @@ -26,7 +26,7 @@ from django.conf import settings from django.core.management.base import BaseCommand from django.core.exceptions import ObjectDoesNotExist -from api.models import Device +from dps.models import Device from telemetry.models import Telemetry diff --git a/bite/telemetry/migrations/0001_initial.py b/bite/telemetry/migrations/0001_initial.py index 9a6222a..8d30fba 100644 --- a/bite/telemetry/migrations/0001_initial.py +++ b/bite/telemetry/migrations/0001_initial.py @@ -11,7 +11,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ - ('api', '0001_initial'), + ('dps', '0001_initial'), ] operations = [ @@ -23,7 +23,7 @@ class Migration(migrations.Migration): ('transport', models.CharField(choices=[('http', 'http'), ('mqtt', 'mqtt')], default='http', max_length=4)), ('clock', models.IntegerField(null=True, validators=[django.core.validators.MinValueValidator(0)])), ('payload', models.JSONField(validators=[telemetry.models.telemetry_validation])), - ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='api.device')), + ('device', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='dps.device')), ], options={ 'verbose_name_plural': 'Telemetry', diff --git a/bite/telemetry/models.py b/bite/telemetry/models.py index c7cafe9..3f7cec7 100644 --- a/bite/telemetry/models.py +++ b/bite/telemetry/models.py @@ -21,7 +21,7 @@ from django.db import models from django.core.validators import MinValueValidator from django.core.exceptions import ValidationError -from api.models import Device +from dps.models import Device def telemetry_validation(value): diff --git a/bite/telemetry/serializers.py b/bite/telemetry/serializers.py index d657682..251762e 100644 --- a/bite/telemetry/serializers.py +++ b/bite/telemetry/serializers.py @@ -18,7 +18,7 @@ # along with this program. If not, see . from rest_framework import serializers -from api.models import Device +from dps.models import Device from telemetry.models import Telemetry diff --git a/bite/telemetry/tests.py b/bite/telemetry/tests.py index f9f8034..468e50e 100644 --- a/bite/telemetry/tests.py +++ b/bite/telemetry/tests.py @@ -19,7 +19,7 @@ import json from django.test import TestCase, Client -from api.models import Device, WhiteList +from dps.models import Device, WhiteList class ApiTestCase(TestCase): diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index 5bf7abc..7b75d4a 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -37,8 +37,11 @@ services: - "${CUSTOM_DOCKER_IP:-0.0.0.0}:8000:8000" kafka: + environment: + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT ports: - - "${CUSTOM_DOCKER_IP:-0.0.0.0}:9092:9092" + - "${CUSTOM_DOCKER_IP:-0.0.0.0}:29092:29092" data-migration: volumes: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 5a74303..3a0d226 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -69,8 +69,6 @@ services: environment: ZOOKEEPER_CLIENT_PORT: 2181 ZOOKEEPER_TICK_TIME: 2000 - ports: - - 22181:2181 kafka: image: confluentinc/cp-kafka:latest @@ -81,8 +79,8 @@ services: environment: KAFKA_BROKER_ID: 1 KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181 - KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092,PLAINTEXT_HOST://localhost:29092 - KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT + KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092 + KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 diff --git a/docker/simulator/device_simulator.py b/docker/simulator/device_simulator.py index 6ffb1e6..822aade 100755 --- a/docker/simulator/device_simulator.py +++ b/docker/simulator/device_simulator.py @@ -114,7 +114,7 @@ def main(): ) args = parser.parse_args() - subscribe = "/api/device/subscribe/" + dps = "/dps/device/provision/" telemetry = "/telemetry/" if args.serial is None: @@ -123,7 +123,7 @@ def main(): ) data = {"serial": args.serial} - post_json(args.endpoint, subscribe, data) + post_json(args.endpoint, dps, data) while True: data = { diff --git a/docs/application_chart.odg b/docs/application_chart.odg index e5d4a33..e7ca904 100644 Binary files a/docs/application_chart.odg and b/docs/application_chart.odg differ diff --git a/docs/application_chart.png b/docs/application_chart.png index 5ba6e24..1d02671 100644 Binary files a/docs/application_chart.png and b/docs/application_chart.png differ diff --git a/esp32/rssiHall/rssiHall.ino b/esp32/rssiHall/rssiHall.ino index 8059ddb..378418a 100644 --- a/esp32/rssiHall/rssiHall.ino +++ b/esp32/rssiHall/rssiHall.ino @@ -55,13 +55,13 @@ struct netConfig { } config; char* serial; -const String apiURL = "/api/device/subscribe/"; +const String dpsURL = "/dps/device/subscribe/"; const String telemetryURL = "/telemetry/"; void setup(void) { Serial.begin(115200); - StaticJsonDocument<64> api; + StaticJsonDocument<64> dps; preferences.begin("iot"); // Get the serial number from flash @@ -117,8 +117,8 @@ void setup(void) { Serial.println("DEBUG: clock updated via NTP."); #endif - api["serial"] = serial; - postData(config, apiURL, api); + dps["serial"] = serial; + postData(config, dpsURL, dps); telemetry["device"] = serial; // payload["id"] = serverName;