Garage Door Monitor and Opener

Dependencies:   X_NUCLEO_COMMON ST_INTERFACES

Introduction

This system implements a simple garage door opener and environmental monitor. The hardware connects to the internet using Wi-Fi then on to the Pelion Device Management Platform which provides device monitoring and secure firmware updates over the air (FOTA). Pelion Device Management provides a flexible set of REST APIs which we will use to communicate to a web application running on an EC-2 instance in AWS. The web application will serve a web page where we can monitor and control our garage..

This project is intended to work on the DISCO-L475VG-IOT01A from ST Microelectronics It implements a simple actuator to drive a relay to simulate pushing the "open" button on older style garage doors which do not use a rolling code interface.

The system is designed to be mounted over the door so that the on board time of flight sensor can be used to detect if the door is open or closed.

The system also monitors temperature, humidity and barometric pressure.

https://os.mbed.com/media/uploads/JimCarver/garageopener.jpg

Hardware Requirements:

DISCO-L475G-IOT01A https://os.mbed.com/platforms/ST-Discovery-L475E-IOT01A/

Seeed Studio Grove Relay module https://www.seeedstudio.com/Grove-Relay.html

Seeed Studio Grove cable, I used this one: https://www.seeedstudio.com/Grove-4-pin-Male-Jumper-to-Grove-4-pin-Conversion-Cable-5-PCs-per-Pack.html

Connect to the PMOD connector like this:

https://os.mbed.com/media/uploads/JimCarver/opener.jpg

This shows how I installed so that the time of flight sensor can detect when the door is open

https://os.mbed.com/media/uploads/JimCarver/opener1.jpg https://os.mbed.com/media/uploads/JimCarver/opener2.jpg

To use the project:

You will also need a Pelion developers account.

I suggest you first use the Pelion quick state to become familiar with Pelion Device Management. https://os.mbed.com/guides/connect-device-to-pelion/1/?board=ST-Discovery-L475E-IOT01A

Web Interface

For my web interface I am running node-red under Ubuntu in an EC2 instance on AWS. This can run for 12 month within the constraints of their free tier. Here is a tutorial: https://nodered.org/docs/getting-started/aws

You will also need to install several node-red add ons:

sudo npm install -g node-red-dashboard

sudo npm install -g node-red-contrib-mbed-cloud

sudo npm istall -g node-red-contrib-moment

After starting node-red import the contents of GarageFlow.txt from the project, pin the flow into the page.

To enable your web app to access your Pelion account you need an API key.

First you will neet to use your Pelion account to create an API key.

https://os.mbed.com/media/uploads/JimCarver/api_portal.jpg

Now we need to apply that API key to your Node-Red flow.

https://os.mbed.com/media/uploads/JimCarver/api_node-red.jpg

Committer:
JimCarver
Date:
Wed Nov 27 00:10:21 2019 +0000
Revision:
35:cbbafa9c3e15
Parent:
34:a5724eeaaf9d
Child:
37:ec1124e5ec1f
Pelion Controlled Remote Garage Door Opener

Who changed what in which revision?

UserRevisionLine numberNew contents of line
adustm 1:e86b1cffc402 1 // ----------------------------------------------------------------------------
adustm 4:cf7342047b4d 2 // Copyright 2016-2018 ARM Ltd.
adustm 1:e86b1cffc402 3 //
adustm 1:e86b1cffc402 4 // SPDX-License-Identifier: Apache-2.0
adustm 1:e86b1cffc402 5 //
adustm 1:e86b1cffc402 6 // Licensed under the Apache License, Version 2.0 (the "License");
adustm 1:e86b1cffc402 7 // you may not use this file except in compliance with the License.
adustm 1:e86b1cffc402 8 // You may obtain a copy of the License at
adustm 1:e86b1cffc402 9 //
adustm 1:e86b1cffc402 10 // http://www.apache.org/licenses/LICENSE-2.0
adustm 1:e86b1cffc402 11 //
adustm 1:e86b1cffc402 12 // Unless required by applicable law or agreed to in writing, software
adustm 1:e86b1cffc402 13 // distributed under the License is distributed on an "AS IS" BASIS,
adustm 1:e86b1cffc402 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
adustm 1:e86b1cffc402 15 // See the License for the specific language governing permissions and
adustm 1:e86b1cffc402 16 // limitations under the License.
adustm 1:e86b1cffc402 17 // ----------------------------------------------------------------------------
MarceloSalazar 9:265744785d33 18 #ifndef MBED_TEST_MODE
screamer 28:0e774865873d 19
adustm 1:e86b1cffc402 20 #include "mbed.h"
adustm 1:e86b1cffc402 21 #include "simple-mbed-cloud-client.h"
screamer 10:b27c962b3c3f 22 #include "LittleFileSystem.h"
screamer 33:cfd9430e7d1e 23
screamer 33:cfd9430e7d1e 24 // Default network interface object. Don't forget to change the WiFi SSID/password in mbed_app.json if you're using WiFi.
screamer 33:cfd9430e7d1e 25 NetworkInterface *net;
screamer 33:cfd9430e7d1e 26
screamer 33:cfd9430e7d1e 27 // Default block device available on the target board
screamer 33:cfd9430e7d1e 28 BlockDevice* bd = BlockDevice::get_default_instance();
screamer 33:cfd9430e7d1e 29 SlicingBlockDevice sd(bd, 0, 2*1024*1024);
screamer 33:cfd9430e7d1e 30
screamer 33:cfd9430e7d1e 31 #if COMPONENT_SD || COMPONENT_NUSD
screamer 33:cfd9430e7d1e 32 // Use FATFileSystem for SD card type blockdevices
screamer 33:cfd9430e7d1e 33 FATFileSystem fs("fs");
screamer 33:cfd9430e7d1e 34 #else
screamer 33:cfd9430e7d1e 35 // Use LittleFileSystem for non-SD block devices to enable wear leveling and other functions
screamer 33:cfd9430e7d1e 36 LittleFileSystem fs("fs");
screamer 33:cfd9430e7d1e 37 #endif
screamer 33:cfd9430e7d1e 38
screamer 33:cfd9430e7d1e 39 // Default User button for GET example and for resetting the storage
screamer 33:cfd9430e7d1e 40 InterruptIn button(BUTTON1);
screamer 33:cfd9430e7d1e 41 // Default LED to use for PUT/POST example
JimCarver 35:cbbafa9c3e15 42 DigitalOut DoorActivate(PD_3, 0);
screamer 33:cfd9430e7d1e 43
screamer 33:cfd9430e7d1e 44 // How often to fetch sensor data (in seconds)
JimCarver 35:cbbafa9c3e15 45 #define SENSORS_POLL_INTERVAL 15.0
JimCarver 35:cbbafa9c3e15 46 int dflag = 1;
screamer 33:cfd9430e7d1e 47 // Sensors related includes and initialization
screamer 10:b27c962b3c3f 48 #include "HTS221Sensor.h"
screamer 10:b27c962b3c3f 49 #include "LPS22HBSensor.h"
screamer 28:0e774865873d 50 #include "VL53L0X.h"
screamer 10:b27c962b3c3f 51
screamer 10:b27c962b3c3f 52 static DevI2C devI2c(PB_11,PB_10);
screamer 12:1f1a50e973db 53 static HTS221Sensor sen_hum_temp(&devI2c);
screamer 12:1f1a50e973db 54 static LPS22HBSensor sen_press_temp(&devI2c);
JimCarver 35:cbbafa9c3e15 55
screamer 28:0e774865873d 56 static DigitalOut shutdown_pin(PC_6);
screamer 28:0e774865873d 57 static VL53L0X sen_distance(&devI2c, &shutdown_pin, PC_7);
screamer 11:8df4529f060d 58
MarceloSalazar 9:265744785d33 59 // Declaring pointers for access to Pelion Client resources outside of main()
screamer 12:1f1a50e973db 60 MbedCloudClientResource *res_button;
JimCarver 35:cbbafa9c3e15 61 MbedCloudClientResource *DoorControl;
JimCarver 35:cbbafa9c3e15 62
adustm 1:e86b1cffc402 63
screamer 33:cfd9430e7d1e 64 // Additional resources for sensor readings
JimCarver 35:cbbafa9c3e15 65
screamer 12:1f1a50e973db 66 MbedCloudClientResource *res_humidity;
screamer 12:1f1a50e973db 67 MbedCloudClientResource *res_temperature;
screamer 12:1f1a50e973db 68 MbedCloudClientResource *res_pressure;
screamer 12:1f1a50e973db 69 MbedCloudClientResource *res_distance;
JimCarver 35:cbbafa9c3e15 70
JimCarver 35:cbbafa9c3e15 71 // define your personal password
JimCarver 35:cbbafa9c3e15 72 #define DoorPassword "MyPassword"
adustm 1:e86b1cffc402 73
JimCarver 35:cbbafa9c3e15 74 char DoorCode[32];
JimCarver 35:cbbafa9c3e15 75 DigitalOut ConnectTrue(LED1);
JimCarver 35:cbbafa9c3e15 76 DigitalOut CodeError(LED2);
JimCarver 35:cbbafa9c3e15 77 int ErrorCount = 0;
JimCarver 35:cbbafa9c3e15 78 int ErrorLockoutTime = 0;
JimCarver 35:cbbafa9c3e15 79
screamer 33:cfd9430e7d1e 80 // An event queue is a very useful structure to debounce information between contexts (e.g. ISR and normal threads)
screamer 33:cfd9430e7d1e 81 // This is great because things such as network operations are illegal in ISR, so updating a resource in a button's fall() function is not allowed
screamer 33:cfd9430e7d1e 82 EventQueue eventQueue;
screamer 33:cfd9430e7d1e 83
screamer 10:b27c962b3c3f 84 // When the device is registered, this variable will be used to access various useful information, like device ID etc.
screamer 10:b27c962b3c3f 85 static const ConnectorClientEndpointInfo* endpointInfo;
adustm 1:e86b1cffc402 86
screamer 10:b27c962b3c3f 87 /**
adustm 4:cf7342047b4d 88 * PUT handler
adustm 4:cf7342047b4d 89 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 90 * @param newValue Updated value for the resource
adustm 4:cf7342047b4d 91 */
screamer 32:2871fbeb627d 92 void put_callback(MbedCloudClientResource *resource, m2m::String newValue) {
JimCarver 35:cbbafa9c3e15 93
JimCarver 35:cbbafa9c3e15 94 if(ErrorLockoutTime != 0) { /* Ignore password attempts while locked */
JimCarver 35:cbbafa9c3e15 95 printf("Password Lockout!\r\n");
JimCarver 35:cbbafa9c3e15 96 return;
JimCarver 35:cbbafa9c3e15 97 }
screamer 29:6ff737b67e7d 98 printf("*** PUT received, new value: %s \n", newValue.c_str());
JimCarver 35:cbbafa9c3e15 99 strcpy(DoorCode, newValue.c_str());
JimCarver 35:cbbafa9c3e15 100 printf("%s\r\n", DoorCode);
JimCarver 35:cbbafa9c3e15 101 if(!strcmp(DoorCode, DoorPassword )) {
JimCarver 35:cbbafa9c3e15 102 DoorActivate = 1; * Activate relay for 1500ms */
JimCarver 35:cbbafa9c3e15 103 wait_ms(1500);
JimCarver 35:cbbafa9c3e15 104 DoorActivate = 0;
JimCarver 35:cbbafa9c3e15 105 DoorCode[0] = NULL;
JimCarver 35:cbbafa9c3e15 106 // clear password error data
JimCarver 35:cbbafa9c3e15 107 ErrorCount = 0;
JimCarver 35:cbbafa9c3e15 108 ErrorLockoutTime = 0;
JimCarver 35:cbbafa9c3e15 109 } else { /* bad password attempt */
JimCarver 35:cbbafa9c3e15 110 DoorCode[0] = NULL;
JimCarver 35:cbbafa9c3e15 111 ErrorCount++;
JimCarver 35:cbbafa9c3e15 112 if(ErrorCount >= 3) { /* If password submitted is wring lockout the remote control on the third error */
JimCarver 35:cbbafa9c3e15 113 ErrorLockoutTime = (ErrorCount - 2) * 2; /* Double the lockout time after every failed password */
JimCarver 35:cbbafa9c3e15 114 CodeError = 1; /* Indicate lockout on LED */
JimCarver 35:cbbafa9c3e15 115 printf("PasswordLocked %d Minutes\r\n", ErrorLockoutTime);
JimCarver 35:cbbafa9c3e15 116 }
JimCarver 35:cbbafa9c3e15 117 }
JimCarver 35:cbbafa9c3e15 118
JimCarver 35:cbbafa9c3e15 119
adustm 1:e86b1cffc402 120 }
adustm 1:e86b1cffc402 121
JimCarver 35:cbbafa9c3e15 122
adustm 1:e86b1cffc402 123
screamer 11:8df4529f060d 124 /**
screamer 13:42b49a0caade 125 * Button function triggered by the physical button press.
screamer 11:8df4529f060d 126 */
screamer 11:8df4529f060d 127 void button_press() {
screamer 12:1f1a50e973db 128 int v = res_button->get_value_int() + 1;
screamer 12:1f1a50e973db 129 res_button->set_value(v);
screamer 29:6ff737b67e7d 130 printf("*** Button clicked %d times \n", v);
adustm 1:e86b1cffc402 131 }
adustm 1:e86b1cffc402 132
adustm 4:cf7342047b4d 133 /**
adustm 4:cf7342047b4d 134 * Notification callback handler
adustm 4:cf7342047b4d 135 * @param resource The resource that triggered the callback
adustm 4:cf7342047b4d 136 * @param status The delivery status of the notification
adustm 4:cf7342047b4d 137 */
adustm 4:cf7342047b4d 138 void button_callback(MbedCloudClientResource *resource, const NoticationDeliveryStatus status) {
screamer 29:6ff737b67e7d 139 printf("*** Button notification, status %s (%d) \n", MbedCloudClientResource::delivery_status_to_string(status), status);
adustm 4:cf7342047b4d 140 }
adustm 1:e86b1cffc402 141
adustm 4:cf7342047b4d 142 /**
adustm 4:cf7342047b4d 143 * Registration callback handler
adustm 4:cf7342047b4d 144 * @param endpoint Information about the registered endpoint such as the name (so you can find it back in portal)
adustm 4:cf7342047b4d 145 */
adustm 4:cf7342047b4d 146 void registered(const ConnectorClientEndpointInfo *endpoint) {
screamer 17:fc98adcf835a 147 printf("Registered to Pelion Device Management. Endpoint Name: %s\n", endpoint->internal_endpoint_name.c_str());
screamer 10:b27c962b3c3f 148 endpointInfo = endpoint;
adustm 4:cf7342047b4d 149 }
adustm 1:e86b1cffc402 150
screamer 10:b27c962b3c3f 151 /**
screamer 10:b27c962b3c3f 152 * Initialize sensors
screamer 10:b27c962b3c3f 153 */
screamer 10:b27c962b3c3f 154 void sensors_init() {
JimCarver 35:cbbafa9c3e15 155 uint8_t id1, id2;
screamer 10:b27c962b3c3f 156
screamer 29:6ff737b67e7d 157 printf ("\nSensors configuration:\n");
screamer 10:b27c962b3c3f 158 // Initialize sensors
screamer 12:1f1a50e973db 159 sen_hum_temp.init(NULL);
screamer 12:1f1a50e973db 160 sen_press_temp.init(NULL);
screamer 28:0e774865873d 161 sen_distance.init_sensor(VL53L0X_DEFAULT_ADDRESS);
screamer 10:b27c962b3c3f 162
screamer 10:b27c962b3c3f 163 /// Call sensors enable routines
screamer 12:1f1a50e973db 164 sen_hum_temp.enable();
screamer 12:1f1a50e973db 165 sen_press_temp.enable();
JimCarver 35:cbbafa9c3e15 166
screamer 10:b27c962b3c3f 167
screamer 29:6ff737b67e7d 168 sen_hum_temp.read_id(&id1);
screamer 29:6ff737b67e7d 169 sen_press_temp.read_id(&id2);
screamer 10:b27c962b3c3f 170
screamer 29:6ff737b67e7d 171 printf("HTS221 humidity & temperature = 0x%X\n", id1);
screamer 29:6ff737b67e7d 172 printf("LPS22HB pressure & temperature = 0x%X\n", id2);
screamer 10:b27c962b3c3f 173
screamer 17:fc98adcf835a 174 printf("\n"); ;
screamer 10:b27c962b3c3f 175 }
screamer 10:b27c962b3c3f 176
screamer 10:b27c962b3c3f 177 /**
screamer 10:b27c962b3c3f 178 * Update sensors and report their values.
screamer 10:b27c962b3c3f 179 * This function is called periodically.
screamer 10:b27c962b3c3f 180 */
screamer 10:b27c962b3c3f 181 void sensors_update() {
JimCarver 35:cbbafa9c3e15 182 float temp1_value, temp2_value, humid_value, pressure_value;
screamer 32:2871fbeb627d 183 uint32_t distance_value, distance_reading;
screamer 10:b27c962b3c3f 184
JimCarver 35:cbbafa9c3e15 185 if(!dflag++) { /* Only update the sensors once a minute */
JimCarver 35:cbbafa9c3e15 186 sen_hum_temp.get_humidity(&humid_value);
JimCarver 35:cbbafa9c3e15 187 sen_hum_temp.get_temperature(&temp1_value);
JimCarver 35:cbbafa9c3e15 188 sen_press_temp.get_pressure(&pressure_value);
JimCarver 35:cbbafa9c3e15 189 sen_press_temp.get_temperature(&temp2_value);
screamer 32:2871fbeb627d 190 res_humidity->set_value(humid_value);
screamer 32:2871fbeb627d 191 res_temperature->set_value(temp1_value);
screamer 32:2871fbeb627d 192 res_pressure->set_value(pressure_value);
screamer 32:2871fbeb627d 193 res_temperature2->set_value(temp2_value);
JimCarver 35:cbbafa9c3e15 194 if(ErrorLockoutTime != 0) {
JimCarver 35:cbbafa9c3e15 195 ErrorLockoutTime--;
JimCarver 35:cbbafa9c3e15 196 if(ErrorLockoutTime == 0) {
JimCarver 35:cbbafa9c3e15 197 printf("Unlocked\r\n");
JimCarver 35:cbbafa9c3e15 198 CodeError = 0;
JimCarver 35:cbbafa9c3e15 199 }
JimCarver 35:cbbafa9c3e15 200 }
JimCarver 35:cbbafa9c3e15 201 }
JimCarver 35:cbbafa9c3e15 202 if(dflag > 3) dflag = 0;
JimCarver 35:cbbafa9c3e15 203 distance_reading = sen_distance.get_distance(&distance_value);
JimCarver 35:cbbafa9c3e15 204
JimCarver 35:cbbafa9c3e15 205
JimCarver 35:cbbafa9c3e15 206 if (distance_reading == VL53L0X_ERROR_NONE) {
JimCarver 35:cbbafa9c3e15 207 // printf("VL53L0X dist: %7ld mm\n", distance_value);
screamer 32:2871fbeb627d 208 res_distance->set_value((int)distance_value);
JimCarver 35:cbbafa9c3e15 209 } else {
JimCarver 35:cbbafa9c3e15 210 // printf("VL53L0X dist: -- \n");
JimCarver 35:cbbafa9c3e15 211 distance_value = 1999;
JimCarver 35:cbbafa9c3e15 212 res_distance->set_value((int)distance_value);
screamer 28:0e774865873d 213 }
screamer 10:b27c962b3c3f 214 }
screamer 10:b27c962b3c3f 215
adustm 4:cf7342047b4d 216 int main(void) {
screamer 17:fc98adcf835a 217 printf("\nStarting Simple Pelion Device Management Client example\n");
JimCarver 35:cbbafa9c3e15 218 ConnectTrue = 0;
JimCarver 35:cbbafa9c3e15 219 CodeError = 0;
JimCarver 35:cbbafa9c3e15 220 DoorActivate = 0;
screamer 29:6ff737b67e7d 221 int storage_status = fs.mount(&sd);
screamer 29:6ff737b67e7d 222 if (storage_status != 0) {
screamer 29:6ff737b67e7d 223 printf("Storage mounting failed.\n");
screamer 29:6ff737b67e7d 224 }
screamer 30:15743b79c6cb 225 // If the User button is pressed ons start, then format storage.
screamer 29:6ff737b67e7d 226 bool btn_pressed = (button.read() == MBED_CONF_APP_BUTTON_PRESSED_STATE);
screamer 29:6ff737b67e7d 227 if (btn_pressed) {
screamer 29:6ff737b67e7d 228 printf("User button is pushed on start...\n");
screamer 29:6ff737b67e7d 229 }
screamer 30:15743b79c6cb 230
screamer 29:6ff737b67e7d 231 if (storage_status || btn_pressed) {
screamer 29:6ff737b67e7d 232 printf("Formatting the storage...\n");
screamer 30:15743b79c6cb 233 int storage_status = StorageHelper::format(&fs, &sd);
screamer 10:b27c962b3c3f 234 if (storage_status != 0) {
screamer 13:42b49a0caade 235 printf("ERROR: Failed to reformat the storage (%d).\n", storage_status);
screamer 10:b27c962b3c3f 236 }
screamer 28:0e774865873d 237 } else {
screamer 28:0e774865873d 238 printf("You can hold the user button during boot to format the storage and change the device identity.\n");
screamer 10:b27c962b3c3f 239 }
screamer 10:b27c962b3c3f 240
screamer 10:b27c962b3c3f 241 sensors_init();
screamer 10:b27c962b3c3f 242
adustm 4:cf7342047b4d 243 // Connect to the internet (DHCP is expected to be on)
screamer 13:42b49a0caade 244 printf("Connecting to the network using Wifi...\n");
MarceloSalazar 9:265744785d33 245 net = NetworkInterface::get_default_instance();
adustm 4:cf7342047b4d 246
screamer 10:b27c962b3c3f 247 nsapi_error_t net_status = -1;
screamer 10:b27c962b3c3f 248 for (int tries = 0; tries < 3; tries++) {
screamer 10:b27c962b3c3f 249 net_status = net->connect();
screamer 10:b27c962b3c3f 250 if (net_status == NSAPI_ERROR_OK) {
screamer 10:b27c962b3c3f 251 break;
screamer 10:b27c962b3c3f 252 } else {
screamer 13:42b49a0caade 253 printf("Unable to connect to network. Retrying...\n");
screamer 10:b27c962b3c3f 254 }
screamer 10:b27c962b3c3f 255 }
MarceloSalazar 9:265744785d33 256
screamer 10:b27c962b3c3f 257 if (net_status != NSAPI_ERROR_OK) {
screamer 13:42b49a0caade 258 printf("ERROR: Connecting to the network failed (%d)!\n", net_status);
adustm 1:e86b1cffc402 259 return -1;
adustm 1:e86b1cffc402 260 }
adustm 1:e86b1cffc402 261
MarceloSalazar 9:265744785d33 262 printf("Connected to the network successfully. IP address: %s\n", net->get_ip_address());
adustm 1:e86b1cffc402 263
screamer 17:fc98adcf835a 264 printf("Initializing Pelion Device Management Client...\n");
screamer 17:fc98adcf835a 265
MarceloSalazar 9:265744785d33 266 // SimpleMbedCloudClient handles registering over LwM2M to Pelion DM
MarceloSalazar 9:265744785d33 267 SimpleMbedCloudClient client(net, bd, &fs);
adustm 4:cf7342047b4d 268 int client_status = client.init();
adustm 4:cf7342047b4d 269 if (client_status != 0) {
screamer 13:42b49a0caade 270 printf("ERROR: Pelion Client initialization failed (%d)\n", client_status);
adustm 1:e86b1cffc402 271 return -1;
adustm 1:e86b1cffc402 272 }
adustm 1:e86b1cffc402 273
adustm 4:cf7342047b4d 274 // Creating resources, which can be written or read from the cloud
screamer 32:2871fbeb627d 275 res_button = client.create_resource("3200/0/5501", "Button Count");
screamer 12:1f1a50e973db 276 res_button->set_value(0);
screamer 12:1f1a50e973db 277 res_button->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 278 res_button->observable(true);
JimCarver 35:cbbafa9c3e15 279 //res_button->max_age(6000);
screamer 12:1f1a50e973db 280 res_button->attach_notification_callback(button_callback);
adustm 1:e86b1cffc402 281
JimCarver 35:cbbafa9c3e15 282 DoorControl = client.create_resource("3201/0/5853", "Door Control");
JimCarver 35:cbbafa9c3e15 283 DoorControl->set_value(1);
JimCarver 35:cbbafa9c3e15 284 DoorControl->methods(M2MMethod::GET | M2MMethod::PUT);
JimCarver 35:cbbafa9c3e15 285 DoorControl->attach_put_callback(put_callback);
screamer 33:cfd9430e7d1e 286
screamer 10:b27c962b3c3f 287 // Sensor resources
screamer 32:2871fbeb627d 288 res_temperature = client.create_resource("3303/0/5700", "Temperature HTS221 (C)");
screamer 12:1f1a50e973db 289 res_temperature->set_value(0);
screamer 12:1f1a50e973db 290 res_temperature->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 291 res_temperature->observable(true);
screamer 10:b27c962b3c3f 292
screamer 32:2871fbeb627d 293 res_humidity = client.create_resource("3304/0/5700", "Humidity");
screamer 12:1f1a50e973db 294 res_humidity->set_value(0);
screamer 12:1f1a50e973db 295 res_humidity->methods(M2MMethod::GET);
screamer 12:1f1a50e973db 296 res_humidity->observable(true);
screamer 10:b27c962b3c3f 297
screamer 32:2871fbeb627d 298 res_temperature2 = client.create_resource("3303/1/5700", "Temperature LPS22HB (C)");
screamer 13:42b49a0caade 299 res_temperature2->set_value(0);
screamer 13:42b49a0caade 300 res_temperature2->methods(M2MMethod::GET);
screamer 13:42b49a0caade 301 res_temperature2->observable(true);
screamer 13:42b49a0caade 302
screamer 32:2871fbeb627d 303 res_pressure = client.create_resource("3323/0/5700", "Pressure");
screamer 28:0e774865873d 304 res_pressure->set_value(0);
screamer 28:0e774865873d 305 res_pressure->methods(M2MMethod::GET);
screamer 28:0e774865873d 306 res_pressure->observable(true);
screamer 28:0e774865873d 307
screamer 32:2871fbeb627d 308 res_distance = client.create_resource("3330/0/5700", "Distance");
screamer 28:0e774865873d 309 res_distance->set_value((float)999.9);
screamer 13:42b49a0caade 310 res_distance->methods(M2MMethod::GET);
screamer 13:42b49a0caade 311 res_distance->observable(true);
screamer 11:8df4529f060d 312
MarceloSalazar 9:265744785d33 313 printf("Initialized Pelion Client. Registering...\n");
adustm 1:e86b1cffc402 314
adustm 4:cf7342047b4d 315 // Callback that fires when registering is complete
adustm 4:cf7342047b4d 316 client.on_registered(&registered);
adustm 1:e86b1cffc402 317
MarceloSalazar 9:265744785d33 318 // Register with Pelion DM
adustm 4:cf7342047b4d 319 client.register_and_connect();
adustm 1:e86b1cffc402 320
JimCarver 35:cbbafa9c3e15 321 int i = 6000; // wait up 600 seconds before attaching sensors and button events
screamer 12:1f1a50e973db 322 while (i-- > 0 && !client.is_client_registered()) {
screamer 12:1f1a50e973db 323 wait_ms(100);
screamer 12:1f1a50e973db 324 }
JimCarver 35:cbbafa9c3e15 325 ConnectTrue = 1;
screamer 11:8df4529f060d 326 button.fall(eventQueue.event(&button_press));
JimCarver 35:cbbafa9c3e15 327 res_button->set_value(0);
JimCarver 35:cbbafa9c3e15 328 sensors_update();
screamer 15:a0430d40a918 329 // The timer fires on an interrupt context, but debounces it to the eventqueue, so it's safe to do network operations
adustm 4:cf7342047b4d 330 Ticker timer;
screamer 11:8df4529f060d 331 timer.attach(eventQueue.event(&sensors_update), SENSORS_POLL_INTERVAL);
adustm 1:e86b1cffc402 332
adustm 4:cf7342047b4d 333 // You can easily run the eventQueue in a separate thread if required
adustm 4:cf7342047b4d 334 eventQueue.dispatch_forever();
adustm 1:e86b1cffc402 335 }
screamer 28:0e774865873d 336
MarceloSalazar 9:265744785d33 337 #endif