Let’s take the little app created in the previous post up to the next level and integrate it into a home automation platform Home Assistant (HA). That way if you change your status on the BusyBoard, Home Assistant can pick this up and trigger an automation. Here we’ll add an API to BusyBoard which can be read easily from Home Assistant so we can turn a smart light on (and switch the color to red).

While the BusyBoard was a nifty solution to indicate to your household when you are busy with work and should not be interrupted, this does require everyone to check the BusyBoard regularly. Not the most user-friendly experience! It would be far more convenient if we can somehow indicate thi in the real world … similar to an “On Air” sign in radio- and tv-studios. As I’ve already got a few smart lights linked up with HA this can fairly easily be done, but we’ll need an API in BusyBoard we can read from Home Assistant, so let’s implement this.

## Adding an API to BusyBoard

If you are developing a larger application an you need an API, have a look at packages like Flask-Restful or even a framework designed specifically for APIs like FastAPI! Here however we don’t need bells and whistles, we simply need an endpoint for each users where we can see if they are busy or not. The first step is do add a function to the database model to export a user to a dictionary. To do this a little code needs to be added to the model (in ./busyboard/models.py) as shown below.

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)
}


This couldn’t be more straightforward, a single function that an export the data from the model as a dictionary. Here, all fields are explicitly converted to integers, strings and bools. This isn’t strictly necessary for all fields, but it helps avoiding errors when converting them to JSON later on.

Next, we’ll need to add the routes to ./busyboard/__init__.py, again this is very simple. A few lines of code shown below will do the trick.

    @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())


So now if we go to e.g. \<busyboard_url\>/api/users/1 we’ll get a JSON response which looks like:

{
"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"
}


That was easy enough, now let’s move over to Home Assistant to read this API and do something cool in response.

## Configuring Home Assistant

Home Assistant comes with support to read REST APIs, so also here there is very little configuration required. The only thing needed is to add a rest-sensor for each user that reads the field “busy”. In the Home Assistant settings folder open the file configuration.yml with a text editor and add the following part to the sensor section. Note that the URL will have to be adjusted to the spot where your instance of BusyBoard is running.


sensor:
- platform: rest
resource: <busyboard_url>/api/users/1
name: user_name
value_template: '{{ value_json.busy }}'



After this you’ll have to restart Home Assistant and the sensor will be available as sensor.user_name. Now using the GUI or directly in the configuration file automations.yaml you can create a new automation that triggers another device, like a light. You’ll have to add a trigger that goes of once the sensor goes from False to True and the other way around, the action will be a service, in this case a smart light, will be switched on or off. Details how to do this will depend a lot on the type of light you are using and how it is configured in HA. Though feel free to use the section from my automations.yaml file as a reference (shown below).

- 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:
- 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