1
0
mirror of https://github.com/daniviga/bite.git synced 2024-11-26 14:56:13 +01:00
Go to file
2021-12-08 22:25:18 +01:00
.github/workflows Update codeql-analysis.yml 2020-10-25 11:40:15 +01:00
arduino Store ESP32 settings in the nvs 2021-03-24 21:54:41 +01:00
bite Remove Django 3.2 warnings 2021-10-02 18:41:19 +02:00
docker Make pytz dep explicit and update alpine 2021-12-08 19:15:38 +01:00
docs Update badges [skip ci] 2021-03-26 22:28:18 +01:00
esp32 Hyperscale (#25) 2021-03-26 22:17:53 +01:00
.gitignore Store ESP32 settings in the nvs 2021-03-24 21:54:41 +01:00
.gitmodules Implement the MQTT protocol (#11) 2020-06-08 23:17:16 +02:00
.travis.yml Make pull quiet in travis 2021-10-09 23:21:30 +02:00
LICENSE Initial commit 2020-05-29 14:20:21 +02:00
README.md Extend the readme 2021-12-08 22:25:18 +01:00
requirements-dev.txt Bootstrap Django project 2020-05-29 14:27:38 +02:00
requirements.txt Make pytz dep explicit and update alpine 2021-12-08 19:15:38 +01:00

BITE - A Basic/IoT/Example

Playing with IoT

Build Status AGPLv3 Python 3.9 MQTT Moby docker-compose 3.7+

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

Future implementations

Installation

Requirements

  • moby-engine or podman-docker (recommended)
  • docker-compose

The project is compatible with Docker for Windows (using Linux executors), but it is advised to directly use a minimal Linux VM instead (via the preferred hypervisor).

Podman

podman, with podman-docker is the recommended way to run BITE, in rootless mode.

Requirements are:

  • podman
  • podman-docker
  • catatonit
  • docker-compose

On Fedora 33+:

sudo dnf install -y podman podman-docker catatonit docker-compose

To setup podman run:

systemctl start --user podman.socket
export DOCKER_HOST=unix://run/user/$UID/podman/podman.sock

Application stack

The application stack is composed by the following components:

  • Django with Django REST framework web application (running via gunicorn in production mode)
    • mqtt-to-db custom daemon to dump telemetry into the timeseries database
    • telemetry payload is stored as json object (via PostgreSQL JSON data type)
  • Timescale DB, a PostgreSQL database with a timeseries extension
  • Mosquitto MQTT broker (see alternatives below)
  • Nginx as ingress for HTTP (see alternative below)
  • Chrony as NTP server (with optional MD5 encryption)

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, using image code

docker-compose -f docker/docker-compose.yml build
docker-compose -f docker/docker-compose.yml up -d [--scale {bite,mqtt-to-db)=N]

It exposes:

  • http://localhost:80 (HTTP and MQTT over Websockets)
  • tcp://localhost:1883 (MQTT)
  • udp://localhost:123 (NTP)

Django runs with DEBUG = True and SKIP_WHITELIST = True

Development with direct access to services and autoreload

docker-compose -f docker/docker-compose.yml -f docker-compose.dev.yml up -d [--scale {bite,mqtt-to-db)=N]

It exposes:

  • http://localhost:80 (HTTP and MQTT over Websockets)
  • http://localhost:8080 (Django's runserver)
  • tcp://localhost:1883 (MQTT)
  • tcp://localhost:9001 (MQTT over Websockets)
  • udp://localhost:123 (NTP)
  • tcp://localhost:5432 (PostgreSQL/Timescale)

Django runs with DEBUG = True and SKIP_WHITELIST = True

Production (kind of...)

docker-compose -f docker/docker-compose.yml -f docker-compose.prod.yml up -d [--scale {bite,mqtt-to-db)=N]

It exposes:

  • http://localhost:80 (HTTP and MQTT over Websockets)
  • tcp://localhost:1883 (MQTT)
  • udp://localhost:123 (NTP)

Django runs with DEBUG = False and SKIP_WHITELIST = False

Extra features

The project provides multiple modules that can be combined with the fore-mentioned configurations.

Traefik

To use Traefik instead of Nginx use:

docker-compose -f docker/docker-compose.yml up -f docker/ingress/docker-compose.traefik.yml -d

VerneMQ

A ~8x memory usage can be expected compared to Mosquitto.

To use VerneMQ instead of Mosquitto run:

docker-compose -f docker/docker-compose.yml up -f docker/mqtt/docker-compose.vernemq.yml -d

RabbitMQ

RabbitMQ does provide AMQP protocol too, but ingestion on the application side is not implemented yet. A ~10x memory usage can be expected compared to Mosquitto.

To use RabbitMQ (with the MQTT plugin enabled) instead of Mosquitto run:

docker-compose -f docker/docker-compose.yml up -f docker/mqtt/docker-compose.rabbitmq.yml -d

EDGE gateway simulation (via dind)

An EDGE gateway, with containers as modules, may be simulated via dind (docker-in-docker).

Start the EDGE

docker-compose -f docker/docker-compose.yml up -f docker/edge/docker-compose.edge.yml -d

Run the modules inside the EDGE

DOCKER_HOST='127.0.0.1:22375' docker-compose -f docker-compose.modules.yml up -d [--scale {device-http,device-ws,device-mqtt}=N]

Arduino

A simple Arduino UNO sketch is provided in the arduino/tempLightSensor folder. The sketch reads temperature and light from sensors.

/* ... */

void loop(void) {
  const int postDelay = TELEMETRY_DELAY * 1000;

  unsigned int tempReading = analogRead(A0);
  unsigned int photocellReading = analogRead(A1);

  float tempVoltage = tempReading * AREF_VOLTAGE / 1024.0;
  float tempC = (tempVoltage - 0.5) * 100 ;

  if (NTPValid) {
    telemetry["clock"] = timeClient.getEpochTime();
  } else {
    telemetry["clock"] = NULL; // converted into 0
  }
  payload["light"] = photocellReading;

  temp["celsius"] = tempC;
  temp["raw"] = tempReading;
  temp["volts"] = tempVoltage;

#if USE_MQTT
  publishData(config, telemetry);
#else
  postData(config, telemetryURL, telemetry);
#endif

/* ... */

Read more ...

Testing

Application tests are part of the Django suite:

python manage.py test

End-to-End tests are performed via Travis-CI. See .travis.yml for further explanations.