Skip to content

Instantly share code, notes, and snippets.

@praveev
Created November 22, 2015 19:24
Show Gist options
  • Save praveev/22b034c36549c872fdcb to your computer and use it in GitHub Desktop.
Save praveev/22b034c36549c872fdcb to your computer and use it in GitHub Desktop.
How to design a system where you send instructions to an appliance like sonos or nest from your phone
===============
I am an iOS engineer and have just recently started doing side projects that required me to build products end-to-end (backend + serving/middle tier + front end). During one such exercise I wondered how to design a system where you send instructions to an appliance like sonos or nest from your phone.
How are such systems designed? I am looking to learn how to architect and build such systems.
For instance: What database would you choose to store the device information, user information and user-device relationship?
The flow of information I am thinking is of the following:
target_device_id +
user_access_token + validation +
instruction serving instruction (secure protocol)
Phone ======================> Middle-tier ==================================> Device
<===================== <==================================
status status
**On the App side:**
1. There is an Oauth2 based login mechanism where the user logins and stores the access token on the client side along with its expert date.
2. On App Enter Foreground, all the devices connected to that user are shown. This involves the app to make a call to get all the device ids and their information.
3. The user then selects one such device and sends an instruction such as Off or inc. volume.
**On the Middle tier:**
Have an array of public servers that can serve. They are fronted by a load balancer that hits those servers.
*Pseudo Code for Middle Tier: (Go lang or Java or Node.js or something else…..)*
```
public class Serving {
// Get a set of device ids registered to this user from some database. So probably it has a cache on this to get a better hit rate.
// Maybe the cache could be warmed for that user when he opens the app from Step 2 on the app side.
private Set<String> deviceIds(String user_access_token)
// This will probably hit the device table and get all the device info which will give the device type.
private DeviceType deviceType(String device_id)
// Checks if the instruction is valid for the device type.
// Including device type to make this backward compatible in the case of launching different devices in the future.
private boolean isInstructionValidForDeviceType(DeviceType deviceType, Instruction instruction)
// Assuming “Status” object is deserialized into JSON.
// This is the crux of the serving logic and all this should happen within hundreds of milliseconds. SLA ~ 100ms
public Status checkAndSend(user_access_token, target_device_id, instruction) {
Set<String> registered_device_ids = self.deviceIds(user_access_token);
if (registered_device_ids.contains(target_device_ids))
{
Device deviceType = self.deviceType(target_device_id);
if (self.isInstructionValidForDeviceType(deviceType, instruction))
{
boolean didSend = self.sendInstruction(target_device_ids, instruction);
if (didSend)
{
return new Status(“success”, true);
}
return new Status(“Unable to send instruction”, false);
}
else
{
return new Status(“Invalid instruction for device”, false);
}
}
else
{
return new Status(“invalid device”, false);
}
}
}
```
**Backend (NoSQL?)**
User table, Device table, User-Device table.
Caching with Redis.
**On the Device Side**
Basically a mini computer with raspberry pi like specs or even better. It connects to the wifi so maybe it can be communicated https as well as UART?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment