how to use standard motion sensor device

chris michael
Posts: 3
Joined: Tue Dec 26, 2023 5:42 am

how to use standard motion sensor device

Postby chris michael » Tue Dec 26, 2023 5:55 am

Hi, I am new to the forum
I am trying to add a motion sensor device to my rainmaker project
I don't know the primary param nor how it works.
I am currently using a power param, but it is read/write, which means I can turn on and off the detection within the app, which I don't want
can somebody help

ESP_Piyush
Posts: 309
Joined: Wed Feb 20, 2019 7:02 am

Re: how to use standard motion sensor device

Postby ESP_Piyush » Wed Dec 27, 2023 10:47 am

Are you using esp-idf of Arduino? Can you share your current snippet which creates the device so that we can suggest appropriate changes?

chris michael
Posts: 3
Joined: Tue Dec 26, 2023 5:42 am

Re: how to use standard motion sensor device

Postby chris michael » Wed Dec 27, 2023 6:51 pm

[Codebox]static Device motion_sensor("Motion sensor", "esp.device.motion-sensor", NULL);[/Codebox]
Adding the device

[Codebox]#include "RMaker.h"
#include "WiFi.h"
#include "WiFiProv.h"
#include "AceButton.h"
#include "Preferences.h"
#include "DHT.h"
#include <SimpleTimer.h>
#include <RCSwitch.h>
Preferences pref;
using namespace ace_button;
RCSwitch mySwitch = RCSwitch();
SimpleTimer Timer;
const char *service_name = "PROV_12345";
const char *pop = "1234567";
// define the Device Names
char deviceName_1[] = "TubeLight";
char deviceName_2[] = "WarmLight";
char deviceName_3[] = "BulbLight";
char deviceName_4[] = "Outlet";
// define the GPIO connected with Relays and switches
static uint8_t RelayPin1 = 23; //D23
static uint8_t RelayPin2 = 22; //D22
static uint8_t RelayPin3 = 21; //D21
static uint8_t RelayPin4 = 19; //D19
static uint8_t SwitchPin1 = 13; //D13
static uint8_t SwitchPin2 = 12; //D12
static uint8_t SwitchPin3 = 14; //D14
static uint8_t SwitchPin4 = 27; //D27
static uint8_t fan_switch = 26; //D26
static uint8_t Fanplus = 25; //D25
static uint8_t Fanminus = 33; //D33
static uint8_t pir = 25; //D25
static uint8_t DHTPIN = 33;
static uint8_t wifiLed = 2; //D2
static uint8_t gpio_reset = 0;
int FanState = 0 ;
bool toggleState_1 = LOW; //Define integer to remember the toggle state for relay 1
bool toggleState_2 = LOW; //Define integer to remember the toggle state for relay 2
bool toggleState_3 = LOW; //Define integer to remember the toggle state for relay 3
bool toggleState_4 = LOW; //Define integer to remember the toggle state for relay 4
bool toggleState_5 = LOW; //Define integer to remember the toggle state for relay 5
bool toggleState_8 = LOW; //Define integer to remember the toggle state for relay 5
bool pir_state = 0;
int Slider_Value = 0;
int curr_speed = 0;
bool Speed = true;
ButtonConfig config1;
AceButton button1(&config1);
ButtonConfig config2;
AceButton button2(&config2);
ButtonConfig config3;
AceButton button3(&config3);
ButtonConfig config4;
AceButton button4(&config4);
ButtonConfig config5;
AceButton button5(&config5);
ButtonConfig config6;
AceButton button6(&config6);
ButtonConfig config7;
AceButton button7(&config7);
void handleEvent1(AceButton*, uint8_t, uint8_t);
void handleEvent2(AceButton*, uint8_t, uint8_t);
void handleEvent3(AceButton*, uint8_t, uint8_t);
void handleEvent4(AceButton*, uint8_t, uint8_t);
void handleEvent5(AceButton*, uint8_t, uint8_t);
void handleEvent6(AceButton*, uint8_t, uint8_t);
void handleEvent7(AceButton*, uint8_t, uint8_t);
//The framework provides some standard device types like Switch, LightBulb, Fan, temperature sensor.
static LightBulb my_switch1(deviceName_1, &RelayPin1);
static LightBulb my_switch2(deviceName_2, &RelayPin2);
static LightBulb my_switch3(deviceName_3, &RelayPin3);
static Device my_outlet(deviceName_4, "esp.device.outlet", NULL);//refer note1
static Device motion_sensor("Motion sensor", "esp.device.motion-sensor", NULL);
static Fan my_fan("Fan");
static TemperatureSensor temperature("Temperature");
static TemperatureSensor humidity("Humidity");

DHT dht(DHTPIN, DHT11);

void sysProvEvent(arduino_event_t *sys_event)
{
switch (sys_event->event_id) {
case ARDUINO_EVENT_PROV_START:
#if CONFIG_IDF_TARGET_ESP32S2
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on SoftAP\n", service_name, pop);
printQR(service_name, pop, "softap");
#else
Serial.printf("\nProvisioning Started with name \"%s\" and PoP \"%s\" on BLE\n", service_name, pop);
printQR(service_name, pop, "ble");
#endif
break;
case ARDUINO_EVENT_PROV_INIT:
wifi_prov_mgr_disable_auto_stop(10000);
break;
case ARDUINO_EVENT_PROV_CRED_SUCCESS:
wifi_prov_mgr_stop_provisioning();
break;
default:;
}
}
void write_callback(Device *device, Param *param, const param_val_t val, void *priv_data, write_ctx_t *ctx)
{
const char *device_name = device->getDeviceName();
const char *param_name = param->getParamName();

if (strcmp(device_name, "Fan") == 0){
if (strcmp(param_name, "Power") == 0){
Serial.printf("\nReceived value = %d for %s - %s\n", val.val.b, device_name, param_name);
Speed = val.val.b;
if (Speed) {
mySwitch.send("10000100010110010011111001000011");
my_fan.updateAndReportParam("Power", 1);
toggleState_5 = !toggleState_5;
}
else{
SZERO();
}
}
}
if (strcmp(param_name, "Speed") == 0){
Serial.printf("\nReceived value = %d for %s - %s\n", val.val.i, device_name, param_name);
int Slider_Value = val.val.i;
int slider = map(Slider_Value, 0, 100, 0, 5);
if (Speed){
if (slider == 1){
SONE();
}
if (slider == 0){
SZERO();
}
if (slider == 2){
STWO();
}
if (slider == 3){
STHREE();
}
if (slider == 4){
SFOUR();
}
if (slider == 5){
SFIVE();
}
else{}
param->updateAndReport(val);
}
}
if(strcmp(device_name, deviceName_1) == 0) {
Serial.printf("Lightbulb = %s\n", val.val.b? "true" : "false");
if(strcmp(param_name, "Power") == 0) {
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
toggleState_1 = val.val.b;
(toggleState_1 == false) ? digitalWrite(RelayPin1, HIGH) : digitalWrite(RelayPin1, LOW);
param->updateAndReport(val);
}
}
else if(strcmp(device_name, deviceName_2) == 0) {
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
if(strcmp(param_name, "Power") == 0) {
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
toggleState_2 = val.val.b;
(toggleState_2 == false) ? digitalWrite(RelayPin2, HIGH) : digitalWrite(RelayPin2, LOW);
param->updateAndReport(val);
}
}
else if(strcmp(device_name, deviceName_3) == 0) {
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
if(strcmp(param_name, "Power") == 0) {
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
toggleState_3 = val.val.b;
(toggleState_3 == false) ? digitalWrite(RelayPin3, HIGH) : digitalWrite(RelayPin3, LOW);
param->updateAndReport(val);
}
}
else if(strcmp(device_name, deviceName_4) == 0) {
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
if(strcmp(param_name, "Power") == 0) {
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
toggleState_4 = val.val.b;
(toggleState_4 == false) ? digitalWrite(RelayPin4, HIGH) : digitalWrite(RelayPin4, LOW);
param->updateAndReport(val);
}
}
else if(strcmp(device_name, "Motion sensor") == 0) {
Serial.printf("Switch value = %s\n", val.val.b? "true" : "false");
if(strcmp(param_name, "Power") == 0) {
Serial.printf("Received value = %s for %s - %s\n", val.val.b? "true" : "false", device_name, param_name);
toggleState_8 = val.val.b;
param->updateAndReport(val);
}
}
}
void setup()
{
uint32_t chipId = 0;
Serial.begin(115200);
dht.begin();
// Set the Relays GPIOs as output mode
pinMode(RelayPin1, OUTPUT);
pinMode(RelayPin2, OUTPUT);
pinMode(RelayPin3, OUTPUT);
pinMode(RelayPin4, OUTPUT);
pinMode(wifiLed, OUTPUT);
// Configure the input GPIOs
pinMode(SwitchPin1, INPUT_PULLUP);
pinMode(SwitchPin2, INPUT_PULLUP);
pinMode(SwitchPin3, INPUT_PULLUP);
pinMode(SwitchPin4, INPUT_PULLUP);
pinMode(Fanplus, INPUT_PULLUP);
pinMode(Fanminus, INPUT_PULLUP);
pinMode(fan_switch, INPUT_PULLUP);
pinMode(pir, INPUT_PULLUP);
pinMode(gpio_reset, INPUT);
mySwitch.enableTransmit(18);
// Write to the GPIOs the default state on booting
digitalWrite(RelayPin1, HIGH);
digitalWrite(RelayPin2, HIGH);
digitalWrite(RelayPin3, HIGH);
digitalWrite(RelayPin4, HIGH);
digitalWrite(wifiLed, LOW);
config1.setEventHandler(button1Handler);
config2.setEventHandler(button2Handler);
config3.setEventHandler(button3Handler);
config4.setEventHandler(button4Handler);
config5.setEventHandler(button5Handler);
config6.setEventHandler(button6Handler);
config7.setEventHandler(button7Handler);
button1.init(SwitchPin1);
button2.init(SwitchPin2);
button3.init(SwitchPin3);
button4.init(SwitchPin4);
button5.init(fan_switch);
button6.init(Fanplus);
button7.init(Fanminus);

Node my_node;
my_node = RMaker.initNode("Bedroom_3");
//custom fan
Param speed("Speed", ESP_RMAKER_PARAM_RANGE, value(0), PROP_FLAG_READ | PROP_FLAG_WRITE);//change
speed.addBounds(value(0), value(100), value(1));//refer note5
speed.addUIType(ESP_RMAKER_UI_SLIDER);
my_fan.addParam(speed);
//Standard outlet device
my_outlet.addNameParam();
my_outlet.addPowerParam(true);
my_outlet.assignPrimaryParam(my_outlet.getParamByName(ESP_RMAKER_DEF_POWER_NAME));//refer note3
//Standard motion sensor device
motion_sensor.addNameParam();
motion_sensor.addPowerParam(true,"Motion-Detection");
//refer note2
Param Motion_Detection_State("Motion_Detection_State", ESP_RMAKER_PARAM_TOGGLE, value(0), PROP_FLAG_READ);
Motion_Detection_State.addUIType(ESP_RMAKER_UI_TOGGLE);//refer note4
motion_sensor.addParam(Motion_Detection_State);
motion_sensor.assignPrimaryParam(motion_sensor.getParamByName(ESP_RMAKER_DEF_POWER_NAME));
//Standard switch device
my_switch1.addCb(write_callback);
my_switch2.addCb(write_callback);
my_switch3.addCb(write_callback);
my_outlet.addCb(write_callback);
my_fan.addCb(write_callback);
motion_sensor.addCb(write_callback);
//Add switch device to the node
my_node.addDevice(my_switch1);
my_node.addDevice(my_switch2);
my_node.addDevice(my_switch3);
my_node.addDevice(my_outlet);
my_node.addDevice(my_fan);
my_node.addDevice(motion_sensor);
my_node.addDevice(temperature);
my_node.addDevice(humidity);
RMaker.enableOTA(OTA_USING_PARAMS);
RMaker.enableTZService();
RMaker.enableSchedule();

Timer.setInterval(45000);

for(int i=0; i<17; i=i+8) {
chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i;
}
Serial.printf("\nChip ID: %d Service Name: %s\n", chipId, service_name);
Serial.printf("\nStarting ESP-RainMaker\n");
RMaker.start();

WiFi.onEvent(sysProvEvent);
#if CONFIG_IDF_TARGET_ESP32
WiFiProv.beginProvision(WIFI_PROV_SCHEME_BLE, WIFI_PROV_SCHEME_HANDLER_FREE_BTDM, WIFI_PROV_SECURITY_1, pop, service_name);
#else
WiFiProv.beginProvision(WIFI_PROV_SCHEME_SOFTAP, WIFI_PROV_SCHEME_HANDLER_NONE, WIFI_PROV_SECURITY_1, pop, service_name);
#endif

toggleState_1 = pref.getBool("Relay1", 0);
Serial.print("Last State Relay1 - "); Serial.println(toggleState_1);
digitalWrite(RelayPin1, toggleState_1);
my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
delay(200);
toggleState_2 = pref.getBool("Relay2", 0);
Serial.print("Last State Relay2- "); Serial.println(toggleState_2);
digitalWrite(RelayPin2, toggleState_2);
my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
delay(200);
toggleState_3 = pref.getBool("Relay3", 0);
Serial.print("Last State Relay3- "); Serial.println(toggleState_3);
digitalWrite(RelayPin3, toggleState_3);
my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
delay(200);
toggleState_4 = pref.getBool("Relay4", 0);
Serial.print("Last State Relay4- "); Serial.println(toggleState_4);
digitalWrite(RelayPin4, toggleState_4);
my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
delay(200);
FanState = pref.getInt("Fan", 0);
Serial.print("Last State Fan- "); Serial.println(FanState);
if (FanState == 0){
SZERO();
}
else if (FanState == 1){
SONE();
}
else if (FanState == 2){
STWO();
}
else if (FanState == 3){
STHREE();
}
else if (FanState == 4){
SFOUR();
}
else if (FanState == 5){
SFIVE();
}
else{}
delay(200);
my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
my_outlet.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
my_fan.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
motion_sensor.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, false);
}
void loop(){
if(digitalRead(gpio_reset) == LOW) { //Push button pressed
Serial.printf("Reset Button Pressed!\n");
delay(100);
int startTime = millis();
while(digitalRead(gpio_reset) == LOW) delay(50);
int endTime = millis();
if ((endTime - startTime) > 10000) {
Serial.printf("Reset to factory.\n");
RMakerFactoryReset(2);
} else if ((endTime - startTime) > 3000) {
Serial.printf("Reset Wi-Fi.\n");
RMakerWiFiReset(2);
}
}
delay(100);
if (WiFi.status() != WL_CONNECTED){
digitalWrite(wifiLed, false);
}
else{
digitalWrite(wifiLed, true);
if (Timer.isReady()) { // Check is ready a second timer
Serial.println("Sending Sensor's Data");
Send_Sensor();
Timer.reset(); // Reset a second timer
}
}
if (toggleState_8 == 1){
if (digitalRead(pir) == LOW && pir_state == 0){
delay(100);
pir_state = !pir_state;
motion_sensor.updateAndReportParam("Motion_Detection_State", 0);
}
else if (digitalRead(pir) == HIGH && pir_state == 1){
delay(100);
pir_state = !pir_state;
motion_sensor.updateAndReportParam("Motion_Detection_State", 1);
}
}
else{
motion_sensor.updateAndReportParam("Motion_Detection_State", 0);
}
button1.check();
button2.check();
button3.check();
button4.check();
button5.check();
button6.check();
button7.check();
}
void button1Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT1");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin1, toggleState_1);
toggleState_1 = !toggleState_1;
my_switch1.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_1);
break;
}
}
void button2Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT2");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin2, toggleState_2);
toggleState_2 = !toggleState_2;
my_switch2.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_2);
break;
}
}
void button3Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT3");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin3, toggleState_3);
toggleState_3 = !toggleState_3;
my_switch3.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_3);
break;
}
}
void button4Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT4");
switch (eventType) {
case AceButton::kEventReleased:
digitalWrite(RelayPin4, toggleState_4);
toggleState_4 = !toggleState_4;
my_outlet.updateAndReportParam(ESP_RMAKER_DEF_POWER_NAME, toggleState_4);
break;
}
}
void button5Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {
Serial.println("EVENT5");
switch (eventType) {
case AceButton::kEventReleased:
if(toggleState_4 == LOW){
mySwitch.send("10000100010110010011111001000011");
my_fan.updateAndReportParam("Power", 1);
toggleState_5 = !toggleState_5;
}
else if(toggleState_4 == HIGH){
SZERO();
}
break;
}
}
void button6Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {//plus
Serial.println("EVENT6");
switch (eventType) {
case AceButton::kEventReleased:
if(curr_speed == 0);
{
SONE();
}
if(curr_speed == 1);
{
STWO();
}
if(curr_speed == 2);
{
STHREE();
}
if(curr_speed == 3);
{
SFOUR();
}
if(curr_speed == 4);
{
SFIVE();
}
break;
}
}
void button7Handler(AceButton* button, uint8_t eventType, uint8_t buttonState) {//MINUS
Serial.println("EVENT7");
switch (eventType) {
case AceButton::kEventReleased:
if(curr_speed == 1);
{
SZERO();
}
if(curr_speed == 2);
{
SONE();
}
if(curr_speed == 3);
{
STWO();
}
if(curr_speed == 4);
{
STHREE();
}
if(curr_speed == 5);
{
SFOUR();
}
break;
}
}
void Send_Sensor()
{
float h = dht.readHumidity();
float t = dht.readTemperature();
Serial.print("Temperature - "); Serial.println(t);
Serial.print("Humidity - "); Serial.println(h);
temperature.updateAndReportParam("Temperature", t);
humidity.updateAndReportParam("Temperature", h);
}
void SZERO(){
Serial.println("SPEED 0");
curr_speed = 0;
my_fan.updateAndReportParam("Speed", 0);
my_fan.updateAndReportParam("Power", 0);
mySwitch.send("10000100010110010011011001101001");
pref.putInt("Fan", curr_speed);
toggleState_5 = !toggleState_5;
}
void SONE(){
Serial.println("SPEED 1");
curr_speed = 1;
toggleState_5 = HIGH;
my_fan.updateAndReportParam("Speed", 1);
my_fan.updateAndReportParam("Power", 1);
mySwitch.send("10000100010110010011010100001100");
pref.putInt("Fan", curr_speed);
}
void STWO(){
Serial.println("SPEED 2");
curr_speed = 2;
toggleState_5 = HIGH;
my_fan.updateAndReportParam("Speed", 2);
my_fan.updateAndReportParam("Power", 1);
mySwitch.send("10000100010110010011111100110101");
pref.putInt("Fan", curr_speed);
}
void STHREE(){
Serial.println("SPEED 3");
curr_speed = 3;
toggleState_5 = HIGH;
my_fan.updateAndReportParam("Speed", 3);
my_fan.updateAndReportParam("Power", 1);
mySwitch.send("10000100010110010011010001011000");
pref.putInt("Fan", curr_speed);
}
void SFOUR(){
Serial.println("SPEED 4");
curr_speed = 4;
toggleState_5 = HIGH;
my_fan.updateAndReportParam("Speed", 4);
my_fan.updateAndReportParam("Power", 1);
mySwitch.send("10000100010110010011001101101100");
pref.putInt("Fan", curr_speed);
}
void SFIVE(){
Serial.println("SPEED 5");
curr_speed = 5;
toggleState_5 = HIGH;
my_fan.updateAndReportParam("Speed", 5);
my_fan.updateAndReportParam("Power", 1);
mySwitch.send("10000100010110010011001000101001");
pref.putInt("Fan", curr_speed);
}[/Codebox]

This is the code
I am using Arduino IDE and an esp32 development road

ESP_Piyush
Posts: 309
Joined: Wed Feb 20, 2019 7:02 am

Re: how to use standard motion sensor device

Postby ESP_Piyush » Thu Dec 28, 2023 2:43 pm

Please check my comment here for some pointers. Your motion sensor device creation logic seems fine, since it indeed sets the device type to esp.device.motion-sensor, but you can skip the power parameter if the motion sensor does not need any control. The motion detection state parameter, however, should have the esp.param.motion-detection-state type.

Param Motion_Detection_State("Motion_Detection_State", "esp.param.motion-detection-state", value(0), PROP_FLAG_READ);

chris michael
Posts: 3
Joined: Tue Dec 26, 2023 5:42 am

Re: how to use standard motion sensor device

Postby chris michael » Sun Jan 07, 2024 12:40 pm

Thank you
The code seems to be working.

Who is online

Users browsing this forum: No registered users and 92 guests