Skip to content

Commit

Permalink
Merge pull request #27 from steersbob/feature/service-setup
Browse files Browse the repository at this point in the history
feature/service setup
  • Loading branch information
steersbob authored Aug 1, 2023
2 parents 0a561a8 + f5a97a9 commit e182630
Show file tree
Hide file tree
Showing 18 changed files with 889 additions and 726 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv/
.vscode/
23 changes: 16 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ on:
branches: ["**"]
pull_request:
branches: [develop, edge]
workflow_dispatch: {}

env:
DOCKER_IMAGE: ghcr.io/brewblox/brewblox-tilt

jobs:
build:
Expand All @@ -23,7 +27,7 @@ jobs:
id: meta
uses: docker/metadata-action@v4
with:
images: ghcr.io/brewblox/brewblox-tilt
images: ${{ env.DOCKER_IMAGE }}

- name: ghcr.io login
uses: docker/login-action@v2
Expand All @@ -33,10 +37,15 @@ jobs:
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Install dependencies
- name: Install Apt dependencies
run: >
sudo apt update &&
sudo apt install -y --no-install-recommends
libbluetooth-dev
libatlas-base-dev
- name: Install Python dependencies
run: |
sudo apt update
sudo apt install -y libbluetooth-dev
python -m pip install --upgrade pip
pip install poetry wheel
poetry install
Expand All @@ -46,9 +55,9 @@ jobs:
poetry run pytest
poetry run flake8
- name: Run setup script
- name: Build
run: |
bash docker/before_build.sh
poetry run invoke build
- name: Build Docker image
uses: docker/build-push-action@v4
Expand All @@ -57,4 +66,4 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
context: docker
context: .
12 changes: 4 additions & 8 deletions docker/Dockerfile → Dockerfile
Original file line number Diff line number Diff line change
@@ -1,23 +1,19 @@
FROM python:3.9 as base
FROM python:3.9-bullseye as base

ENV PIP_EXTRA_INDEX_URL=https://www.piwheels.org/simple
ENV PIP_FIND_LINKS=/wheeley

COPY ./dist /app/dist
COPY ./requirements.txt /app/requirements.txt

RUN set -ex \
&& mkdir /wheeley \
&& pip3 install --upgrade pip wheel \
&& pip3 wheel --wheel-dir=/wheeley -r /app/requirements.txt \
&& pip3 wheel --wheel-dir=/wheeley /app/dist/*
&& pip3 wheel --wheel-dir=/wheeley -r /app/dist/requirements.txt \
&& pip3 wheel --wheel-dir=/wheeley /app/dist/*.tar.gz

FROM python:3.9-slim
FROM python:3.9-slim-bullseye
WORKDIR /app

ARG service_info=UNKNOWN
ENV SERVICE_INFO=${service_info}

COPY --from=base /wheeley /wheeley

RUN set -ex \
Expand Down
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,12 @@ sudo apt update && sudo apt install -y libbluetooth-dev
To build a local Docker image:

```bash
bash docker/before_build.sh
docker build --tag brewblox/brewblox-tilt:local docker
poetry run invoke local-docker
```

A `docker-compose.yml` file that uses `brewblox/brewblox-tilt:local` is present in the repository root.
This builds the Python package and then the Dockerfile as `ghcr.io/brewblox/brewblox-tilt:local`.

A `docker-compose.yml` file that uses `ghcr.io/brewblox/brewblox-tilt:local` is present in the repository root.

To start it, run:

Expand Down
26 changes: 14 additions & 12 deletions brewblox_tilt/__main__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
from brewblox_service import mqtt, scheduler, service

from brewblox_tilt import broadcaster, broadcaster_sim
from brewblox_tilt.models import ServiceConfig


def create_parser(default_name='tilt'):
parser = service.create_parser(default_name=default_name)
def create_parser():
parser = service.create_parser('tilt')

parser.add_argument('--lower-bound',
help='Lower bound of acceptable SG values. '
Expand Down Expand Up @@ -37,20 +38,21 @@ def create_parser(default_name='tilt'):


def main():
app = service.create_app(parser=create_parser())
config = app['config']
parser = create_parser()
config = service.create_config(parser, model=ServiceConfig)
app = service.create_app(config)

scheduler.setup(app)
mqtt.setup(app)
async def setup():
scheduler.setup(app)
mqtt.setup(app)

if config['simulate'] is not None:
broadcaster_sim.setup(app)
else:
broadcaster.setup(app)
if config.simulate is not None:
broadcaster_sim.setup(app)
else:
broadcaster.setup(app)

# We have no meaningful REST API, so we set listen_http to False
service.furnish(app)
service.run(app, listen_http=False)
service.run_app(app, setup(), listen_http=False)


if __name__ == '__main__':
Expand Down
13 changes: 7 additions & 6 deletions brewblox_tilt/broadcaster.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from brewblox_service import brewblox_logger, features, mqtt, repeater

from brewblox_tilt import const, parser
from brewblox_tilt.models import ServiceConfig

LOGGER = brewblox_logger(__name__)

Expand All @@ -25,12 +26,12 @@ class Broadcaster(repeater.RepeaterFeature):
def __init__(self, app: web.Application):
super().__init__(app)

config = app['config']
self.name = config['name']
self.inactive_scan_interval = max(config['inactive_scan_interval'], 0)
self.active_scan_interval = max(config['active_scan_interval'], 0)
self.state_topic = config['state_topic'] + f'/{self.name}'
self.history_topic = config['history_topic'] + f'/{self.name}'
config: ServiceConfig = app['config']
self.name = config.name
self.inactive_scan_interval = max(config.inactive_scan_interval, 0)
self.active_scan_interval = max(config.active_scan_interval, 0)
self.state_topic = f'{config.state_topic}/{self.name}'
self.history_topic = f'{config.history_topic}/{self.name}'
self.names_topic = f'brewcast/tilt/{self.name}/names'

self.scanner = None
Expand Down
15 changes: 8 additions & 7 deletions brewblox_tilt/broadcaster_sim.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from brewblox_service import brewblox_logger, features, mqtt, repeater

from brewblox_tilt import const, parser
from brewblox_tilt.models import ServiceConfig

LOGGER = brewblox_logger(__name__)

Expand Down Expand Up @@ -48,19 +49,19 @@ class BroadcasterSim(repeater.RepeaterFeature):
def __init__(self, app: web.Application):
super().__init__(app)

config = app['config']
self.name = config['name']
self.active_scan_interval = max(config['active_scan_interval'], 0)
self.state_topic = config['state_topic'] + f'/{self.name}'
self.history_topic = config['history_topic'] + f'/{self.name}'
config: ServiceConfig = app['config']
self.name = config.name
self.active_scan_interval = max(config.active_scan_interval, 0)
self.state_topic = f'{config.state_topic}/{self.name}'
self.history_topic = f'{config.history_topic}/{self.name}'
self.names_topic = f'brewcast/tilt/{self.name}/names'

self.interval = 1
self.parser = parser.EventDataParser(app)
self.simulations = [Simulation(simulated)
for simulated in config['simulate']]
for simulated in config.simulate]

LOGGER.info(f'Started simulation for {config["simulate"]}')
LOGGER.info(f'Started simulation for {config.simulate}')

async def on_names_change(self, topic: str, payload: str):
self.parser.apply_custom_names(json.loads(payload))
Expand Down
File renamed without changes.
11 changes: 11 additions & 0 deletions brewblox_tilt/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from typing import Optional

from brewblox_service.models import BaseServiceConfig


class ServiceConfig(BaseServiceConfig):
lower_bound: float
upper_bound: float
active_scan_interval: float
inactive_scan_interval: float
simulate: Optional[list[str]]
24 changes: 13 additions & 11 deletions brewblox_tilt/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@

import numpy as np
from brewblox_service import brewblox_logger
from pint import UnitRegistry
from pint import Quantity, UnitRegistry

from brewblox_tilt import config, const
from brewblox_tilt import const, device
from brewblox_tilt.models import ServiceConfig

LOGGER = brewblox_logger(__name__)
ureg = UnitRegistry()
Q_ = ureg.Quantity
Q_: Quantity = ureg.Quantity


@dataclass
Expand Down Expand Up @@ -120,11 +121,12 @@ def calibrated_value(self, key_candidates: list[str], value: float, ndigits=0) -

class EventDataParser():
def __init__(self, app):
self.lower_bound = app['config']['lower_bound']
self.upper_bound = app['config']['upper_bound']
config: ServiceConfig = app['config']
self.lower_bound = config.lower_bound
self.upper_bound = config.upper_bound

const.CONFIG_DIR.mkdir(parents=True, exist_ok=True)
self.config = config.DeviceConfig(const.DEVICES_FILE_PATH)
self.devconfig = device.DeviceConfig(const.DEVICES_FILE_PATH)
self.session_macs: set[str] = set()
self.sg_cal = Calibrator(const.SG_CAL_FILE_PATH)
self.temp_cal = Calibrator(const.TEMP_CAL_FILE_PATH)
Expand Down Expand Up @@ -180,7 +182,7 @@ def _parse_event(self, event: TiltEvent) -> Optional[TiltMessage]:

color = decoded['color']
mac = event.mac.strip().replace(':', '').upper()
name = self.config.lookup(mac, color)
name = self.devconfig.lookup(mac, color)

if mac not in self.session_macs:
self.session_macs.add(mac)
Expand Down Expand Up @@ -231,7 +233,7 @@ def _parse_event(self, event: TiltEvent) -> Optional[TiltMessage]:

sync: list[TiltTemperatureSync] = []

for src in self.config.sync:
for src in self.devconfig.sync:
sync_tilt = src.get('tilt')
sync_type = src.get('type')
sync_service = src.get('service')
Expand Down Expand Up @@ -261,9 +263,9 @@ def parse(self, events: list[TiltEvent]) -> list[TiltMessage]:
Invalid events are excluded.
"""
messages = [self._parse_event(evt) for evt in events]
self.config.commit()
self.devconfig.commit()
return [msg for msg in messages if msg is not None]

def apply_custom_names(self, names: dict[str, str]) -> None:
self.config.apply_custom_names(names)
self.config.commit()
self.devconfig.apply_custom_names(names)
self.devconfig.commit()
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
version: '3.7'
version: "3.7"
services:
eventbus:
image: brewblox/mosquitto:develop
ports:
- "1883:1883"
tilt:
# Manually build the "local" image before use
image: brewblox/brewblox-tilt:local
image: ghcr.io/brewblox/brewblox-tilt:local
privileged: true
network_mode: host
command: --mqtt-protocol=mqtt --debug --simulate orange red
Expand Down
3 changes: 0 additions & 3 deletions docker/.gitignore

This file was deleted.

12 changes: 0 additions & 12 deletions docker/before_build.sh

This file was deleted.

Loading

0 comments on commit e182630

Please sign in to comment.