Join things on single device

Good morning, I have a device that I have recently developed that has an ESP32 on the board and I want to control two relays and a temperature sensor. Separately the codes work and transmit perfectly but I cannot get the two codes together in one code and it works .

I leave attached the codes separately.

Relay code:

#include <Arduino.h>
#include “Thing.h”
#include “WebThingAdapter.h”

// TODO: Hardcode your wifi credentials here (and keep it private)
const char *ssid = “Cr@ck3r”;
const char *password = “Frumusete159753”;

#if defined(LED_BUILTIN)
const int ledPin = LED_BUILTIN;
#else
const int ledPin = 4; // manually configure LED pin
#endif

WebThingAdapter *adapter;

const char *ledTypes[] = {“OnOffSwitch”, “Light”, nullptr};
ThingDevice led(“led”, “Built-in LED”, ledTypes);
ThingProperty ledOn(“on”, “”, BOOLEAN, “OnOffProperty”);

bool lastOn = false;

void setup(void) {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(115200);
Serial.println("");
Serial.print(“Connecting to “”);
Serial.print(ssid);
Serial.println(”"");
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
bool blink = true;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
digitalWrite(ledPin, blink ? LOW : HIGH); // active low led
blink = !blink;
}
digitalWrite(ledPin, LOW); // active low led

Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
adapter = new WebThingAdapter(“w25”, WiFi.localIP());

led.addProperty(&ledOn);
adapter->addDevice(&led);
adapter->begin();
Serial.println(“HTTP server started”);
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(led.id);
}

void loop(void) {
adapter->update();
bool on = ledOn.getValue().boolean;
digitalWrite(ledPin, on ? LOW : HIGH); // active low led
if (on != lastOn) {
Serial.print(led.id);
Serial.print(": ");
Serial.println(on);
}
lastOn = on;
}


Temperature sensor code:

#include “Thing.h”
#include “WebThingAdapter.h”
#include “DHT.h”

const char* ssid = “Cr@ck3r”;
const char* password = “Frumusete159753”;

// minimal change from last sensor reading to
// update our values
const double threshold = 0.1;

WebThingAdapter* adapter;

// MultiLevelSensor and Sensor are mandatory for this type of application.
// See https://iot.mozilla.org/schemas/
const char* deviceTypes[] = {“MultiLevelSensor”, “Sensor”, nullptr};

// Sets up the device info. First two values are free-form.
ThingDevice device(“DHTSensor”, “Temperatura Comedor”, deviceTypes);

// Sets up device properties. Not sure about the second value here. Probably doesn’t make sense.
// Third and fourth argument are not freeform.
ThingProperty temperature(“temperature”, “Input pin”, NUMBER, “LevelProperty”);

// Pin to connect DHT sensor’s data wire (yellow)
const int sensorPin = 4;
DHT dht;
int samplingPeriod = dht.getMinimumSamplingPeriod();

double lastTemperatureValue = 0;

void setup(void) {
Serial.begin(115200);
Serial.println("");

dht.setup(sensorPin);
Serial.print("Sensor model: ");
Serial.println(dht.getModel());

Serial.print(“Connecting to “”);
Serial.print(ssid);
Serial.println(”"");
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
bool blink = true;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}

Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

// Here ‘Comedor’ becomes part of the hostname => Comedor.local
// so make sure it’s unique in your network.
adapter = new WebThingAdapter(“Comedor”, WiFi.localIP());

device.addProperty(&temperature);
adapter->addDevice(&device);

Serial.println(“Starting HTTP server”);
adapter->begin();
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(device.id);
}

// The loop function makes sure we get up-to-date values.
void loop(void) {

delay(samplingPeriod);

float temperatureVal = dht.getTemperature();
double temperatureValDouble = (double) temperatureVal;
if (abs(temperatureValDouble - lastTemperatureValue) >= threshold) {
Serial.print("log: Temperature: ");
Serial.print(temperatureValDouble);
Serial.println(“°C”);
ThingPropertyValue temperatureLevelValue;
temperatureLevelValue.number = temperatureValDouble;
temperature.setValue(temperatureLevelValue);
lastTemperatureValue = temperatureValDouble;
}
adapter->update();
}

I have tried it in various ways but there is no way I can get to control the two relays separately and display the temperature on the same device. Besides, on the platform it only shows me 1 On / Off device or temperature, but not both at the same time.

Can someone help me please, because I don’t want to use 1 device for relays and 1 for temperature.

Thank you so much everyone.

You may want to look at this very similar question.

Essentially, you’ll create two separate ThingDevice instances and add both to the same adapter, then update both in your loop() function.

I fired everything up and started to add the first one by URL
when both showed up. I played around with them in the Gateway for
a while then they disconnected. It seems like there might be a
problem with that particular 8266 that I couldn’t get it working
yesterday .

  A question if I might - is setting of moistureLevel.unit

required? I’m using some capacitive moisture sensors that give me
a range of about 300 - 900. Can I just moistureLevel.unit = “”;
Or is there a better way

  Within the Gateway rules - is the only use of the time of day for

equality? Is greater or less than possible?

Thank you for your help

RW Paar

The unit is not required. You can see what’s required for each property type here.

For the rule, you’ll want to install the “DateTime” add-on, then add the DateTime device to your gateway. Using that device’s properties, you can create the rules you want.

This is my first add-on, I installed the add-on but I’m not sure
how to add the DateTime device to the Gateway

According to the post that you have indicated, my very basic notions of programming and the hours that I have tried to make this work, I have not managed to make it work :frowning:

I leave attached the code that I have tried.

Code:

#include <Arduino.h>
#include “Thing.h”
#include “WebThingAdapter.h”
#include “DHT.h”

// TODO: Hardcode your wifi credentials here (and keep it private)
const char ssid = "******";
const char *password = “********”;

// minimal change from last sensor reading to
// update our values
const double threshold = 0.1;

#if defined(LED_BUILTIN)
const int ledPin = LED_BUILTIN;
#else
const int ledPin = 4; // manually configure LED pin
const int ledPin = 2; // manually configure LED pin
#endif

WebThingAdapter* adapter;

// MultiLevelSensor and Sensor are mandatory for this type of application.
const char* deviceTypes[] = {“MultiLevelSensor”, “Sensor”, nullptr};

const char *ledTypes[] = {“OnOffSwitch”, “Light”, nullptr};
ThingDevice led(“led”, “Built-in LED”, ledTypes);
ThingProperty ledOn(“on”, “”, BOOLEAN, “OnOffProperty”);

bool lastOn = false;

// Sets up the device info. First two values are free-form.
ThingDevice device(“DHTSensor”, “temperature”, deviceTypes);

// Sets up device properties.
ThingProperty temperature(“temperature”, “Input pin”, NUMBER, “LevelProperty”);

// Pin to connect DHT sensor’s data wire (yellow)
const int sensorPin = 12;
DHT dht;
int samplingPeriod = dht.getMinimumSamplingPeriod();

double lastTemperatureValue = 0;

void setup(void) {
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
Serial.begin(115200);
Serial.println("");
Serial.print(“Connecting to “”);
Serial.print(ssid);
Serial.println(”"");
#if defined(ESP8266) || defined(ESP32)
WiFi.mode(WIFI_STA);
#endif
WiFi.begin(ssid, password);
Serial.println("");

// Wait for connection
bool blink = true;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
digitalWrite(ledPin, blink ? LOW : HIGH); // active low led
blink = !blink;
}
digitalWrite(ledPin, LOW); // active low led

Serial.println("");
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
adapter = new WebThingAdapter(“w25”, WiFi.localIP());

led.addProperty(&ledOn);
adapter->addDevice(&led);
adapter->begin();
Serial.println(“HTTP server started”);
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(led.id);
}

// Here ‘Comedor’ becomes part of the hostname => Comedor.local
// so make sure it’s unique in your network.
adapter = new WebThingAdapter(“Comedor”, WiFi.localIP());

device.addProperty(&temperature);
adapter->addDevice(&device);

Serial.println(“Starting HTTP server”);
adapter->begin();
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.print("/things/");
Serial.println(device.id);
}

// The loop function makes sure we get up-to-date values.
void loop(void) {

delay(samplingPeriod);

float temperatureVal = dht.getTemperature();
double temperatureValDouble = (double) temperatureVal;
if (abs(temperatureValDouble - lastTemperatureValue) >= threshold) {
Serial.print("log: Temperature: ");
Serial.print(temperatureValDouble);
Serial.println(“°C”);
ThingPropertyValue temperatureLevelValue;
temperatureLevelValue.number = temperatureValDouble;
temperature.setValue(temperatureLevelValue);
lastTemperatureValue = temperatureValDouble;
}
adapter->update();
}

adapter->update();
bool on = ledOn.getValue().boolean;
digitalWrite(ledPin, on ? LOW : HIGH); // active low led
if (on != lastOn) {
Serial.print(led.id);
Serial.print(": ");
Serial.println(on);
}
lastOn = on;
}

It marks errors in all the code, if I remove a function it marks another error and so on.

I don´t know what am i doing wrong, can you please make me understand?

Thank you very much.

On the main Things page, you’ll want to press the + button in the lower right corner, then add the DateTime device.

I’m guessing you copied/pasted from that post. Discourse replaces straight quotes ("") with their curly versions (“”). You’ll need to replace those in your code.

After replacing the quotes as you have recommended it gives me this error:

Error:

Mozilla_2_Reles_y_Temp:82:20: error: ‘things’ was not declared in this scope

Serial.print(”/things/”);

                ^

Mozilla_2_Reles_y_Temp:82:30: error: expected primary-expression before ‘)’ token

Serial.print(”/things/”);

                          ^

C:\Users\ioans\Documents\Arduino\Mozilla_2_Reles_y_Temp\Mozilla_2_Reles_y_Temp.ino: At global scope:

Mozilla_2_Reles_y_Temp:88:1: error: ‘adapter’ does not name a type

adapter = new WebThingAdapter(”Comedor”, WiFi.localIP());

Mozilla_2_Reles_y_Temp:90:1: error: ‘device’ does not name a type

device.addProperty(&temperature);

Mozilla_2_Reles_y_Temp:91:1: error: ‘adapter’ does not name a type

adapter->addDevice(&device);

Mozilla_2_Reles_y_Temp:93:1: error: ‘Serial’ does not name a type

Serial.println(”Starting HTTP server”);

Mozilla_2_Reles_y_Temp:94:1: error: ‘adapter’ does not name a type

adapter->begin();

Mozilla_2_Reles_y_Temp:95:1: error: ‘Serial’ does not name a type

Serial.print(”http://”);

Mozilla_2_Reles_y_Temp:97:1: error: ‘Serial’ does not name a type

Serial.print(”/things/”);

Mozilla_2_Reles_y_Temp:98:1: error: ‘Serial’ does not name a type

Serial.println(device.id);

Mozilla_2_Reles_y_Temp:99:1: error: expected declaration before ‘}’ token

}

What can this be about? :frowning:

When you’re posting code and logs to Discourse, can you please wrap them in triple-backticks, like this? That will prevent the quoting issue.

Please post all of your code inside backticks and I’ll take a look.

I am so sorry that i don´t understand what you are trying to say with the “backticks” but i will paste the code that i have right now and it´s not working.

Code:

#include <Arduino.h>
#include “Thing.h”
#include “WebThingAdapter.h”
#include “DHT.h”

const char* ssid = “Cr@ck3r”;
const char* password = “Frumusete159753”;

// minimal change from last sensor reading to
// update our values
const double threshold = 0.1;

const int Rele1 = 2;
const int Rele2 = 4;
// Pin to connect DHT sensor’s data wire (yellow)
const int sensorPin = 14;
DHT dht;
int samplingPeriod = dht.getMinimumSamplingPeriod();

double lastTemperatureValue = 0;

WebThingAdapter *adapter = NULL;

const char* deviceTypes[] = {“MultiLevelSensor”, “Sensor”, nullptr};
ThingDevice device(“DHTSensor”, “Temperatura Comedor”, deviceTypes);
ThingProperty temperature(“temperature”, “Input pin”, NUMBER, “LevelProperty”);

const char *switchDeviceTypes[] = {“OnOffSwitch”, nullptr};
ThingDevice OnOffSwitch(“device:esp32:Rele1”, “Rele1”, switchDeviceTypes);
ThingDevice OnOffSwitch(“device:esp32:Rele2”, “Rele2”, switchDeviceTypes);
ThingProperty Rele1On(“Rele1On”, “Rele1”, BOOLEAN, “OnOffProperty”);
ThingProperty Rele2On(“Rele2On”, “Rele2”, BOOLEAN, “OnOffProperty”);

void setup(void) {
pinMode(Rele1, OUTPUT);
pinMode(Rele2, OUTPUT);
digitalWrite(Rele1, LOW);
digitalWrite(Rele2, LOW);
Serial.begin(115200);

// Connect to WiFi access point
Serial.print(“Connecting to “);
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while ( WiFi.status() != WL_CONNECTED ) {
delay(500);
Serial.print(”.”);
}

// Show connection details
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("IP address: “);
Serial.println(WiFi.localIP());
Serial.println(” ");

// Start HTTP server
adapter->begin();
Serial.println(“HTTP server started”);
Serial.print(“http://”);
Serial.print(WiFi.localIP());
Serial.println(device.id);

// set initial values
device.addProperty(&temperature);
adapter->addDevice(&device);

//sensor type
dht.setup(sensorPin);
Serial.print("Sensor model: ");
Serial.println(dht.getModel());
}

void loop(void) {

delay(samplingPeriod);

float temperatureVal = dht.getTemperature();
double temperatureValDouble = (double) temperatureVal;
if (abs(temperatureValDouble - lastTemperatureValue) >= threshold) {
Serial.print("log: Temperature: ");
Serial.print(temperatureValDouble);
Serial.println(“°C”);
ThingPropertyValue temperatureLevelValue;
temperatureLevelValue.number = temperatureValDouble;
temperature.setValue(temperatureLevelValue);
lastTemperatureValue = temperatureValDouble;
}
adapter->update();
}

Sorry for my bad english too :frowning:

Is the DateTime device something that I have to purchase?
download?

Here’s a screencast to show you what to do: https://send.firefox.com/download/f9badcf0623a2d18/#PDqsiaqZtBsUPz44EyuUkA

Note the long pause after adding the add-on… It takes some time for the add-on’s dependencies to be installed in the background, so just wait a few minutes at that point.

Followed the steps in the video - when I added the device on
Things by URL, it said ‘Loading’ but never got past that point - I
let it run for about an hour before cancelling.

Another question - how do you delete a floor plan?

The loading stage only actually lasts for about 30 seconds before it times out. Just try again. You probably didn’t wait long enough after installing the add-on.

You can’t delete a floorplan, but you can upload a new one.

Floor plan deletion sounds like something that should be on the
feature request list

  Would there be any adverse setup implications if I were to start

all over with a new copy of the gateway software? I haven’t made
that much progress with the current copy

No, you shouldn’t have any issues. If you want to reuse the subdomain you set up, just make sure you enter the same email address you did the first time.

@Crack3r This should work:

#define LARGE_JSON_BUFFERS 1

#include <Arduino.h>
#include "Thing.h"
#include "WebThingAdapter.h"
#include "DHT.h"

const char* ssid = "XXXXX";
const char* password = "XXXXX";

// minimal change from last sensor reading to
// update our values
const double threshold = 0.1;

const int Rele1 = 2;
const int Rele2 = 4;
// Pin to connect DHT sensor’s data wire (yellow)
const int sensorPin = 14;
DHT dht;
int samplingPeriod = dht.getMinimumSamplingPeriod();

double lastTemperatureValue = 0;

WebThingAdapter *adapter = NULL;

const char* sensorDeviceTypes[] = {"MultiLevelSensor", "Sensor", nullptr};
ThingDevice sensor("device:esp32:DHTSensor", "Temperatura Comedor", sensorDeviceTypes);
ThingProperty temperature("temperature", "Input pin", NUMBER, "LevelProperty");

const char *switchDeviceTypes[] = {"OnOffSwitch", nullptr};
ThingDevice switch1("device:esp32:Rele1", "Rele1", switchDeviceTypes);
ThingProperty rele1On("Rele1On", "Rele1", BOOLEAN, "OnOffProperty");
ThingDevice switch2("device:esp32:Rele2", "Rele2", switchDeviceTypes);
ThingProperty rele2On("Rele2On", "Rele2", BOOLEAN, "OnOffProperty");

void setup(void) {
    pinMode(Rele1, OUTPUT);
    pinMode(Rele2, OUTPUT);
    digitalWrite(Rele1, LOW);
    digitalWrite(Rele2, LOW);
    Serial.begin(115200);

    //sensor type
    dht.setup(sensorPin);
    Serial.print("Sensor model: ");
    Serial.println(dht.getModel());

    // Connect to WiFi access point
    Serial.print("Connecting to ");
    Serial.println(ssid);
    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    while ( WiFi.status() != WL_CONNECTED ) {
        delay(500);
        Serial.print(".");
    }

    // Show connection details
    Serial.print("Connected to ");
    Serial.println(ssid);
    Serial.print("IP address: ");
    Serial.println(WiFi.localIP());
    Serial.println(" ");

    // create adapter instance
    adapter = new WebThingAdapter("esp32", WiFi.localIP());

    // set up devices and properties
    temperature.title = "Temperatura";
    temperature.minimum = dht.getLowerBoundTemperature();
    temperature.maximum = dht.getUpperBoundTemperature();
    temperature.multipleOf = dht.getNumberOfDecimalsTemperature() == 1 ? 0.1 : 1;
    temperature.unit = "degree celsius";
    temperature.readOnly = true;
    sensor.addProperty(&temperature);
    adapter->addDevice(&sensor);

    rele1On.title = "Rele1 On";
    switch1.addProperty(&rele1On);
    adapter->addDevice(&switch1);

    rele2On.title = "Rele2 On";
    switch2.addProperty(&rele2On);
    adapter->addDevice(&switch2);

    // Start HTTP server
    adapter->begin();
    Serial.println("HTTP server started");
    Serial.print("http://");
    Serial.print(WiFi.localIP());
}

void loop(void) {
    delay(samplingPeriod);

    // check relay values
    bool on1 = rele1On.getValue().boolean;
    digitalWrite(Rele1, on1 ? HIGH : LOW);
    bool on2 = rele2On.getValue().boolean;
    digitalWrite(Rele2, on2 ? HIGH : LOW);

    // update temperature value
    float temperatureVal = dht.getTemperature();
    double temperatureValDouble = (double) temperatureVal;
    if (abs(temperatureValDouble - lastTemperatureValue) >= threshold) {
        Serial.print("log: Temperature: ");
        Serial.print(temperatureValDouble);
        Serial.println("°C");
        ThingPropertyValue temperatureLevelValue;
        temperatureLevelValue.number = temperatureValDouble;
        temperature.setValue(temperatureLevelValue);
        lastTemperatureValue = temperatureValDouble;
    }

    adapter->update();
}

Thank you very much mrstegeman, it works perfectly and from the first attempt. I have also seen that now the temperature sensor shows decimals that it did not before.

Now that I have seen the code I understand better how it works.

Thank you very much for the code and for the lesson, you are the best.

Added and configured the DateTime add-on yesterday. Adding the
DateTime thing gives me a 400.