Awesome
Example-IoT-Hue
Example project how-to create an Philips Hue compatible REST-API that is discovered and controllable by Hue compatible Smart-Home devices like Amazon Alexa or Google Echo.
It demonstrates how Oat++ can be used to develop an Amazon Alexa or Google Home compatible REST-API which emulates Philips Hue bulbs. Oat++ answers to search requests of you favorite SmartHome hub and you can register your fake bulbs to it. After the registration of your fake bulbs to your Hub/Alexa/Google Home, you can control your Oat++ application with 🗣️"Alexa, turn on <your fake device name>"!
For this discoverability, the oatpp-ssdp
module is used to receive and answer SSDP searches.
This REST-API was implemented with the help of the Hue API unofficial reference documentation by burgestrand.se
See more:
- Oat++ Website
- Oat++ Github Repository
- Get Started
- Philips Hue API — Unofficial Reference Documentation
Overview
This project is using oatpp, oatpp-swagger and oatpp-ssdp modules.
Project layout
|- CMakeLists.txt // projects CMakeLists.txt
|- src/
| |
| |- controller/ // Folder containing HueDeviceController and SsdpController where all endpoints are declared
| |- db/ // Folder with database mock
| |- dto/ // DTOs are declared here
| |- SwaggerComponent.hpp // Swagger-UI config
| |- DeviceDescriptorComponent.hpp // Component describing your "Hue Hub" (YOU HAVE TO CONFIGURE THIS FILE TO FIT YOUR ENVIRONMENT)
| |- AppComponent.hpp // Service config
| |- App.cpp // main() is here
|
|- test/ // test folder
|- utility/install-oatpp-modules.sh // utility script to install required oatpp-modules.
Build and Run
Before you run this example you have to edit src/DeviceDescriptorComponent.hpp
to match your IP address.
Since this is only an example and to keep it simple this is not automated or parameterised!
You have to come up with your own implementation that fits your environment.
OATPP_CREATE_COMPONENT(std::shared_ptr<DeviceDescriptor>, deviceDescriptor)("deviceDescriptor", [] {
auto desc = std::make_shared<DeviceDescriptor>();
// ToDo: Add your machines Address and Port here! You have to come up with your own way to automate this...
desc->ipPort = "192.168.100.100:80"; // your real IP and Port your HTTP-Controller is running on
// assignable
desc->mac = "be5t0a70cafe"; // can be a fake one
// fixed
desc->sn = "1000000471337";
desc->uuid = "2f402f80-da50-11e1-9b23-" + desc->mac;
return desc;
}());
Using CMake
Requires
oatpp
,oatpp-ssdp
andoatpp-swagger
modules installed. You may runutility/install-oatpp-modules.sh
script to install required oatpp modules.
$ mkdir build && cd build
$ cmake ..
$ make
$ ./example-iot-hue-ssdp-exe # - run application.
In Docker
$ docker build -t example-iot-hue-ssdp .
$ docker run -p 8000:8000 -t example-iot-hue-ssdp
Endpoints declaration
All implemented endpoints are compatible to a Philips Hue bridge (V1 and V3). Their path and structure are fixed!
SSDP: Search Responder
ENDPOINT("M-SEARCH", "*", star)
This Endpoint accepts and answers to M-SEARCH
SSDP packets like a Philips Hue hub would do.
HTTP: description.xml
ENDPOINT("GET", "/description.xml", description)
In the discovery answer, a reference to this endpoint is send back.
This endpoints emulates a static desciption.xml
which includes all necessary information required to act as an Philips Hue hub.
See Bridge discovery (burgestrand.se)
HTTP: One-Shot 'user' registration
ENDPOINT("POST", "/api", appRegister, BODY_DTO(oatpp::Object<UserRegisterDto>, userRegister))
This endpoint just emulates a valid user-registration on a Philips Hue hub.
See Application registration (burgestrand.se)
HTTP: Get all 'lights'
ENDPOINT("GET", "/api/{username}/lights", getLights, PATH(String, username))
This endpoint returns a object of all devices in a Philips Hue compatible fashion. However, formally this endpoint should just return the names. But returning the full list is fine too.
HTTP: Get state of a specific light
ENDPOINT("GET", "/api/{username}/lights/{hueId}", getLight, PATH(String, username), PATH(Int32, hueId))
This endpoint returns the state of the light given in {hueId}
in a Philips Hue compatible fashion.
HTTP: Set state of a specific light
ENDPOINT("PUT", "/api/{username}/lights/{hueId}/state", updateState,
PATH(String, username),
PATH(Int32, hueId),
BODY_DTO(Object<HueDeviceStateDto>, state))
This endpoint accepts a Philips Hue compatible state-object and sets the state in the internal database accordingly. It is called e.g. by Alexa if you tell it 🗣️"Alexa, turn on <device name>". Finally it returns a "success" or "error" object.
Thanks
- To @DavidHamburg for spotting an issue with the old device id's that prevented Alexa from finding the devices
Notes
The newest version of the example shows the correct icon for the device in the Amazon Alexa app. Support for color-temperature and brightness was added too. Setting a custom color is still not forking properly. While you can set a custom color, the Alexa app will show you an error and won't show the color you have set. Feel free to fix this and send us your PR!