Hardware components | ||||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
Software apps and online services | ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
| ||||||
|
In this project, I am going to show how I made Alexa enabled home monitoring and controlling system using RSL10 Sense Development Board from ON Semiconductor. RSL10 is used to sense the environmental parameters (temperature, humidity, air pressure, and light intensity) of a room. An Alexa Skill was developed to remotely access these parameters and give commands to control those parameters. ESP8266 based Node MCU is used to receive MQTT message and turn on/off the light, fan according to the voice command.
Features- Temperature, Humidity, Air Pressure, Light Intensity, and Air Quality can be monitored remotely by using Alexa, Android App, and Web Dashboard.
- Temperature, Humidity and Light Intensity can be controlled by turning on/off the fan, humidifier, and light respectively through voice command.
- Above mentioned appliances can also be controlled automatically based on a preset threshold value.
Before further reading please watches the demo video:
How does the System Work?- i. The RSL10 Sense DB is used to sense the environmental parameters (e.g. temperature, humidity, air pressure, air quality, and light intensity).
- ii. RSL10 sends this data to an Android app using BLE (Bluetooth Low Energy).
- iii. The Android application uploads this data to the AWS DynamoDB table and Atmosphere Cloud. The Android app also used to visualize the data from the phone.
- iv. An AWS Lambda function reads the data from the DynamoDB table and provides to Alexa Skill Kit.
- v. Using a custom Alexa skill user can know any of the mentioned parameters and can request Alexa to turn on or off the light, fan.
- vi. According to the user request, Alexa Skill sends an MQTT message to the Broker.
- vii. A Node MCU is used to subscribe to the broker. After receiving the MQTT message it sends the control signal to the light/fan according to the received message.
RSL10-SENSE-DB is an ultra-low power consumption BLE enabled microcontroller board from ON semiconductor and can be used in low power IoT applications. The firmware for the board can be developed by ON Semiconductor IDE and Atmosphere IoT Platform. I used the Atmosphere IoT Platform for developing the firmware for my project. The atmosphere offers IoT solution builders the fastest and simplest way to build, connect, and manage complete sensor-to-cloud solutions including Android Application.
I used the Atmosphere Platform to develop firmware and smartphone application. To start working with the Atmosphere platform you need to create an account from the following link: https://platform.atmosphereiot.com/.
To start with RSL10 you can read this guide (Getting Started with RSL10-SENSE-GEVK) from Atmosphere.
You can also watch the following video before getting started.
First, you need to work in the firmware tab. The following image shows the visual design of the firmware for my project.
The following images show the properties for every element from left to right sequentially. The first connector is between interval element to sensor block. Then the BLE GATT characteristics. Finally, the connector properties between sensor to BLE are shown.
Then, you need to design the Application layout from the application tab. You can upload picture for background and image labels. In this stage, you need to add cloud event to upload the data to cloud.
The properties for every element is shown in the following images. The sequence is from left to right.
Finally, you need to work with Cloud events. Atmosphere cloud events and AWS DynamoDB elements are chosen from the elements toolbox. DynamoDB data will be used for Alexa Skill and Data Storage elements will be used to monitor from Atmosphere dashboard.
The following image shows the properties for DynamoDB elements and connectors properties.
We completed the firmware and smartphone app design. Now we need to upload the firmware to RSL10 Sense development board.
While uploading the program you will get the following message.
After completing the firmware uploading you will get the following confirmation message.
Before creating AWS DynamoDB table you should read this excellent guide (AWS Integration Setup Guide)
If you want to get some more help regarding Alexa Skill and AWS Lembda Setup you can read my previous project: https://www.hackster.io/25439/voice-controlled-smart-home-36e37e
I created a table named onsemi for storing the data from the RSL10. The table has 4 rows for storing humidity, temperature, pressure, and illumination. This row will be created automatically.
Step 3: Creating a Lambda FunctionAlexa Skill can trigger Lambda function. The Lambda function used in this project contains python code for accessing DynamoDB table and sending MQTT messege to MQTT Broker.
Read my talking weather station project to see the details of creating a Lambda Function for Alexa and DynamoDB: https://www.hackster.io/taifur/talking-weather-station-69864e
In this stage, I created a custom Alexa Skill for accessing environmental data from RSL10 and sending command for controlling room appliances according to the environmental parameters. The JSON code for the skill is attached in the code section.
If you want to know how to make a custom Alexa Skill read the tutorial: https://medium.com/crowdbotics/how-to-build-a-custom-amazon-alexa-skill-step-by-step-my-favorite-chess-player-dcc0edae53fb
For controlling the light/fan on receiving the MQTT message I used Node MCU as the main controller. Node MCU receives MQTT message from the broker and sends the control signal to the relay board according to the received message. Arduino development environment was used for developing the code for Node MCU. The source code is attached to the code section.
The following image shows a test hardware setup for my project.
We have completed all of our design work. It is the perfect time to connect RSL10 Sense board to the smartphone application. To do that you need to install Atmosphere IoT Android/IOS apps in your device.
If you use Android download and install Atmosphere IoT from Google Play Store. Log in with your Atmosphere account and click to add new device icon. You will find the device you designed. Click on the device and it will be connected.
After connecting successfully you will see the apps you designed earlier from Atmosphere cloud. You will also get the data from the RSL10 board.
If you get the data then Congratulation! You Made It. Enjoy!!!
Python Code for Lambda
Python"""
This code is developed by MD. KHAIRUL ALAM
for a demo project made by RSL10 from ON Semiconductor
"""
from __future__ import print_function
import xml.etree.ElementTree as etree
from datetime import datetime as dt
import paho.mqtt.client as mqtt
import boto3
import io
import time
dynamodb = boto3.resource('dynamodb')
table = dynamodb.Table('onsemi')
def on_connect(client, userdata, flags, rc):
print("connected")
def on_subscribe(client, obj, mid, granted_qos):
print("subscribed")
client = mqtt.Client()
client.on_connect = on_connect
#client.on_message = on_message
client.on_subscribe = on_subscribe
client.connect("mqtt.eclipse.org", 1883, 60)
#def on_message(client, obj, msg):
# received_message = str(msg.payload)
# print(msg.topic + " " + str(msg.qos) + " " + received_message)
#client.username_pw_set("cnpemclt", "ccZRVtdCTqID")
#client.connect("mqtt.eclipse.org", "1883")
#client.connect("m12.cloudmqtt.com", 15708, 60)
# Start subscribe, with QoS level 0
#client.subscribe("test/door", 0)
def read_table_item(table_name, pk_name, pk_value):
"""
Return item read by primary key.
"""
table = dynamodb.Table(table_name)
response = table.get_item(Key={pk_name: pk_value})
if 'Item' in response:
value = response['Item']['value']
#print (value)
return value
def lambda_handler(event, context):
""" Route the incoming request based on type (LaunchRequest, IntentRequest,
etc.) The JSON body of the request is provided in the event parameter.
"""
#print("event.session.application.applicationId=" +
# event['session']['application']['applicationId'])
"""
Uncomment this if statement and populate with your skill's application ID to
prevent someone else from configuring a skill that sends requests to this
function.
"""
# if (event['session']['application']['applicationId'] !=
# "amzn1.echo-sdk-ams.app.[unique-value-here]"):
# raise ValueError("Invalid Application ID")
if event['session']['new']:
on_session_started({'requestId': event['request']['requestId']},
event['session'])
if event['request']['type'] == "LaunchRequest":
return on_launch(event['request'], event['session'])
elif event['request']['type'] == "IntentRequest":
return on_intent(event['request'], event['session'])
elif event['request']['type'] == "SessionEndedRequest":
return on_session_ended(event['request'], event['session'])
def on_session_started(session_started_request, session):
""" Called when the session starts """
print("on_session_started requestId=" + session_started_request['requestId']
+ ", sessionId=" + session['sessionId'])
def on_launch(launch_request, session):
""" Called when the user launches the skill without specifying what they
want
"""
print("on_launch requestId=" + launch_request['requestId'] +
", sessionId=" + session['sessionId'])
# Dispatch to your skill's launch
return get_welcome_response()
def on_intent(intent_request, session):
""" Called when the user specifies an intent for this skill """
print("on_intent requestId=" + intent_request['requestId'] +
", sessionId=" + session['sessionId'])
intent = intent_request['intent']
intent_name = intent_request['intent']['name']
# Dispatch to your skill's intent handlers
if intent_name == "TemperatureSensorIntent":
return temperature_read(intent, session)
elif intent_name == "HumiditySensorIntent":
return humidity_read(intent, session)
elif intent_name == "LightSensorIntent":
return light_read(intent, session)
elif intent_name == "LightRequiredIntent":
return light_required(intent, session)
elif intent_name == "PressureSensorIntent":
return pressure_read(intent, session)
elif intent_name == "AirqualitySensorIntent":
return airquality_read(intent, session)
elif intent_name == "AllSensorIntent":
return all_sensor_read(intent, session)
elif intent_name == "ControlLightIntent":
return turn_on_light(intent, session)
elif intent_name == "ControlLightOffIntent":
return turn_off_light(intent, session)
elif intent_name == "FanOnIntent":
return turn_on_fan(intent, session)
elif intent_name == "FanOffIntent":
return turn_off_fan(intent, session)
elif intent_name == "AMAZON.HelpIntent":
return get_welcome_response()
elif intent_name == "AMAZON.StopIntent" or intent_name == "AMAZON.CancelIntent":
return session_end(intent, session)
else:
raise ValueError("Invalid intent")
def on_session_ended(session_ended_request, session):
""" Called when the user ends the session.
Is not called when the skill returns should_end_session=true
"""
print("on_session_ended requestId=" + session_ended_request['requestId'] +
", sessionId=" + session['sessionId'])
# add cleanup logic here
# --------------- Functions that control the skill's behavior ------------------
def get_welcome_response():
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
session_attributes = {}
card_title = "Welcome"
speech_output = "Welcome to the room app. " \
"I know your room temperature, humidity, light intensity, air quality, air pressure. " \
" You can ask me about any parameter."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = "Please ask me like, " \
"What is the temperature?"
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def temperature_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result = read_table_item("onsemi", "serial", "temperature")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Reading Temperature"
speech_output = "The room temperature is {0:.2f} degree centigrade.".format(result)
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def humidity_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result = read_table_item("onsemi", "serial", "humidity")
#humidity = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Reading Humidity"
speech_output = "The humidity is {0:.2f} percent.".format(result)
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def light_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result = read_table_item("onsemi", "serial", "light")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Reading Light"
speech_output = "The light intensity in your room is %d Lumen per square meter." %(result)
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def pressure_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result = read_table_item("onsemi", "serial", "pressure")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Reading Pressure"
speech_output = "The Atmospheric Pressure in your room is %d hectopascals." %(result)
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def light_required(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
#client.publish("walabot/robot/arm/...", "pick")
#time.sleep(2)
result = read_table_item("onsemi", "serial", "light")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Calculating..."
if result < 240:
speech_output = "Your room illumination is not enough for reading. The recommended light level for reading is 250 to 300 lux, where you have only %d lux" %(result)
elif result >250 and result <=400:
speech_output = "Yes, your room illumination is good for reading and normal office work."
elif result >700:
speech_output = "Your room illumination is more than enough."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = False
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def turn_on_light(intent, session):
""" mqtt message sent to turn on the light
"""
client.publish("onsemi/light", "1ON")
time.sleep(2)
session_attributes = {}
card_title = "Calculating..."
speech_output = "Light is on."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def turn_off_light(intent, session):
""" mqtt message sent ot turn off the light
"""
client.publish("onsemi/light", "2OFF")
time.sleep(2)
session_attributes = {}
card_title = "Calculating..."
speech_output = "Light is off."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def turn_on_fan(intent, session):
""" sent mqtt message for turning on the fan
"""
client.publish("onsemi/light", "3ON")
time.sleep(2)
session_attributes = {}
card_title = "Calculating..."
speech_output = "Fan is on."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def turn_off_fan(intent, session):
""" sent mqtt message for turning off the fan
"""
client.publish("onsemi/light", "4OFF")
time.sleep(2)
session_attributes = {}
card_title = "Calculating..."
speech_output = "Fan is off."
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def airquality_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result = read_table_item("onsemi", "serial", "airquality")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Reading TVOC"
if result <= 50:
speech_output = "Total Volatile Organic Compounds in your room air is %d Parts per billion. It seems good." %(result)
elif result >50 and result <=150:
speech_output = "Total Volatile Organic Compounds in your room air is %d Parts per billion. It seems air quality is not so good." %(result)
elif result >150 and result <=250:
speech_output = "Total Volatile Organic Compounds in your room air is %d Parts per billion and air is polluted." %(result)
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def all_sensor_read(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
result1 = read_table_item("onsemi", "serial", "temperature")
result2 = read_table_item("onsemi", "serial", "humidity")
result3 = read_table_item("onsemi", "serial", "light")
result4 = read_table_item("onsemi", "serial", "pressure")
result5 = read_table_item("onsemi", "serial", "airquality")
#temperature = float("{0:.2f}".format(result))
session_attributes = {}
card_title = "Varifying room condition"
speech_output1 = "Your room temperature is %.2f degree centigrade and humidity is %.2f percent." %(result1, result2)
speech_output2 = " Ambiant light is %d lux. Atmospheric air pressure in your room is %d hectopascals and air quality is good." %(result3, result4)
speech_output = speech_output1 + speech_output2
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
def session_end(intent, session):
""" If we wanted to initialize the session to have some attributes we could
add those here
"""
session_attributes = {}
card_title = "End"
speech_output = "Thank you for calling me. Have a nice day!"
# If the user either does not reply to the welcome message or says something
# that is not understood, they will be prompted again with this text.
reprompt_text = ""
should_end_session = True
return build_response(session_attributes, build_speechlet_response(
card_title, speech_output, reprompt_text, should_end_session))
# --------------- Helpers that build all of the responses ----------------------
def build_speechlet_response(title, output, reprompt_text, should_end_session):
return {
'outputSpeech': {
'type': 'PlainText',
'text': output
},
'card': {
'type': 'Simple',
'title': title,
'content': output
},
'reprompt': {
'outputSpeech': {
'type': 'PlainText',
'text': reprompt_text
}
},
'shouldEndSession': should_end_session
}
def build_response(session_attributes, speechlet_response):
return {
'version': '1.0',
'sessionAttributes': session_attributes,
'response': speechlet_response
}
Arduino code for Node MCU
Arduino/*
Developed by Md. Khairul Alam
Arduino PubSub Library is need to add.
Download from: https://github.com/knolleary/pubsubclient
*/
#include <ESP8266WiFi.h>
#include <PubSubClient.h>
// Update these with values suitable for your network.
const char* ssid = "..............";
const char* password = "...........";
const char* mqtt_server = "mqtt.eclipse.org";
int light = 0;
int fan = 2;
WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;
void setup_wifi() {
delay(10);
// We start by connecting to a WiFi network
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
// Switch on the LED if an 1 was received as first character
if ((char)payload[0] == '1') {
digitalWrite(light, HIGH); // Turn the LED on (Note that LOW is the voltage level
Serial.print("Light on");
// but actually the LED is on; this is because
// it is active low on the ESP-01)
}
else if ((char)payload[0] == '2') {
digitalWrite(light, LOW); // Turn the LED on (Note that LOW is the voltage level
Serial.print("Light off");
// but actually the LED is on; this is because
// it is active low on the ESP-01)
}
else if ((char)payload[0] == '3') {
digitalWrite(fan, HIGH); // Turn the LED on (Note that LOW is the voltage level
Serial.print("Fan on");
// but actually the LED is on; this is because
// it is active low on the ESP-01)
}
else if ((char)payload[0] == '4') {
digitalWrite(fan, LOW); // Turn the LED on (Note that LOW is the voltage level
Serial.print("Fan off");
// but actually the LED is on; this is because
// it is active low on the ESP-01)
}
}
void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
// Create a random client ID
String clientId = "ESP8266Client-";
clientId += String(random(0xffff), HEX);
// Attempt to connect
if (client.connect(clientId.c_str())) {
Serial.println("connected");
// Once connected, publish an announcement...
client.publish("outTopic", "hello world");
// ... and resubscribe
client.subscribe("onsemi/light");
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(light, OUTPUT); // Initialize the BUILTIN_LED pin as an output
pinMode(fan, OUTPUT); // Initialize the BUILTIN_LED pin as an output
Serial.begin(115200);
setup_wifi();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
#include "callbacks.h"
//HEADER START
//HEADER END
void ATMO_Setup() {
}
ATMO_Status_t Interval_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Interval_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_INTERVAL_Handle_t intervalHandle;
ATMO_INTERVAL_AddAbilityInterval(
ATMO_PROPERTY(Interval, instance),
ATMO_ABILITY(Interval, interval),
ATMO_PROPERTY(Interval, time),
&intervalHandle
);
return ATMO_Status_Success;
}
ATMO_Status_t Interval_interval(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t BME680_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t BME680_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
BME680_Config_t config;
config.i2cInstance = ATMO_PROPERTY(BME680, i2cInstance );
if ( !BME680_Init( &config ) )
{
return ATMO_Status_Fail;
}
return ATMO_Status_Success;
}
ATMO_Status_t BME680_readTemperature(ATMO_Value_t *in, ATMO_Value_t *out) {
float temperature = 0.0;
if ( BME680_GetTempData( &temperature ) != BME680_Status_Success )
{
return ATMO_Status_Fail;
}
ATMO_CreateValueFloat( out, temperature );
return ATMO_Status_Success;
}
ATMO_Status_t BME680_readHumidity(ATMO_Value_t *in, ATMO_Value_t *out) {
float humidity = 0.0;
if ( BME680_GetHumidity( &humidity ) != BME680_Status_Success )
{
return ATMO_Status_Fail;
}
ATMO_CreateValueFloat( out, humidity );
return ATMO_Status_Success;
}
ATMO_Status_t BME680_readPressure(ATMO_Value_t *in, ATMO_Value_t *out) {
float pressure = 0.0;
if ( BME680_GetPressure( &pressure ) != BME680_Status_Success )
{
return ATMO_Status_Fail;
}
ATMO_CreateValueFloat( out, pressure );
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_BLE_GATTSAddService(
ATMO_PROPERTY(Temperature, instance),
&ATMO_VARIABLE(Temperature, bleServiceHandle),
ATMO_PROPERTY(Temperature, bleServiceUuid));
uint8_t property = 0;
uint8_t permission = 0;
property |= ATMO_PROPERTY(Temperature, read) ? ATMO_BLE_Property_Read : 0;
property |= ATMO_PROPERTY(Temperature, write) ? ATMO_BLE_Property_Write : 0;
property |= ATMO_PROPERTY(Temperature, notify) ? ATMO_BLE_Property_Notify : 0;
permission |= ATMO_PROPERTY(Temperature, read) ? ATMO_BLE_Permission_Read : 0;
permission |= ATMO_PROPERTY(Temperature, write) ? ATMO_BLE_Permission_Write : 0;
ATMO_DATATYPE types[3] = {ATMO_PROPERTY(Temperature, writeDataType), ATMO_PROPERTY(Temperature, readDataType), ATMO_PROPERTY(Temperature, notifyDataType)};
ATMO_BLE_GATTSAddCharacteristic(
ATMO_PROPERTY(Temperature, instance),
&ATMO_VARIABLE(Temperature, bleCharacteristicHandle),
ATMO_VARIABLE(Temperature, bleServiceHandle),
ATMO_PROPERTY(Temperature, bleCharacteristicUuid),
property, permission, ATMO_GetMaxValueSize(3, 64, types));
ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
ATMO_PROPERTY(Temperature, instance),
ATMO_VARIABLE(Temperature, bleCharacteristicHandle),
ATMO_BLE_Characteristic_Written,
ATMO_ABILITY(Temperature, written));
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {
// Convert to the desired write data type
ATMO_Value_t convertedValue;
ATMO_InitValue(&convertedValue);
ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(Temperature, readDataType), in);
ATMO_BLE_GATTSSetCharacteristic(
ATMO_PROPERTY(Temperature, instance),
ATMO_VARIABLE(Temperature, bleCharacteristicHandle),
convertedValue.size,
(uint8_t *)convertedValue.data,
NULL);
ATMO_FreeValue(&convertedValue);
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_written(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CreateValueConverted(out, ATMO_PROPERTY(Temperature, writeDataType), in);
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Temperature_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_BLE_GATTSAddService(
ATMO_PROPERTY(Humidity, instance),
&ATMO_VARIABLE(Humidity, bleServiceHandle),
ATMO_PROPERTY(Humidity, bleServiceUuid));
uint8_t property = 0;
uint8_t permission = 0;
property |= ATMO_PROPERTY(Humidity, read) ? ATMO_BLE_Property_Read : 0;
property |= ATMO_PROPERTY(Humidity, write) ? ATMO_BLE_Property_Write : 0;
property |= ATMO_PROPERTY(Humidity, notify) ? ATMO_BLE_Property_Notify : 0;
permission |= ATMO_PROPERTY(Humidity, read) ? ATMO_BLE_Permission_Read : 0;
permission |= ATMO_PROPERTY(Humidity, write) ? ATMO_BLE_Permission_Write : 0;
ATMO_DATATYPE types[3] = {ATMO_PROPERTY(Humidity, writeDataType), ATMO_PROPERTY(Humidity, readDataType), ATMO_PROPERTY(Humidity, notifyDataType)};
ATMO_BLE_GATTSAddCharacteristic(
ATMO_PROPERTY(Humidity, instance),
&ATMO_VARIABLE(Humidity, bleCharacteristicHandle),
ATMO_VARIABLE(Humidity, bleServiceHandle),
ATMO_PROPERTY(Humidity, bleCharacteristicUuid),
property, permission, ATMO_GetMaxValueSize(3, 64, types));
ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
ATMO_PROPERTY(Humidity, instance),
ATMO_VARIABLE(Humidity, bleCharacteristicHandle),
ATMO_BLE_Characteristic_Written,
ATMO_ABILITY(Humidity, written));
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {
// Convert to the desired write data type
ATMO_Value_t convertedValue;
ATMO_InitValue(&convertedValue);
ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(Humidity, readDataType), in);
ATMO_BLE_GATTSSetCharacteristic(
ATMO_PROPERTY(Humidity, instance),
ATMO_VARIABLE(Humidity, bleCharacteristicHandle),
convertedValue.size,
(uint8_t *)convertedValue.data,
NULL);
ATMO_FreeValue(&convertedValue);
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_written(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CreateValueConverted(out, ATMO_PROPERTY(Humidity, writeDataType), in);
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Humidity_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_BLE_GATTSAddService(
ATMO_PROPERTY(Pressure, instance),
&ATMO_VARIABLE(Pressure, bleServiceHandle),
ATMO_PROPERTY(Pressure, bleServiceUuid));
uint8_t property = 0;
uint8_t permission = 0;
property |= ATMO_PROPERTY(Pressure, read) ? ATMO_BLE_Property_Read : 0;
property |= ATMO_PROPERTY(Pressure, write) ? ATMO_BLE_Property_Write : 0;
property |= ATMO_PROPERTY(Pressure, notify) ? ATMO_BLE_Property_Notify : 0;
permission |= ATMO_PROPERTY(Pressure, read) ? ATMO_BLE_Permission_Read : 0;
permission |= ATMO_PROPERTY(Pressure, write) ? ATMO_BLE_Permission_Write : 0;
ATMO_DATATYPE types[3] = {ATMO_PROPERTY(Pressure, writeDataType), ATMO_PROPERTY(Pressure, readDataType), ATMO_PROPERTY(Pressure, notifyDataType)};
ATMO_BLE_GATTSAddCharacteristic(
ATMO_PROPERTY(Pressure, instance),
&ATMO_VARIABLE(Pressure, bleCharacteristicHandle),
ATMO_VARIABLE(Pressure, bleServiceHandle),
ATMO_PROPERTY(Pressure, bleCharacteristicUuid),
property, permission, ATMO_GetMaxValueSize(3, 64, types));
ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
ATMO_PROPERTY(Pressure, instance),
ATMO_VARIABLE(Pressure, bleCharacteristicHandle),
ATMO_BLE_Characteristic_Written,
ATMO_ABILITY(Pressure, written));
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {
// Convert to the desired write data type
ATMO_Value_t convertedValue;
ATMO_InitValue(&convertedValue);
ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(Pressure, readDataType), in);
ATMO_BLE_GATTSSetCharacteristic(
ATMO_PROPERTY(Pressure, instance),
ATMO_VARIABLE(Pressure, bleCharacteristicHandle),
convertedValue.size,
(uint8_t *)convertedValue.data,
NULL);
ATMO_FreeValue(&convertedValue);
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_written(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CreateValueConverted(out, ATMO_PROPERTY(Pressure, writeDataType), in);
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t Pressure_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t NOA1305AmbientLight_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t NOA1305AmbientLight_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
if(!NOA1305_Init(ATMO_PROPERTY(NOA1305AmbientLight, i2cInstance)))
{
return ATMO_Status_Fail;
}
return ATMO_Status_Success;
}
ATMO_Status_t NOA1305AmbientLight_readAmbientLight(ATMO_Value_t *in, ATMO_Value_t *out) {
uint32_t ambientLightLux = 0;
if(!NOA1305_GetAmbientLight(&ambientLightLux))
{
return ATMO_Status_Fail;
}
ATMO_CreateValueUnsignedInt(out, ambientLightLux);
return ATMO_Status_Success;
}
ATMO_Status_t light_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t light_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_BLE_GATTSAddService(
ATMO_PROPERTY(light, instance),
&ATMO_VARIABLE(light, bleServiceHandle),
ATMO_PROPERTY(light, bleServiceUuid));
uint8_t property = 0;
uint8_t permission = 0;
property |= ATMO_PROPERTY(light, read) ? ATMO_BLE_Property_Read : 0;
property |= ATMO_PROPERTY(light, write) ? ATMO_BLE_Property_Write : 0;
property |= ATMO_PROPERTY(light, notify) ? ATMO_BLE_Property_Notify : 0;
permission |= ATMO_PROPERTY(light, read) ? ATMO_BLE_Permission_Read : 0;
permission |= ATMO_PROPERTY(light, write) ? ATMO_BLE_Permission_Write : 0;
ATMO_DATATYPE types[3] = {ATMO_PROPERTY(light, writeDataType), ATMO_PROPERTY(light, readDataType), ATMO_PROPERTY(light, notifyDataType)};
ATMO_BLE_GATTSAddCharacteristic(
ATMO_PROPERTY(light, instance),
&ATMO_VARIABLE(light, bleCharacteristicHandle),
ATMO_VARIABLE(light, bleServiceHandle),
ATMO_PROPERTY(light, bleCharacteristicUuid),
property, permission, ATMO_GetMaxValueSize(3, 64, types));
ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
ATMO_PROPERTY(light, instance),
ATMO_VARIABLE(light, bleCharacteristicHandle),
ATMO_BLE_Characteristic_Written,
ATMO_ABILITY(light, written));
return ATMO_Status_Success;
}
ATMO_Status_t light_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {
// Convert to the desired write data type
ATMO_Value_t convertedValue;
ATMO_InitValue(&convertedValue);
ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(light, readDataType), in);
ATMO_BLE_GATTSSetCharacteristic(
ATMO_PROPERTY(light, instance),
ATMO_VARIABLE(light, bleCharacteristicHandle),
convertedValue.size,
(uint8_t *)convertedValue.data,
NULL);
ATMO_FreeValue(&convertedValue);
return ATMO_Status_Success;
}
ATMO_Status_t light_written(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CreateValueConverted(out, ATMO_PROPERTY(light, writeDataType), in);
return ATMO_Status_Success;
}
ATMO_Status_t light_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t light_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
BHI160_Config_t config;
config.i2cInstance = ATMO_PROPERTY(EmbeddedBHI160, i2cInstance);
config.gpioInstance = ATMO_PROPERTY(EmbeddedBHI160, gpioInstance);
config.intPin = ATMO_PROPERTY(EmbeddedBHI160, intPin);
if(!BHI160_Init(&config))
{
return ATMO_Status_Fail;
}
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_xAcceleration(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(&data, NULL, NULL);
ATMO_CreateValueFloat(out, data.x);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_yAcceleration(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(&data, NULL, NULL);
ATMO_CreateValueFloat(out, data.y);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_zAcceleration(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(&data, NULL, NULL);
ATMO_CreateValueFloat(out, data.z);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_acceleration(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(&data, NULL, NULL);
ATMO_CreateValue3dVectorFloat(out, &data);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_angularRate(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, &data, NULL);
ATMO_CreateValue3dVectorFloat(out, &data);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_xAngularRate(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, &data, NULL);
ATMO_CreateValueFloat(out, data.x);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_yAngularRate(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, &data, NULL);
ATMO_CreateValueFloat(out, data.y);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_zAngularRate(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, &data, NULL);
ATMO_CreateValueFloat(out, data.z);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_orientation(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, NULL, &data);
ATMO_CreateValue3dVectorFloat(out, &data);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_xOrientation(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, NULL, &data);
ATMO_CreateValueFloat(out, data.x);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_yOrientation(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, NULL, &data);
ATMO_CreateValueFloat(out, data.y);
return ATMO_Status_Success;
}
ATMO_Status_t EmbeddedBHI160_zOrientation(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_3dFloatVector_t data;
BHI160_GetData(NULL, NULL, &data);
ATMO_CreateValueFloat(out, data.z);
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_trigger(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_setup(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_BLE_GATTSAddService(
ATMO_PROPERTY(acceleration, instance),
&ATMO_VARIABLE(acceleration, bleServiceHandle),
ATMO_PROPERTY(acceleration, bleServiceUuid));
uint8_t property = 0;
uint8_t permission = 0;
property |= ATMO_PROPERTY(acceleration, read) ? ATMO_BLE_Property_Read : 0;
property |= ATMO_PROPERTY(acceleration, write) ? ATMO_BLE_Property_Write : 0;
property |= ATMO_PROPERTY(acceleration, notify) ? ATMO_BLE_Property_Notify : 0;
permission |= ATMO_PROPERTY(acceleration, read) ? ATMO_BLE_Permission_Read : 0;
permission |= ATMO_PROPERTY(acceleration, write) ? ATMO_BLE_Permission_Write : 0;
ATMO_DATATYPE types[3] = {ATMO_PROPERTY(acceleration, writeDataType), ATMO_PROPERTY(acceleration, readDataType), ATMO_PROPERTY(acceleration, notifyDataType)};
ATMO_BLE_GATTSAddCharacteristic(
ATMO_PROPERTY(acceleration, instance),
&ATMO_VARIABLE(acceleration, bleCharacteristicHandle),
ATMO_VARIABLE(acceleration, bleServiceHandle),
ATMO_PROPERTY(acceleration, bleCharacteristicUuid),
property, permission, ATMO_GetMaxValueSize(3, 64, types));
ATMO_BLE_GATTSRegisterCharacteristicAbilityHandle(
ATMO_PROPERTY(acceleration, instance),
ATMO_VARIABLE(acceleration, bleCharacteristicHandle),
ATMO_BLE_Characteristic_Written,
ATMO_ABILITY(acceleration, written));
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_setValue(ATMO_Value_t *in, ATMO_Value_t *out) {
// Convert to the desired write data type
ATMO_Value_t convertedValue;
ATMO_InitValue(&convertedValue);
ATMO_CreateValueConverted(&convertedValue, ATMO_PROPERTY(acceleration, readDataType), in);
ATMO_BLE_GATTSSetCharacteristic(
ATMO_PROPERTY(acceleration, instance),
ATMO_VARIABLE(acceleration, bleCharacteristicHandle),
convertedValue.size,
(uint8_t *)convertedValue.data,
NULL);
ATMO_FreeValue(&convertedValue);
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_written(ATMO_Value_t *in, ATMO_Value_t *out) {
ATMO_CreateValueConverted(out, ATMO_PROPERTY(acceleration, writeDataType), in);
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_subscibed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
ATMO_Status_t acceleration_unsubscribed(ATMO_Value_t *in, ATMO_Value_t *out) {
return ATMO_Status_Success;
}
//FOOTER START
//FOOTER END
{
"interactionModel": {
"languageModel": {
"invocationName": "room master",
"intents": [
{
"name": "AMAZON.FallbackIntent",
"samples": []
},
{
"name": "AMAZON.CancelIntent",
"samples": []
},
{
"name": "AMAZON.HelpIntent",
"samples": []
},
{
"name": "AMAZON.StopIntent",
"samples": []
},
{
"name": "AMAZON.NavigateHomeIntent",
"samples": []
},
{
"name": "TemperatureSensorIntent",
"slots": [],
"samples": [
"amount of temperature",
"value of temperature",
"room temperature condition",
"about temperature",
"tell temperature",
"how much cold my room is",
"how much hot my room is",
"Tell the temperature",
"What is the room temperature",
"What is the temperature"
]
},
{
"name": "HumiditySensorIntent",
"slots": [],
"samples": [
"value of humidity",
"humidity percentage",
"percentage of humidity",
"amount of humidity",
"humidity amount",
"humidity situation",
"room humidity",
"about my room humidity",
"what about humidity",
"What is the room humidity",
"What is the humidity"
]
},
{
"name": "LightSensorIntent",
"slots": [],
"samples": [
"what is the light intensity in my room",
"what is the light intensity of my room",
"what is the room light intensity",
"about the light intensity",
"about the light amount",
"what is the light amount",
"What is the light intensity"
]
},
{
"name": "PressureSensorIntent",
"slots": [],
"samples": [
"value of air pressure",
"amount of air pressure",
"value of atmospheric pressure",
"amount of atmospheric pressure",
"what is the atmospheric pressure",
"how abou air pressure",
"What is the air pressure"
]
},
{
"name": "AirqualitySensorIntent",
"slots": [],
"samples": [
"waht is the room air quality",
"what about room air quality",
"about room air quality",
"air is good or not",
"is the air is good",
"what is the air purity",
"about air quality",
"What is the air quality"
]
},
{
"name": "AllSensorIntent",
"slots": [],
"samples": [
"about environmental condition of my room",
"about environmental parameters of my room",
"about room situation",
"about room environmrnt",
"What about room environment"
]
},
{
"name": "LightRequiredIntent",
"slots": [],
"samples": [
"is it ok to read in this illumination",
"is it ok to read in this light",
"is the light is enough to read",
"is the light is ok to read",
"is it ok to read",
"is the light is enough for reading",
"Is my illumination is enough for reading",
"Is the illumination is enough for reading",
"Is illumination is enough for reading",
"Is my room light is enough for reading",
"Is my room illumination is enough for reading"
]
},
{
"name": "ControlLightIntent",
"slots": [],
"samples": [
"adjust the light for my work",
"I will work",
"I want to work",
"I want to write",
"I want to read",
"light on",
"on light",
"on the light",
"turn on the light"
]
},
{
"name": "ControlLightOffIntent",
"slots": [],
"samples": [
"I want to sleep",
"light off",
"off light",
"turn light off",
"turn off the light",
"off the light"
]
},
{
"name": "FanOnIntent",
"slots": [],
"samples": [
"it is hot",
"reduce temperature",
"i am feeling hot",
"decrease temperature",
"i think it is hot",
"on fan",
"on the fan",
"turn on the fan"
]
},
{
"name": "FanOffIntent",
"slots": [],
"samples": [
"make room hot",
"off fan",
"turn off the fan",
"turn off fan",
"increase temperature"
]
}
],
"types": []
}
}
}
Comments