Laten we de kleine app uit het vorige artikel naar een hoger niveau tillen en integreren in het domoticaplatform Home Assistant (HA). Wanneer je je status op BusyBoard wijzigt, kan Home Assistant die zo oppikken en een automatisering activeren. We voegen een API aan BusyBoard toe die Home Assistant gemakkelijk kan uitlezen, zodat we een slimme lamp kunnen inschakelen (en rood laten kleuren).
Hoewel BusyBoard een handige oplossing was om je huisgenoten te laten weten wanneer je aan het werk bent en niet gestoord wilt worden, moet iedereen BusyBoard daarvoor wel regelmatig controleren. Niet bepaald de gebruiksvriendelijkste ervaring! Het zou veel handiger zijn als we dit op de een of andere manier in de echte wereld konden tonen … vergelijkbaar met een bordje “On Air” in radio- en tv-studio’s. Omdat ik al enkele slimme lampen aan HA heb gekoppeld, kan dat vrij eenvoudig. We hebben wel een API in BusyBoard nodig die Home Assistant kan uitlezen, dus laten we die implementeren.
Een API aan BusyBoard toevoegen
Als je een grotere toepassing ontwikkelt en een API nodig hebt, bekijk dan pakketten zoals Flask-Restful
of zelfs een framework dat specifiek voor API’s is ontworpen, zoals FastAPI! Hier hebben we echter geen toeters en bellen nodig:
we willen gewoon voor elke gebruiker een endpoint waarop we kunnen zien of die bezig is. Eerst voegen we aan het
databankmodel een functie toe die een gebruiker naar een dictionary exporteert. Daarvoor moet een beetje code aan het model
(in ./busyboard/models.py) worden toegevoegd, zoals hieronder.
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Text)
busy = db.Column(db.Boolean)
busy_with = db.Column(db.Text)
can_be_disturbed = db.Column(db.Boolean)
notes = db.Column(db.Text)
path = db.Column(db.Unicode(128))
last_change = db.Column(db.DateTime, default=datetime.utcnow)
### see repository for the full code, new function below
def to_dict(self):
return {
'id': int(self.id),
'name': str(self.name),
'busy': bool(self.busy),
'busy_with': str(self.busy_with),
'can_be_distrubed': bool(self.can_be_disturbed),
'last_change': str(self.last_change)
}
Eenvoudiger kan haast niet: één functie die de gegevens uit het model als een dictionary exporteert. Hier worden alle velden expliciet naar gehele getallen, strings en booleans omgezet. Dat is niet strikt noodzakelijk voor elk veld, maar helpt fouten te voorkomen wanneer we ze later naar JSON omzetten.
Vervolgens voegen we de routes toe aan ./busyboard/__init__.py. Ook dat is heel eenvoudig: enkele regels code
zoals hieronder volstaan.
@app.route('/api/users')
@app.route('/api/users/')
def api_users():
users = User.query.all()
return jsonify(list([u.to_dict() for u in users]))
@app.route('/api/users/<int:user_id>')
def api_user(user_id: int):
user = User.query.get(user_id)
return jsonify(user.to_dict())
Als we nu bijvoorbeeld naar \<busyboard_url\>/api/users/1 gaan, krijgen we een JSON-antwoord dat er als volgt uitziet:
{
"busy": false,
"busy_with": "programming",
"can_be_distrubed": false,
"id": 1,
"last_change": "2020-07-26 12:51:05.656357",
"name": "Sebast-I-AH-n"
}
Dat was eenvoudig genoeg. Nu gaan we naar Home Assistant om deze API uit te lezen en daar iets leuks mee te doen.
Home Assistant configureren
Home Assistant ondersteunt het uitlezen van REST-API’s, dus ook hier is er weinig configuratie nodig. Je hoeft
alleen voor elke gebruiker een REST-sensor toe te voegen die het veld “busy” uitleest. Open in de instellingenmap van Home Assistant
het bestand configuration.yml met een teksteditor en voeg het volgende deel aan de sensorsectie toe. Merk op dat
je de URL moet aanpassen aan de locatie waar jouw BusyBoard-versie draait.
sensor:
- platform: rest
resource: <busyboard_url>/api/users/1
name: user_name
value_template: '{{ value_json.busy }}'
Daarna moet je Home Assistant herstarten en is de sensor beschikbaar als sensor.user_name. Via de
GUI of rechtstreeks in het configuratiebestand automations.yaml kun je nu een nieuwe automatisering maken die een ander apparaat activeert, bijvoorbeeld een lamp.
Voeg een trigger toe die afgaat wanneer de sensor van False naar True verandert en omgekeerd. De actie is
een service die in dit geval een slimme lamp in- of uitschakelt. De details hangen sterk af van het
type lamp dat je gebruikt en hoe die in HA is geconfigureerd. Gebruik gerust het onderstaande deel uit mijn bestand automations.yaml
als referentie.
- id: '1597674094193'
alias: User Busy
trigger:
- entity_id: sensor.user_name
from: 'False'
platform: state
to: 'True'
condition: []
action:
service: light.turn_on
data:
brightness: 255
rgb_color:
- 255
- 0
- 0
entity_id:
- light.blinkstick
- id: '1597674578965'
alias: User No Longer Busy
trigger:
- entity_id: sensor.user_name
from: 'True'
platform: state
to: 'False'
condition: []
action:
service: light.turn_off
entity_id: light.blinkstick
Conclusie
Ik heb het zo ingesteld dat deze BlinkStick Square, ingebouwd in een 3D-geprinte maan in de woonkamer, rood oplicht wanneer iemand in het kantoor bezig is. Een duidelijk teken dat het kantoor voorlopig verboden terrein is.
Met enkele regels code kun je een eigen webservice eenvoudig in Home Assistant integreren en apparaten in de echte wereld activeren. De volledige code vind je op GitHub.
Vond je dit artikel interessant? Trakteer me op een koffie