1
0
mirror of https://github.com/daniviga/bite.git synced 2024-11-23 05:16:13 +01:00

Fix HTTP reverse proxy with embedded IoT (#20)

* Add an ENV far for custom docker binding

* Delay in Arduino can be customized

* Fix 400 error with Arduino telemetry and Nginx
This was caused by the client not waiting for a response.
Also Content-Length header was bogus.

* Do not crash mqtt-to-db if devices isn't proviosioned

* Update READMEs
This commit is contained in:
Daniele Viganò 2020-06-21 22:58:46 +02:00 committed by GitHub
parent 76c60d96dd
commit be4c226955
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 39 additions and 18 deletions

View File

@ -47,6 +47,10 @@ a [PostgreSQL](https://www.postgresql.org/) database with a timeseries extension
## Deployment ## Deployment
The `$CUSTOM_DOCKER_IP` environment variable can be used to set a custom
IP address to bind ports. Default is `0.0.0.0`; `127.0.0.1` is a
safe configuration (see https://github.com/docker/compose/issues/2999).
### Development ### Development
```bash ```bash
@ -149,7 +153,7 @@ The sketch reads temperature and light from sensors.
/* ... */ /* ... */
void loop(void) { void loop(void) {
const int postDelay = 10 * 1000; const int postDelay = TELEMETRY_DELAY * 1000;
unsigned int tempReading = analogRead(A0); unsigned int tempReading = analogRead(A0);
unsigned int photocellReading = analogRead(A1); unsigned int photocellReading = analogRead(A1);

View File

@ -52,7 +52,9 @@ The `EEPROM` can be completely erased setting the `ERASE_FIRST` macro to `1`.
The following macros are available in the firmware (to be set at compile time): The following macros are available in the firmware (to be set at compile time):
```c ```c
#define DEBUG_TO_SERIAL 1 // debug on serial port #define DEBUG_TO_SERIAL 0 // debug on serial port
#define USE_MQTT 1 // use mqtt protocol instead of http post #define USE_MQTT 1 // use mqtt protocol instead of http post
#define USE_INTERNAL_NTP 0 // use default ntp server or the internal one #define USE_INTERNAL_NTP 1 // use default ntp server or the internal one
#define TELEMETRY_DELAY 10 // second between telemetry samples
#define AREF_VOLTAGE 3.3 // set aref voltage to 3.3v instead of default 5v
``` ```

View File

@ -5,10 +5,11 @@
#include <NTPClient.h> #include <NTPClient.h>
#include <ArduinoJson.h> #include <ArduinoJson.h>
#define DEBUG_TO_SERIAL 1 // debug on serial port #define DEBUG_TO_SERIAL 0 // debug on serial port
#define USE_MQTT 1 // use mqtt protocol instead of http post #define USE_MQTT 1 // use mqtt protocol instead of http post
#define USE_INTERNAL_NTP 0 // use default ntp server or the internal one #define USE_INTERNAL_NTP 1 // use default ntp server or the internal one
#define AREF_VOLTAGE 3.3 // set aref voltage to 3.3v instead of default 5v #define TELEMETRY_DELAY 10 // second between telemetry samples
#define AREF_VOLTAGE 3.3 // set aref voltage to 3.3v instead of default 5v
char serial[9]; char serial[9];
@ -96,7 +97,7 @@ void setup(void) {
} }
void loop(void) { void loop(void) {
const int postDelay = 10 * 1000; const int postDelay = TELEMETRY_DELAY * 1000;
unsigned int tempReading = analogRead(A0); unsigned int tempReading = analogRead(A0);
unsigned int photocellReading = analogRead(A1); unsigned int photocellReading = analogRead(A1);
@ -161,7 +162,7 @@ void postData(const netConfig &postAPI, const String &URL, const DynamicJsonDocu
ethClient.println(postAPI.port); ethClient.println(postAPI.port);
ethClient.println("Content-Type: application/json"); ethClient.println("Content-Type: application/json");
ethClient.print("Content-Length: "); ethClient.print("Content-Length: ");
ethClient.println(measureJsonPretty(json)); ethClient.println(measureJson(json));
ethClient.println("Connection: close"); ethClient.println("Connection: close");
ethClient.println(); ethClient.println();
serializeJson(json, ethClient); serializeJson(json, ethClient);

View File

@ -8,6 +8,8 @@ from asyncio_mqtt import Client
from django.conf import settings from django.conf import settings
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.core.exceptions import ObjectDoesNotExist
from api.models import Device from api.models import Device
from telemetry.models import Telemetry from telemetry.models import Telemetry
@ -20,7 +22,10 @@ class Command(BaseCommand):
@sync_to_async @sync_to_async
def get_device(self, serial): def get_device(self, serial):
return Device.objects.get(serial=serial) try:
return Device.objects.get(serial=serial)
except ObjectDoesNotExist:
return None
@sync_to_async @sync_to_async
def store_telemetry(self, device, payload): def store_telemetry(self, device, payload):
@ -39,7 +44,12 @@ class Command(BaseCommand):
async for message in messages: async for message in messages:
payload = json.loads(message.payload.decode('utf-8')) payload = json.loads(message.payload.decode('utf-8'))
device = await self.get_device(message.topic) device = await self.get_device(message.topic)
await self.store_telemetry(device, payload) if device is not None:
await self.store_telemetry(device, payload)
else:
self.stdout.write(
self.style.ERROR(
'DEBUG: message discarded'))
def handle(self, *args, **options): def handle(self, *args, **options):
client = mqtt.Client() client = mqtt.Client()

View File

@ -7,15 +7,15 @@ services:
broker: broker:
ports: ports:
- "1883:1883" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:1883:1883"
- "9001:9001" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:9001:9001"
bite: bite:
volumes: volumes:
- ../bite:/srv/app/bite - ../bite:/srv/app/bite
command: ["python3", "manage.py", "runserver", "0.0.0.0:8000"] command: ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
ports: ports:
- "8000:8000" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:8000:8000"
data-migration: data-migration:
volumes: volumes:

View File

@ -20,7 +20,7 @@ services:
networks: networks:
- net - net
ports: ports:
- "123:123/udp" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:123:123/udp"
timescale: timescale:
<<: *service_default <<: *service_default
@ -41,13 +41,13 @@ services:
networks: networks:
- net - net
ports: ports:
- "1883:1883" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:1883:1883"
ingress: ingress:
<<: *service_default <<: *service_default
image: nginx:stable-alpine image: nginx:stable-alpine
ports: ports:
- "80:80" - "${CUSTOM_DOCKER_IP:-0.0.0.0}:80:80"
networks: networks:
- net - net
volumes: volumes:

View File

@ -51,6 +51,7 @@ http {
location / { location / {
proxy_pass http://bite; proxy_pass http://bite;
proxy_http_version 1.1;
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host:$server_port; proxy_set_header X-Forwarded-Host $host:$server_port;
@ -59,6 +60,9 @@ http {
proxy_read_timeout 300; proxy_read_timeout 300;
proxy_connect_timeout 300; proxy_connect_timeout 300;
## !- This is mandatory for IoT that do not wait for a reply -! ##
proxy_ignore_client_abort on;
} }
location /mqtt { location /mqtt {