Pages

Sunday 3 February 2019

IoT Audio Source Switcher [Part 2 - Software]

Recap

In Part 1 I outlined the hardware aspects of creating an IoT audio source switcher. In Part 2 I'll cover the software side of things.

Problem
To be able to remotely select the input audio source from a variety of devices.

Solution
Use network (WiFi / LAN) connections to send messages to enable control.

Architecture
When it comes to network communications there are a number of different ways to accomplish a task. The most common being HTTP calls to some predefined API e.g. http://server1.sky-map.org/search?star=polaris
This is great for sending requests for information, in this example we request the information for the star polaris and we receive XML encoded response. XML and JSON are common formats for communicating this type of information as they can both be parsed quickly and easily.
The HTTP approach also requires that we know the IP address of the device we want to communicate with. This can cause unnecessary extra work.

HTTP Scenario
Here we have deployed the audio switched with an HTTP endpoint that looks something like this...
http://192.168.0.123:8080/audio?source=1
This looks great, we can send commands from any device on the network. However, if we have several devices that are setup to control the audio switcher, then for some reason we need to change the IP address of the audio switcher, all the control devices have to be updated (or perform a search of the full IP range) in order to keep communicating. This might need another endpoint so that we can check what device we're interrogating e.g. http://192.168.0.x:8080/info. 
Another solution is configuring a local DNS server so we can address each device by a name, but that sounds like even more overkill.

Multiple Device Scenario
Let's say we want to extend our setup, now we want to turn on/off some lights when we switch source on the audio switcher. To extend the HTTP implementation we'd need to hit multiple URLs on multiple IPs and possibly send multiple parameters to the endpoints. 

Example:
Our Audio Switcher is on 192.168.0.123
We have light controller on 192.168.0.124
And a power plug on 192.168.0.125

Say we want to switch to source 2, turn off two lights and turn on the device connected to the power plug.

We might have to hit the following endpoints, something like
192.168.0.123/audio?source=2
192.168.0.124/off
192.168.0.125/on

That's 3 different IPs we need to manage and 3 different http endpoints. To make it reliable we'll need to make the IPs static or allocate them in the DHCP settings of the router. 

Now imagine trying to update this after deploying. Adding another device, changing IPs, adjusting the workflow. It's starting to get complicated and difficult to maintain.

Let me introduce something called MQTT.


MQTT

"MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport."

Sounds promising doesn't it?

MQTT uses a publish/subscribe approach to delivering messages to devices. Without just regurgitating hundreds of other sites / YouTube videos that explain MQTT I'll just get to the crux of the matter.

Unlike our HTTP example that requires the controllers to directly send data to the audio switcher (at a known IP), we now tell the audio switcher to subscribe to a topic. The topic is a communication channel that any device can listen to and any other device can publish to.
In the case of the audio switcher it subscribes to "0/kitchen/av/a" where I've defined the topic hierarchy format as "{floor}/{room}/{device}/{property}".

However, we still need to communicate with a specific IP, but at least it's only 1. The MQTT broker or server that handles all the messages. This grunt work is performed by a Raspberry Pi.

Here's how MQTT would work in our multiple devices example.
The audio switcher subscribes to "0/kitchen/av/a" and receives the simple message of 1-4 that dictates which input to switch to.
Any controller devices simply have to publish to the same topic "0/kitchen/av/a" with the message 1-4 to set the source.
Now, if I want to control a second device, say a power switch to turn on the TV if the input of the audio switcher is '1'. I simply have to subscribe the power switch to the same topic "0/kitchen/av/a", the controller knows nothing of the power switch, we haven't had to update the controller with another API endpoint or IP address of another device to control.




Summary

I built an IoT audio source switcher with 4 stereo inputs and 1 stereo output. This will be used to switch the input of an audio amp. Sources are switched using relays to avoid any cross-talk or other components leaking noise into the audio path.
I'm using an ESP8266 to control the unit and provide wifi access. Communication is handled using the MQTT protocol whereby clients can 'subscribe' and 'publish' messages to 'topics'.

The switcher subscribes to a topic e.g. "0/kitchen/av". Other devices can publish to this topic "0/kitchen/av" and include a message, this could be JSON encoded e.g. {"set": "source", "value": "2"}. Any device subscribed to this topic will receive this message and can process it accordingly.
I can publish to this topic from anything, an app, console, or another ESP8266. In one example I show a simple button press on another ESP8266 publishing a message to select the next source.

All the MQTT messages are handled by a local server or 'broker' running on a Raspberry Pi. The local nature of this 'IoT' means it doesn't rely on any external internet connections, third-party services or companies (https://www.telegraph.co.uk/technology/2018/10/12/glitch-yales-smart-security-system-sees-brits-locked-homes/)

No comments:

Post a Comment