Making Better Mornings

Last weekend, I delivered “Better Mornings” - a new Cronx Home Automation feature – I thought it might be useful to give a bit of an insight into the workflow.

😞 Identifying the pain

When you live in a smart home, you start to develop a sort of complacency – everything will just work. It’s because of this that things which either don’t work at all or don’t work as they should become really jarring.

One of those things was our morning automation - almost every day, it required some sort of manual intervention.

The fundamental issue was that I wrote the original version of “Good Morning” back in winter when what we most needed in the morning was light. Now, however, in the height of summer, the flat blindly turning on the kitchen and bedroom lights when we say Good Morning is counterintuitive and annoying.

💡 Okay, so now what?

I work with a private instance of GitLab CE where I keep both public and private repos (and from which select repos are shared on to GitHub).

To raise a bug (which this is), I’ve set up a template to capture as much of the issue as possible.


Summary

The current implementation of “Good Morning” from #246 (closed) etc. isn’t very smart - it turns on too many lights in summer, it assumes that everyone is getting up at the same time and that it’s a workday.

What is the current bug behaviour?

  1. Kitchen lights come on
  2. All bedroom lights come on
  3. Living room TV turns on
  4. Living room TV switches to SD BBC One
  5. SONOS has a 5 minute sleep timer

What is the expected correct behaviour?

Always

  • Turn on the living room TV & switch it to SD BBC One

Sometimes: If alarms are active

  • Set SONOS to switch off after 45 minutes

Sometimes: If it’s dark outside

  • Turn on the kitchen lights to a low brightness
  • Fade in the rest of the bedroom lights (making sure colour temperature is matched)

If we cave and get a smart coffee machine

  • Make coffee! ☕️

🛠 Fixing

When I create an issue in GitLab, I’m immediately presented a single button which will create a new branch and create a new merge request for that branch back into master. In my local development environment, I checkout this new branch, make changes and the commit them.

I use gitmoji to categorise my commits - in this case it was a 🐛 bugfix.

🛑 Testing

When a commit is pushed to GitLab, I use GitLab CI to test two things - is it valid YAML and is it a valid HomeAssistant config?

Within my Docker Stack, I run both Gitlab Runner and DinD (Docker in Docker). I also run with the following .gitlab-ci.yaml file:

image:
  homeassistant/home-assistant

stages:
  - test

test:
  stage: test
  script:
    - cd /usr/src/app
    - cp $CI_PROJECT_DIR/ci_secrets.yaml $CI_PROJECT_DIR/secrets.yaml
    - /usr/local/bin/python -m homeassistant --config $CI_PROJECT_DIR/ --script check_config
    - if /usr/local/bin/python -m homeassistant --config $CI_PROJECT_DIR/ --script check_config | grep "ERROR" ; then exit 1; else echo "No YAML errors"; fi

Essentially what happens here is that a DinD container for Home Assistant is spun up, my pushed commit is loaded, the fake secrets.yaml file is loaded (protecting the privacy of my actual keys etc.) and then the check_config script from Home Assistant is run twice - being slightly over-cautious as I experienced a few issues when I originally set it up.

✅ Merge and Deploy

Assuming the config is valid, I can then merge the generated pull request. Whenever I merge to master for this repository, the changes are automatically pushed to the public repository on GitHub. From there, I actually run TravisCI again (nothing like double checking!) and if that passes, Home Assistant updates itself:

automation:
  - alias: "Configuration Update"
    trigger:
      platform: state
      entity_id: sensor.ambassadrhomeassistant_last_build_finished_at
    condition:
      - condition: state
        entity_id: sensor.ambassadrhomeassistant_last_build_state
        state: 'passed'
      - condition: template
        value_template: '{{states.sensor.ambassadrhomeassistant_last_build_finished_at.attributes["Commit Branch"] == "master"}}'
      - condition: template
        value_template: '{{states.sensor.ambassadrhomeassistant_last_build_finished_at != "unknown"}}'
    action:
      - service: script.configuation_update

script:
  configuation_update:
    sequence:
      - service: shell_command.git_pull
      - service: notify.will
        data_template:
          title: "\U000026A1 Restarting HomeAssistant Now"
          message: "Restarting in 30 seconds to update to new build"
      - service: script.stream
        data:
          message: "\U000026A1 Config update installing..."
      - delay: 00:00:30
      - service: homeassistant.restart

🔁 Not quite done yet

In the first few days after a feature release or major bug fix, I try to monitor to make sure that it’s all working exactly as intended. Sometimes to do this, I put in place additional debugging (either writing to logs, to the Slack stream or through iOS push notifications) so that I can check each step.

In this case, I noticed that the volume increments for alarms that I introduced were a) a bit sudden and b) ended on too high a volume – so I pushed an additional fix within 2 days.

So that’s a quick insight into how I capture issues, how the workflow functions and the tests / checkpoints along the way.

P.S. We did cave and buy that coffee machine - we now have delicious bean-to-cup filter coffee made in line with our smart alarms ☕️