washcroft / HttpGarageDoorController

A project for an Arduino based WiFi-enabled controller, IoT/M2M enabling an ordinary garage door operator.
MIT License
11 stars 4 forks source link

HttpGarageDoorController (v2)

A project for an Arduino based WiFi-enabled controller, IoT/M2M enabling an ordinary garage door operator.

Demo

About

This Arduino project allows you to directly control your garage door and/or light with HTTP requests, it exposes a very basic REST JSON API via its listening HTTP web server. Since security is important here, both API Key header and OAuth 1.0a signing/authentication is supported.

I've used a MKR1000 board which uses the WiFi101 library, however the project also supports compilation for ESP8266 boards.

The Arduino controller toggles GPIO outputs to operate the garage door (using either two separate open/close relays, or more commonly cycling the same one) and also a third output to control the garage light (another relay).

The Arduino controller also uses GPIO inputs to report the state of the garage door (two inputs from separate open/closed reed switches) and also a third input to allow the garage light to be controlled via another source (i.e. the garage door operator itself).

HomeBridge (Apple HomeKit)

My HomeBridge plugin which accompanies this Arduino project can be found at homebridge-http-garagedoorcontroller.

Configuration

The controller is configured in the config.h file:

// Controller Config
const char MDNS_NAME[] = "garagedoorcontroller";
const char FRIENDLY_NAME[] = "Garage Door Controller";
const long DOOR_OUTPUT_PULSE_TIME = 400;
const long DOOR_OUTPUT_PULSE_DELAY_TIME = 1250;
const long DOOR_SENSOR_REACT_TIME = 3000;
const long DOOR_MAX_OPEN_CLOSE_TIME = 25000;
const long DOOR_AUTO_CLOSE_TIME = 300000;

// GPIO Pins
const int LED_OUTPUT_PIN = LED_BUILTIN;
const int DOOR_OUTPUT_OPEN_PIN = 3;
const int DOOR_OUTPUT_CLOSE_PIN = 3;
const int LIGHT_OUTPUT_PIN = 2;
const int LIGHT_INPUT_PIN = 1;
const int SENSOR_OPEN_INPUT_PIN = 5;
const int SENSOR_CLOSED_INPUT_PIN = 4;

// ADVANCED - DEFAULTS ARE NORMALLY OK
// Network Config
const long HTTP_SERVER_PORT = 80;
const long HTTP_REQUEST_TIMEOUT = 4000;
const long HTTP_REQUEST_BUFFER_SIZE = 512;
const long WIFI_CONNECTION_TIMEOUT = 10000;

// OAuth Config
const uint16_t OAUTH_NONCE_SIZE = 24;
const uint16_t OAUTH_NONCE_HISTORY = 255;
const uint16_t OAUTH_TIMESTAMP_VALIDITY_WINDOW = 300000;

Variables:

You will also need to add a secret.h file to your project containing your sensitive configuration:

const char WIFI_SSID[] = "WiFi";
const char WIFI_PASSWORD[] = "MyPassword";
const char OTA_UPDATER_PASSWORD[] = "MyPassword";

const char HTTP_SERVER_APIKEY_HEADER[] = "MyPassword";

const char HTTP_SERVER_OAUTH_CONSUMER_KEY[] = "MyOAuthConsumerKey";
const char HTTP_SERVER_OAUTH_CONSUMER_SECRET[] = "MyOAuthConsumerSecret";

Variables:

Debugging

Debug logging can be enabled in the compile.h file:

#define LOG_LEVEL 0 // ERROR = 1, INFO = 2, DEBUG = 3, VERBOSE = 4, TRACE = 5

Increasing the LOG_LEVEL will increase the amount of Serial output to assist with debugging. Ensure this is set back to 0 for production deployment to conserve resources.

Example Circuit Diagram

Example Circuit Diagram

REST API Documentation

If the HTTP_SERVER_APIKEY_HEADER variable defined in your secret.h file is set, all API requests must include the HTTP header X-API-Key with that value.

If the HTTP_SERVER_OAUTH_CONSUMER_KEY and HTTP_SERVER_OAUTH_CONSUMER_SECRET variables defined in your secret.h file are set, all API requests must include the OAuth signing parameters in the querystring.

The returned content type will always be application/json.

Note: It is always recommended to use OAuth to maintain high security, otherwise intercepted HTTP requests on the network would reveal security keys and passwords that could be reused at a later date. Intercepted HTTP requests authorised with OAuth don't reveal any secrets and the same request (i.e. open door) cannot be "replayed" at a later date.

There are plenty of OAuth clients and libraries available, particularly for communicating with the Twitter API as it uses the same scheme. See Twitter developer documentation "Creating a signature".

Device Info

Returns a JSON payload reporting various running parameters.

Controller Status

Returns a JSON payload reporting various input/output states.

Control Door

Controls the configured door GPIO output pin with a brief pulse (pulse time configured with DOOR_OUTPUT_PULSE_TIME).

Control Light

Controls the configured light GPIO output pin and latches.

Note: If the configured light GPIO input pin is HIGH, it will always override this.

Dependencies, Credits and Licensing

MKR1000:

Note: WiFi101OTA does not currently support mDNS hostname resolution, so you will only be able to access the controller via its IP address. I have submitted Pull Request #3 for this feature to be included, until then you may choose to use my version.

ESP8266:

Libraries:

Bundled:

License

MIT License

Copyright (c) 2017 Warren Ashcroft

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.