Mail trigger

Correct. Already installed on RPI

python agent or pi agent?

this:
"wget https://cayenne.mydevices.com/dl/rpi_b8w8pn82i9.sh

sudo bash rpi_b8w8pn82i9.sh -v"

that is the pi agent. you can edit code on cayenne python library.
for what did you use this code?

An older pi running only a custom python2 program, no Cayenne. Just a conceptual example of how ā€œlatch_stateā€ variable is used for hysteresis/one shotting

What is typical path to Cayenne Python library? Itā€™s been awhile for me. Just dug my piā€™s back out yesterday and put one to work to monitor my household freezer.

have a look at this GitHub - myDevicesIoT/Cayenne-MQTT-Python: Python Library for Cayenne MQTT API and there is an example code Example-04-SendDataOnTrigger.py which you need to modify accordingly to send trigger only once.

/*
Cayenne DS18B20 Example

This sketch shows how to send DS18B20 Sensor data to the Cayenne Dashboard.

The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. Install the OneWire library (http://www.pjrc.com/teensy/td_libs_OneWire.html) from the Arduino Library Manager.
2. Install the DallasTemperature library (http://milesburton.com/Main_Page?title=Dallas_Temperature_Control_Library#Code.2FLibrary) from the Arduino Library Manager.
3. Attach a DS18B20 to a digital pin on your Arduino.
   Schematic:
   [Ground] -- [DS18B20] -- [4.7k resistor] -- [5V]
                   |______________|
                   |
              Digital Pin
4. Set the SENSOR_PIN value below to the pin number you used when connecting the sensor.
5. Set the VIRTUAL_CHANNEL value below to a free virtual channel (or the virtual channel of a DS18B20 Sensor widget you have added) in the Dashboard.
6. Set the Cayenne authentication info to match the authentication info from the Dashboard.
7. Compile and upload this sketch.
8. Once the Arduino connects to the Dashboard it should automatically create a temporary display widget (or update the DS18B20 Sensor widget you have added) with data.
   To make a temporary widget permanent click the plus sign on the widget.
*/

#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <OneWire.h>
#include <DallasTemperature.h>
#include <CayenneMQTTEthernet.h>

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "x";
char password[] = "x";
char clientID[] = "x";

#define SENSOR_PIN 2 // Do not use digital pins 0 or 1 since those conflict with the use of Serial.
#define VIRTUAL_CHANNEL 1

OneWire oneWire(SENSOR_PIN);
DallasTemperature sensors(&oneWire);

void setup()
{
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID);
  sensors.begin();
}

void loop()
{
  Cayenne.loop();
}

// This function is called at intervals to send sensor data to Cayenne.
CAYENNE_OUT(VIRTUAL_CHANNEL)
{
  // Send the command to get temperatures.
  sensors.requestTemperatures();
  // This command writes the temperature in Celsius to the Virtual Channel.
  Cayenne.celsiusWrite(VIRTUAL_CHANNEL, sensors.getTempCByIndex(0));
  // To send the temperature in Fahrenheit use the corresponding code below.
  //Cayenne.fahrenheitWrite(VIRTUAL_CHANNEL, sensors.getTempFByIndex(0));
}

and

/*
This example shows how to connect to Cayenne using an Ethernet W5100 shield and send/receive sample data.

The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.

Steps:
1. Set the Cayenne authentication info to match the authentication info from the Dashboard.
2. Compile and upload the sketch.
3. A temporary widget will be automatically generated in the Cayenne Dashboard. To make the widget permanent click the plus sign on the widget.
*/

#define CAYENNE_DEBUG       // Uncomment to show debug messages
#define CAYENNE_PRINT Serial  // Comment this out to disable prints and save space
#include <CayenneMQTTEthernet.h>

//DTH
#include "DHT.h"
DHT dht(2,DHT22); //Definisco il pin al quale ĆØ collegato il sensore e il tipo
DHT dht2(3,DHT22);
//#define DHTPIN 2
//#define DHTTYPE DHT22
//DHT dht(DHTPIN, DHTTYPE);
#define DTH_hum_Virtual_Channel 1
#define DTH_tempC_Virtual_Channel 2
#define DTH_tempF_Virtual_Channel 3
#define DTH_hic_Virtual_Channel 4
#define DTH_hif_Virtual_Channel 5
#define DTH_hum2_Virtual_Channel 6
#define DTH_tempC2_Virtual_Channel 7
#define DTH_tempF2_Virtual_Channel 8
#define DTH_hic2_Virtual_Channel 9
#define DTH_hif2_Virtual_Channel 10
unsigned long lastMillis_dht = 0;

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "x";
char password[] = "x";
char clientID[] = "x";

void setup() {
    //DTH
  dht.begin();
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID);
}

void loop() {
  Cayenne.loop();
  //DTH
  if (millis() - lastMillis_dht > 10000) {
    lastMillis_dht = millis();
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    // Compute heat index in Fahrenheit (the default)
    float hif = dht.computeHeatIndex(f, h);
    // Compute heat index in Celsius (isFahreheit = false)
    float hic = dht.computeHeatIndex(t, h, false);
    Serial.print("Humidity: ");
    Serial.print(h);
    Serial.print(" %\t");
    Serial.print("Temperature: ");
    Serial.print(t);
    Serial.print(" *C ");
    Serial.print(f);
    Serial.print(" *F\t");
    Serial.print("Heat index: ");
    Serial.print(hic);
    Serial.print(" *C ");
    Serial.print(hif);
    Serial.println(" *F");
    Cayenne.virtualWrite(DTH_hum_Virtual_Channel, h, "rel_hum", "p");
    Cayenne.virtualWrite(DTH_tempC_Virtual_Channel, t, "temp", "c");
    //Cayenne.virtualWrite(DTH_tempF_Virtual_Channel, f, "temp", "f");
    //Cayenne.virtualWrite(DTH_hif_Virtual_Channel, hif, "temp", "f");
    //Cayenne.virtualWrite(DTH_hic_Virtual_Channel, hic, "temp", "c");
    lastMillis_dht = millis();
    // Reading temperature or humidity takes about 250 milliseconds!
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h2 = dht2.readHumidity();
    // Read temperature as Celsius (the default)
    float t2 = dht2.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f2 = dht2.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h2) || isnan(t2) || isnan(f2)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    // Compute heat index in Fahrenheit (the default)
    float hif2 = dht2.computeHeatIndex(f2, h2);
    // Compute heat index in Celsius (isFahreheit = false)
    float hic2 = dht2.computeHeatIndex(t2, h2, false);
    Serial.print("Humidity2: ");
    Serial.print(h2);
    Serial.print(" %\t");
    Serial.print("Temperature2: ");
    Serial.print(t2);
    Serial.print(" *C ");
    Serial.print(f2);
    Serial.print(" *F\t");
    Serial.print("Heat index: ");
    Serial.print(hic2);
    Serial.print(" *C ");
    Serial.print(hif2);
    Serial.println(" *F");
    Cayenne.virtualWrite(DTH_hum2_Virtual_Channel, h2, "rel_hum", "p");
    Cayenne.virtualWrite(DTH_tempC2_Virtual_Channel, t2, "temp", "c");
    //Cayenne.virtualWrite(DTH_tempF2_Virtual_Channel, f2, "temp", "f");
    //Cayenne.virtualWrite(DTH_hif2_Virtual_Channel, hif2, "temp", "f");
    //Cayenne.virtualWrite(DTH_hic2_Virtual_Channel, hic2, "temp", "c");
  }
}

Iā€™m not in a hurry, as I said the sensors go and thatā€™s what I need, triggers if there are better but are not essential.
thank you very much

in the below code, you need to set the threshold value and sendBelowTHreshold as true or false.

 /*
  This example is to be used when using Cayenne triggers.
  The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.
  Steps:
  1. Set the trigger and threshold values in the sketch below.
  2. Set the Cayenne authentication info to match the authentication info from the Dashboard.
  3. Compile and upload the sketch.
  4. Two temporary widget (DATA_CHANNEL and TRIGGER_CHANNEL) will be automatically generated in the Cayenne Dashboard. To make the widget permanent click the plus sign on the widget.
  5. Add trigger on your cayenne dashboard for the TRIGGER_CHANNEL widget when it becomes 1.
*/

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTEthernet.h> // Change this to use a different communication device. See Communications examples.

#include <OneWire.h>
#include <DallasTemperature.h>

#define SENSOR_PIN 2

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "MQTT_USERNAME";
char password[] = "MQTT_PASSWORD";
char clientID[] = "CLIENT_ID";

#define DATA_CHANNEL 1 //Virtual channel for publishing sensor data.
#define TRIGGER_CHANNEL 2 //Virtual channel for publishing the trigger value.
#define THRESHOLD 200 //Threshold for the trigger.
bool sendBelowThreshold = true; //Set to true if the trigger should happen when the data value is below the threshold,
//false if it should happen when the data value is above or equal to the threshold.
bool crossedThreshold = false;

OneWire oneWire(SENSOR_PIN);
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID);
  sensors.begin();

}

void sendTriggerValue(int channel, int value, int threshold, bool sendBelowThreshold) {
  if (((value >= threshold) && !sendBelowThreshold) || ((value < threshold) && sendBelowThreshold)) {
    if (!crossedThreshold) {
      Cayenne.virtualWrite(channel, 1, "digital_sensor", "d"); //set trigger two-state widget to 1
      crossedThreshold = true;
    }
  }
  else
  {
    Cayenne.virtualWrite(channel, 0, "digital_sensor", "d"); //set trigger two-state widget to 0
    crossedThreshold = false;
  }
}

void loop() {
  Cayenne.loop();
}

CAYENNE_OUT_DEFAULT()
{
  sensors.requestTemperatures();
  int sensor_value =  sensors.getTempCByIndex(0);
  sendTriggerValue(TRIGGER_CHANNEL, sensor_value, THRESHOLD, sendBelowThreshold);
  Cayenne.virtualWrite(DATA_CHANNEL, sensor_value , "temp", "c"); //widget to display sensor data.
}
1 Like

for DTH code i have added trigger to only one temperature.

/*
  This example is to be used when using Cayenne triggers.
  The CayenneMQTT Library is required to run this sketch. If you have not already done so you can install it from the Arduino IDE Library Manager.
  Steps:
  1. Set the trigger and threshold values in the sketch below.
  2. Set the Cayenne authentication info to match the authentication info from the Dashboard.
  3. Compile and upload the sketch.
  4. Two temporary widget (DATA_CHANNEL and TRIGGER_CHANNEL) will be automatically generated in the Cayenne Dashboard. To make the widget permanent click the plus sign on the widget.
  5. Add trigger on your cayenne dashboard for the TRIGGER_CHANNEL widget when it becomes 1.
*/

//#define CAYENNE_DEBUG
#define CAYENNE_PRINT Serial
#include <CayenneMQTTEthernet.h> // Change this to use a different communication device. See Communications examples.

// Cayenne authentication info. This should be obtained from the Cayenne Dashboard.
char username[] = "MQTT_USERNAME";
char password[] = "MQTT_PASSWORD";
char clientID[] = "CLIENT_ID";

//DTH
#include "DHT.h"
DHT dht(2, DHT22); //Definisco il pin al quale ĆØ collegato il sensore e il tipo
DHT dht2(3, DHT22);

#define DTH_hum_Virtual_Channel 1
#define DTH_tempC_Virtual_Channel 2
#define DTH_tempF_Virtual_Channel 3
#define DTH_hic_Virtual_Channel 4
#define DTH_hif_Virtual_Channel 5
#define DTH_hum2_Virtual_Channel 6
#define DTH_tempC2_Virtual_Channel 7
#define DTH_tempF2_Virtual_Channel 8
#define DTH_hic2_Virtual_Channel 9
#define DTH_hif2_Virtual_Channel 10
unsigned long lastMillis_dht = 0;

#define TRIGGER_CHANNEL 11 //Virtual channel for publishing the trigger value.
#define THRESHOLD 200 //Threshold for the trigger.
bool sendBelowThreshold = true; //Set to true if the trigger should happen when the data value is below the threshold,
//false if it should happen when the data value is above or equal to the threshold.
bool crossedThreshold = false;

void setup() {
  Serial.begin(9600);
  Cayenne.begin(username, password, clientID);
  dht.begin();
}

void sendTriggerValue(int channel, int value, int threshold, bool sendBelowThreshold) {
  if (((value >= threshold) && !sendBelowThreshold) || ((value < threshold) && sendBelowThreshold)) {
    if (!crossedThreshold) {
      Cayenne.virtualWrite(channel, 1, "digital_sensor", "d"); //set trigger two-state widget to 1
      crossedThreshold = true;
    }
  }
  else
  {
    Cayenne.virtualWrite(channel, 0, "digital_sensor", "d"); //set trigger two-state widget to 0
    crossedThreshold = false;
  }
}

void loop() {
  Cayenne.loop();
}

CAYENNE_OUT_DEFAULT()
{
  float h = dht.readHumidity();
  // Read temperature as Celsius (the default)
  int sensor_value = dht.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f = dht.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(sensor_value) || isnan(f)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif = dht.computeHeatIndex(f, h);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(sensor_value, h, false);
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature: ");
  Serial.print(sensor_value);
  Serial.print(" *C ");
  Serial.print(f);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic);
  Serial.print(" *C ");
  Serial.print(hif);
  Serial.println(" *F");
  Cayenne.virtualWrite(DTH_hum_Virtual_Channel, h, "rel_hum", "p");
  Cayenne.virtualWrite(DTH_tempC_Virtual_Channel, sensor_value, "temp", "c");
  //Cayenne.virtualWrite(DTH_tempF_Virtual_Channel, f, "temp", "f");
  //Cayenne.virtualWrite(DTH_hif_Virtual_Channel, hif, "temp", "f");
  //Cayenne.virtualWrite(DTH_hic_Virtual_Channel, hic, "temp", "c");
  lastMillis_dht = millis();
  // Reading temperature or humidity takes about 250 milliseconds!
  // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
  float h2 = dht2.readHumidity();
  // Read temperature as Celsius (the default)
  float t2 = dht2.readTemperature();
  // Read temperature as Fahrenheit (isFahrenheit = true)
  float f2 = dht2.readTemperature(true);

  // Check if any reads failed and exit early (to try again).
  if (isnan(h2) || isnan(t2) || isnan(f2)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }

  // Compute heat index in Fahrenheit (the default)
  float hif2 = dht2.computeHeatIndex(f2, h2);
  // Compute heat index in Celsius (isFahreheit = false)
  float hic2 = dht2.computeHeatIndex(t2, h2, false);
  Serial.print("Humidity2: ");
  Serial.print(h2);
  Serial.print(" %\t");
  Serial.print("Temperature2: ");
  Serial.print(t2);
  Serial.print(" *C ");
  Serial.print(f2);
  Serial.print(" *F\t");
  Serial.print("Heat index: ");
  Serial.print(hic2);
  Serial.print(" *C ");
  Serial.print(hif2);
  Serial.println(" *F");
  Cayenne.virtualWrite(DTH_hum2_Virtual_Channel, h2, "rel_hum", "p");
  Cayenne.virtualWrite(DTH_tempC2_Virtual_Channel, t2, "temp", "c");
  //Cayenne.virtualWrite(DTH_tempF2_Virtual_Channel, f2, "temp", "f");
  //Cayenne.virtualWrite(DTH_hif2_Virtual_Channel, hif2, "temp", "f");
  //Cayenne.virtualWrite(DTH_hic2_Virtual_Channel, hic2, "temp", "c");
  
  sendTriggerValue(TRIGGER_CHANNEL, sensor_value, THRESHOLD, sendBelowThreshold);
}
1 Like

Thank you very much, as soon as I can I try it Iā€™m curious to see the result.

2 Likes

Any fixes for this from a dashboard end yet rather than having to redo device code as a workaround?
Its not always practical to go back into the field to reprogram arduino devices because a dashboard feature doesnā€™t work as it should - its very not helpful at the moment as it is!
Also it doesnā€™t send the Widget name as we have set - only the channel number which is also unhelpful for end users.

Both these issues are on the cayenne roadmap and will be taken in next quater.

A few quarters have passed now. The dashboard fix for the triggers, and device names in the notifications must be about ready?

we wont be adding this feature to cayenne any soon.

1 Like