Skip to content

Commit

Permalink
Merge pull request #30 from BrewBlox/develop
Browse files Browse the repository at this point in the history
Edge release
  • Loading branch information
steersbob authored Jan 17, 2024
2 parents 6dcd7bc + 826fb2b commit 3732c80
Show file tree
Hide file tree
Showing 15 changed files with 642 additions and 696 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.venv/
.vscode/
14 changes: 9 additions & 5 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-hass

jobs:
build:
Expand All @@ -17,13 +21,13 @@ jobs:
- uses: docker/setup-buildx-action@v2
- uses: actions/setup-python@v4
with:
python-version: "3.9"
python-version: "3.11"

- name: Get image metadata
id: meta
uses: docker/metadata-action@v4
with:
images: ghcr.io/brewblox/brewblox-hass
images: ${{ env.DOCKER_IMAGE }}

- name: ghcr.io login
uses: docker/login-action@v2
Expand All @@ -44,9 +48,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 @@ -55,4 +59,4 @@ jobs:
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm/v7,linux/arm64/v8
context: docker
context: .
3 changes: 0 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
"python.defaultInterpreterPath": ".venv/bin/python",
"python.terminal.activateEnvInCurrentTerminal": true,
"python.terminal.activateEnvironment": true,
"python.linting.flake8Enabled": true,
"python.linting.pylintEnabled": false,
"python.testing.pytestArgs": [
"--no-cov",
"."
Expand All @@ -14,6 +12,5 @@
"[python]": {
"editor.defaultFormatter": "ms-python.autopep8"
},
"python.formatting.provider": "none",
"python.analysis.diagnosticMode": "workspace"
}
39 changes: 39 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
FROM python:3.11-bookworm as base

ENV PIP_EXTRA_INDEX_URL=https://www.piwheels.org/simple
ENV PIP_FIND_LINKS=/wheeley
ENV VENV=/app/.venv
ENV PATH="$VENV/bin:$PATH"

COPY ./dist /app/dist

RUN <<EOF
set -ex

mkdir /wheeley
python3 -m venv $VENV
pip3 install --upgrade pip wheel setuptools
pip3 wheel --wheel-dir=/wheeley -r /app/dist/requirements.txt
pip3 wheel --wheel-dir=/wheeley /app/dist/*.tar.gz
EOF

FROM python:3.11-slim-bookworm
EXPOSE 5000
WORKDIR /app

ENV PIP_FIND_LINKS=/wheeley
ENV VENV=/app/.venv
ENV PATH="$VENV/bin:$PATH"

COPY --from=base /wheeley /wheeley

RUN <<EOF
set -ex

python3 -m venv $VENV
pip3 install --no-index brewblox_hass
pip3 freeze
rm -rf /wheeley
EOF

ENTRYPOINT ["python3", "-m", "brewblox_hass"]
20 changes: 11 additions & 9 deletions brewblox_hass/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@
from brewblox_service import brewblox_logger, mqtt, scheduler, service

from brewblox_hass import relay
from brewblox_hass.models import ServiceConfig

LOGGER = brewblox_logger(__name__)


def create_parser(default_name='hass') -> ArgumentParser:
parser: ArgumentParser = service.create_parser(default_name=default_name)
def create_parser() -> ArgumentParser:
parser: ArgumentParser = service.create_parser('hass')

group = parser.add_argument_group('HASS broker config')
group.add_argument('--hass-mqtt-protocol',
Expand All @@ -33,15 +34,16 @@ def create_parser(default_name='hass') -> ArgumentParser:


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

app = service.create_app(parser=create_parser())
async def setup():
scheduler.setup(app)
mqtt.setup(app)
relay.setup(app)

scheduler.setup(app)
mqtt.setup(app)
relay.setup(app)

service.furnish(app)
service.run(app)
service.run_app(app, setup())


if __name__ == '__main__':
Expand Down
10 changes: 10 additions & 0 deletions brewblox_hass/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from typing import Optional

from brewblox_service.models import BaseServiceConfig, MqttProtocol


class ServiceConfig(BaseServiceConfig):
hass_mqtt_protocol: MqttProtocol
hass_mqtt_host: str
hass_mqtt_port: Optional[int]
hass_mqtt_path: str
49 changes: 21 additions & 28 deletions brewblox_hass/relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
from os import getenv
from typing import Set

import aiomqtt
from aiohttp import web
from brewblox_service import brewblox_logger, features, mqtt

from brewblox_hass.models import ServiceConfig

LOGGER = brewblox_logger(__name__)

REPLACE_PATTERN = r'[^a-zA-Z0-9_]'
Expand Down Expand Up @@ -51,16 +52,18 @@ class Relay(features.ServiceFeature):

def __init__(self, app: web.Application, publisher: mqtt.EventHandler):
super().__init__(app)
config: ServiceConfig = app['config']
self.topic = f'{config.state_topic}/#'
self.publisher: mqtt.EventHandler = publisher
self.known: Set[str] = set()

async def startup(self, app: web.Application):
await mqtt.listen(app, 'brewcast/state/#', self.on_message)
await mqtt.subscribe(app, 'brewcast/state/#')
await mqtt.listen(app, self.topic, self.on_message)
await mqtt.subscribe(app, self.topic)

async def shutdown(self, app: web.Application):
await mqtt.unsubscribe(app, 'brewcast/state/#')
await mqtt.unlisten(app, 'brewcast/state/#', self.on_message)
await mqtt.unsubscribe(app, self.topic)
await mqtt.unlisten(app, self.topic, self.on_message)

async def handle_spark_state(self, message: dict):
service = message['key']
Expand Down Expand Up @@ -141,7 +144,7 @@ async def handle_spark_state(self, message: dict):
LOGGER.info(f'publishing new profile state: {id}')
await self.publisher.publish(
topic=f'homeassistant/binary_sensor/{full}/config',
message=json.dumps({
payload=json.dumps({
'device_class': 'running',
'name': f'{id} ({service})',
'state_topic': state_topic,
Expand Down Expand Up @@ -210,8 +213,8 @@ async def handle_tilt_state(self, message: dict):
err=False,
)

async def on_message(self, topic: str, content: str):
message = json.loads(content)
async def on_message(self, topic: str, payload: str):
message = json.loads(payload)

if message['type'] == 'Spark.state':
return await self.handle_spark_state(message)
Expand All @@ -220,26 +223,16 @@ async def on_message(self, topic: str, content: str):
return await self.handle_tilt_state(message)


class PasswordEventHandler(mqtt.EventHandler):

@staticmethod
def create_client(config: mqtt.MQTTConfig) -> aiomqtt.Client:
client = mqtt.EventHandler.create_client(config)
client.username_pw_set(username=getenv('HASS_MQTT_USERNAME'),
password=getenv('HASS_MQTT_PASSWORD'))

return client
def setup(app: web.Application):
config: ServiceConfig = app['config']

publisher = mqtt.EventHandler(app,
protocol=config.hass_mqtt_protocol,
host=config.hass_mqtt_host,
port=config.hass_mqtt_port,
path=config.hass_mqtt_path)
publisher.client._client.username_pw_set(username=getenv('HASS_MQTT_USERNAME'),
password=getenv('HASS_MQTT_PASSWORD'))

def setup(app: web.Application):
config = app['config']
hass_mqtt = {
'protocol': config['hass_mqtt_protocol'],
'host': config['hass_mqtt_host'],
'port': config['hass_mqtt_port'],
'path': config['hass_mqtt_path'],
}

publisher = PasswordEventHandler(app, **hass_mqtt)
features.add(app, publisher)
features.add(app, publisher, key='HASS publisher')
features.add(app, Relay(app, publisher))
2 changes: 0 additions & 2 deletions docker/.gitignore

This file was deleted.

29 changes: 0 additions & 29 deletions docker/Dockerfile

This file was deleted.

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

This file was deleted.

Loading

0 comments on commit 3732c80

Please sign in to comment.