The below assumes readers are already familiar with basic electronics, C++ coding, Particle Photon and openHAB platforms.
Summary of Device Features- Remote switch button - signals the door opener when to switch states and provides feedback whether the door switch signal was reliably received and executed on the other end
- Precise status feedback fed directly from garage unit (no external magnets or sensors needed). There are five (5) different states defined: Opening, Open, Closing, Closed or Unknown
- Provides exact time when last event occurred - (Open->Closed or Closed->Open events)
- Able to control up to 4 (four) garage doors with the same unit
- iOS and Android support (through openHAB app)
- Integration with existing IoT infrastructure (through openHAB platform)
If you are interested, read on.
IntroductionThis project has been built around several objectives.
First objective is to provide door status information in real-time. This implementation is capable of visualizing not only open or closed, but also transitional door states. All this is implemented without the need of external sensors but by feeding information directly from the garage door opener unit.
Second objective is based around privacy and security. The majority of network communication stays local and there is no need for information processing outside the home LAN. This increases security and sync time for messages exchanged in between system's components.
Lastly but not least, this implementation can be easily integrated with existing openHAB systems to provide single unified interface instead of switching in between different applications.
Hardware SectionThe brain of controller has been built by Particle Photon (WiFi) device. The decision of which platform to be used was influenced by several factors: (1) low cost (2) tiny footprint (3) development IDE and (4) available shields. External WiFi antenna was also added to provide better radio reception and signal stability.
Particle Relay Shield provides relay functionality. The shield comes with additional board space which is used for hosting and implementing several voltage dividers to align logical levels (more information later on). In terms of power, the Relay Shield provides the required 5 volts to power the Photon.
Door Status logic
There are multiple solutions which accomplish the task of monitoring the actual door status i.e. whether door is open, closed or somewhere in between. It is important to implement this capability so the application (software side) is able to provide feedback to user.
One way to feed this information back is to install some sensor (i.e. reed switch) which activates depending on the door position. This implementation feeds door status directly from the garage unit. There is simple mechanism embedded within the unit which controls when door movement should stop as shown below.
Feeding door status this way provides the capability to reliably capture multiple states. No additional external switches are required but establishing connection to the internal mechanism may introduce some complexity.
As it can be seen, voltage levels change from 0V to 5V or vice versa depending on door position. It can be inferred that logical 1 (one) level is represented by 5 Volts as per garage door unit design. This leads to interesting problem regarding the voltage value of logical high in regards to Photon. As per Photon's datasheet, all digital ports are 5V tolerant but this comes with the price of additional settings or the internal pull up/down resistors should be disabled.
To be on the safe side, this implementation reduces the voltage of logical high from 5V to 3.3V. This has been accomplished by utilizing appropriate voltage divider as per below schematic. Having the maximum voltage limited to 3.3V will ensure full compatibility and no damaged ports in the long run.
openHAB was chosen to provide integration with current home automation solutions and nice GUI control over the Photon. Of course, the below assumes familiarity with openHAB, C++ and Particle's IDE.
The Particle piece integrates with openHAB backend through the light weight Message Queuing Telemetry Transport (MQTT) protocol. Since some transport protocol is needed to send and receive messages in between these modules, MQTT was chosen for this purpose. The openHAB platform offers MQTT Binding which allows openHAB to act as MQTT Client. At the same time, Particle Photon is able to utilize MQTT C++ library created by hirotakaster and freely available on Github.
By design, in order to implement the protocol, MQTT broker is required which acts as message forwarder for its clients. Despite the fact that openHAB does not come with a broker service, there are many MQTT broker implementations including free ones on the Internet. For the purpose of this project, an open source broker called Mosquitto was chosen and it has been hosted locally onto the openHAB server. Corresponding solution does not depend on public Internet services as all MQTT messages are exchanged within the local server or the local network.
Both MQTT clients need to ensure that they are not only connected to the broker but also subscribed to the relevant topics. openHAB MQTT binding takes care of reconnecting to broker (every 10 sec) in case connection gets dropped. On the contrary, the Photon does not re-connect and additional piece of code should be added to ensure connection is retried in case TCP session drops due to network connectivity or MQTT broker issues. Similar code is presented below.
// Check MQTT client connection to broker
if (client.isConnected()) {
// make sure keepalives are sent to Broker
client.loop();
}
else { // Connection to broker has been lost
// Re-connect and Re-subscribe after timeout
if ((now - lastConnectCheck) > mqttReConnectTimeout) {
if (client.connect("mqtt_client_name","<username>","<password>"))
mqttsubscribe();
lastConnectCheck = millis();
}
}
// *** END MQTT connection check logic
Once messaging framework has been established, we have a vehicle to transport messages and commands forth and back.
Below figure represents the topic buckets that are being used to transport information to/from. The arrows show the direction of the flow and the text points to the MQTT operation being used. It can be seen majority of information flow goes from left to right and only the push signal goes the other way around.
For example, the Photon subscribes to door-switch topic which will invoke callback function once message is published to it.
int mqttsubscribe () {
if (client.isConnected()) {
client.subscribe("<door-switch_topic");
}
}
The same way openHAB subscribes to door-status topic where the actual door status will be published based on the input values of both D0 and D1 inputs. This is how door status is pushed to openHAB and gets visualized on the GUI.
<home.sitemap>
Switch item=Door_Status label="" mappings=[opening="OPENING", open="OPEN", closing="CLOSING", closed="CLOSED", unknown="UNKNOWN"] icon="garagedoor"
Switch item=Door_Switch label="Door Switch" mappings=[ON="PUSH"] icon="switch"
<home.items>
String Door_Status "%s" { mqtt="<[broker:<door-status_topic>:state:default]" }
Switch Door_Switch { mqtt=">[broker:<door-switch_topic>:command:*:switch]" }
This implementation pushes several other pieces of information, such as door status change time and feedback whether the remote push was accepted successfully. Of course, these are optional items which I thought to be helpful to have in terms of feedback for the user.
The mobile version looks as per below figure and it is directly rendered from your openHAB instance to match the desktop one.
Additional capability was embedded to control the garage door lights. Infrared sensor detects any motion and together with the light sensor activates garage lighting. Photo resistor feeds out an analog input in order to determine how much ambient light is present to make the decision whether to activate the lights or not.
Care should be taken when setting up the PIR using the trimpots (in orange) located on the back of the circuit board. I found out that the max sensitivity works the best for this setting. Furthemore, delay is adjustable to more than 1 minute so this is a personal preference.
Mind that photo resistor feeds an analog port. Depending on ambient light level, there may be cases where your light changes states multiple times per second because of values around the voltage threshold. One way to mitigate this is to implement delay logic which will minimize this effect.
Extra Credit- External WiFi antenna provides reliable connection and 2dBi signal gain. This is especially important in case the Photon will be enclosed into metal casing.
Of course, do not forget to activate the external antenna port to be utilized by the WiFi Radio as per below code:
// let's use external Antenna
WiFi.selectAntenna(ANT_EXTERNAL);
- Clock sync (including time zone and daylight savings time) is important aspect in case time/date is visualized for the user. Photon syncs its clock every time device boots, so periodical syncs will be needed to avoid going out of sync during prolonged running time. However, this logic has never worked for me since due to Particle cloud not setting up the isDST() property correctly.
unsigned long now = millis();
// Check for Time DST
if ((now - lastTimeCheck) > timeSyncTimeout) {
Particle.syncTime(); // sync time with the cloud
if ( Time.isDST() ) {
// Dayligh saving time is in effect
Time.zone(<current_daylight_time_zone_offset>);
}
else {
//DST is not in effect
Time.zone(<current_standard_time_zone_offset>);
}
lastTimeCheck = millis();
}
- Lastly but not least, you need to provision for some air circulation as completely enclosing the Particle Photon and Relay Shield inside a box is not advisable. Soon or later components will overheat and probably malfunction in the long run.
Final implementation is shown below. The white square items are actually magnets which help to easily stick the plastic box on the bottom of garage door opener.
Comments