@jodyalbritton Everything looks correct, taking your suggestions into account. The Arduino section is looking good and outputs great over Serial, but for some reason, the ST device type part isn’t working. Still seeing the ‘–’ where temperatures and humidities should be. Is there somewhere I can add log messages of what the is seeing?
I’ll enclose my code below, should you notice something.:
metadata {
// Automatically generated. Make future change here.
definition (name: "Christoph Multi Thermometers", namespace: "scordinskyc", author: "Christopher Scordinsky") {
capability "Refresh"
capability "Polling"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Sensor"
fingerprint profileId: "0104", deviceId: "0138", inClusters: "0000"
}
// Simulator metadata
simulator {
// status messages
status "ping": "catchall: 0104 0000 01 01 0040 00 6A67 00 00 0000 0A 00 0A70696E67"
status "hello": "catchall: 0104 0000 01 01 0040 00 0A21 00 00 0000 0A 00 0A48656c6c6f20576f726c6421"
}
// UI tile definitions
tiles {
valueTile("tempOven", "device.tempOven", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("tempBroiler", "device.tempBroiler", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("tempFridge", "device.tempFridge", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("tempFreezer", "device.tempFreezer", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("tempOthercrisp", "device.tempOthercrisp", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("tempMoistcrisp", "device.tempMoistcrisp", width: 1, height: 1, inactiveLabel: false) {
state("temperature", label: '${currentValue}°F', unit:"F", backgroundColors: [
[value: 31, color: "#153591"],
[value: 44, color: "#1e9cbb"],
[value: 59, color: "#90d2a7"],
[value: 74, color: "#44b621"],
[value: 84, color: "#f1d801"],
[value: 95, color: "#d04e00"],
[value: 96, color: "#bc2323"]
]
)
}
valueTile("humidityFridge", "device.humidityFridge", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("humidityFreezer", "device.humidityFreezer", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("humidityMoistcrisp", "device.humidityMoistcrisp", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
valueTile("humidityOthercrisp", "device.humidityOthercrisp", width: 1, height: 1, inactiveLabel: false) {
state "humidity", label:'${currentValue}% humidity', unit:""
}
standardTile("refresh", "device.poll") {
state "default", label:'', action:"device.poll()", icon:"st.secondary.refresh"
}
main (["tempOven", "tempBroiler", "tempFridge", "tempFreezer","tempMoistcrisp", "tempOthercrisp","humidityFridge", "humidityFreezer", "humidityMoistcrisp", "humidityOthercrisp"])
details(["tempOven", "tempBroiler", "tempFridge", "tempFreezer","tempMoistcrisp", "tempOthercrisp","humidityFridge", "humidityFreezer", "humidityMoistcrisp", "humidityOthercrisp"])
}
}
Map parse(String description) {
def value = zigbee.parse(description)?.text
// Not super interested in ping, can we just move on?
if (value == "ping" || value == " ")
{
return
}
def linkText = getLinkText(device)
def descriptionText = getDescriptionText(description, linkText, value)
def handlerName = value
def isStateChange = value != "ping"
def displayed = value && isStateChange
def result = [
value: value,
handlerName: handlerName,
linkText: linkText,
descriptionText: descriptionText,
isStateChange: isStateChange,
displayed: displayed
]
if (value in ["!on","!off"])
{
result.name = "switch"
result.value = value[1..-1]
// } else if (value && value[0] == "%") {
// result.name = "level"
// result.value = value[1..-1]
} else if (value && value[0] == "humidityFridge") {
result.name = "humidityFridge";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityFreezer") {
result.name = "humidityFreezer";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityOthercrisp") {
result.name = "humidityOthercrisp";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "humidityMoistcrisp") {
result.name = "humidityMoistcrisp";
result.value = value[1..-1];
result.unit = "%"
} else if (value && value[0] == "tempOven") {
result.name = "tempOven";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempBroiler") {
result.name = "tempBroiler";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempFridge") {
result.name = "tempFridge";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempFreezer") {
result.name = "tempFreezer";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempOthercrisp") {
result.name = "tempOthercrisp";
result.value = value[1..-1];
result.unit = "C"
} else if (value && value[0] == "tempMoistcrisp") {
result.name = "tempMoistcrisp";
result.value = value[1..-1];
result.unit = "C"
} else {
result.name = null;
}
// if ( (value && value[0] == "%") )
// {
// result.unit = "%"
// }
createEvent(name: result.name, value: result.value)
}
def poll() {
zigbee.smartShield(text: "poll").format()
}
And the Arduino:
//*****************************************************************************
/// @file
/// @brief
/// Arduino SmartThings Shield Kitchen temp probes
/// @note
/// ______________
/// | |
/// | SW[] |
/// |[]RST |
/// | AREF |--
/// | GND |--
/// | 13 |--X Othercrisp DHT
/// | 12 |--X Moistcrisp DHT
/// | 11 |--X Fridge DHT
/// --| 3.3V 10 |--X Freezer DHT
/// --| 5V 9 |--
/// --| GND 8 |--
/// --| GND |
/// --| Vin 7 |--X CLK
/// | 6 |--X CS
/// --| A0 5 |--X DO for Broiler
/// --| A1 ( ) 4 |--X DO for Oven
/// --| A2 3 |--X THING_RX
/// --| A3 ____ 2 |--X THING_TX
/// --| A4 | | 1 |--
/// --| A5 | | 0 |--
/// |____| |____|
/// |____|
///
//*****************************************************************************
#include //TODO need to set due to some weird wire language linker, should we absorb this whole library into smartthings
#include
#include
//thermocouple additions
#include "SPI.h"
#include "Adafruit_MAX31855.h"
//*****************************************************************************
// Pin Definitions | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
//For the Yun, have to reassign RX pin
#define PIN_THING_RX 8
#define PIN_THING_TX 2
#define DHT_FREEZER_PIN 10
#define DHT_FRIDGE_PIN 11
#define DHT_MOISTCRISP_PIN 12
#define DHT_OTHERCRISP_PIN 13
#define DHTTYPE DHT22
//tcouple additions
#define DO_oven 4
#define DO_broiler 5
#define CS 6
#define CLK 7
DHT dhtFreezer(DHT_FREEZER_PIN, DHTTYPE);
DHT dhtFridge(DHT_FRIDGE_PIN, DHTTYPE);
DHT dhtMoistcrisp(DHT_MOISTCRISP_PIN, DHTTYPE);
DHT dhtOthercrisp(DHT_OTHERCRISP_PIN, DHTTYPE);
//tcouple additions
Adafruit_MAX31855 thermocouple_oven(CLK, CS, DO_oven);
Adafruit_MAX31855 thermocouple_broiler(CLK, CS, DO_broiler);
//*****************************************************************************
// Global Variables | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
SmartThingsCallout_t messageCallout; // call out function forward decalaration
SmartThings smartthing(PIN_THING_RX, PIN_THING_TX, messageCallout); // constructor
bool isDebugEnabled; // enable or disable debug in this example
int stateLED; // state to track last set value of LED
int stateNetwork; // state of the network
//*****************************************************************************
// Local Functions | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
void on()
{
stateLED = 1; // save state as 1 (on)
smartthing.shieldSetLED(0, 0, 2);
smartthing.send("on"); // send message to cloud
}
//*****************************************************************************
void off()
{
stateLED = 0; // set state to 0 (off)
smartthing.shieldSetLED(0, 0, 0);
smartthing.send("off"); // send message to cloud
}
//*****************************************************************************
void setNetworkStateLED()
{
SmartThingsNetworkState_t tempState = smartthing.shieldGetLastNetworkState();
if (tempState != stateNetwork)
{
switch (tempState)
{
case STATE_NO_NETWORK:
if (isDebugEnabled) Serial.println("NO_NETWORK");
smartthing.shieldSetLED(2, 0, 0); // red
break;
case STATE_JOINING:
if (isDebugEnabled) Serial.println("JOINING");
smartthing.shieldSetLED(2, 0, 0); // red
break;
case STATE_JOINED:
if (isDebugEnabled) Serial.println("JOINED");
smartthing.shieldSetLED(0, 0, 0); // off
break;
case STATE_JOINED_NOPARENT:
if (isDebugEnabled) Serial.println("JOINED_NOPARENT");
smartthing.shieldSetLED(2, 0, 2); // purple
break;
case STATE_LEAVING:
if (isDebugEnabled) Serial.println("LEAVING");
smartthing.shieldSetLED(2, 0, 0); // red
break;
default:
case STATE_UNKNOWN:
if (isDebugEnabled) Serial.println("UNKNOWN");
smartthing.shieldSetLED(0, 2, 0); // green
break;
}
stateNetwork = tempState;
}
}
//*****************************************************************************
// API Functions | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
// V V V V V V V V V V V V V V V V V V V V V V V V V V V V V V
//*****************************************************************************
void setup()
{
// setup default state of global variables
isDebugEnabled = true;
stateLED = 0; // matches state of hardware pin set below
stateNetwork = STATE_JOINED; // set to joined to keep state off if off
//DHT 11
// setup hardware pins
dhtFreezer.begin();
dhtFridge.begin();
dhtMoistcrisp.begin();
dhtOthercrisp.begin();
if (isDebugEnabled)
{ // setup debug serial port
Serial.begin(9600); // setup serial with a baud rate of 9600
Serial.println("setup.."); // print out 'setup..' on start
////give the sensor some time to calibrate
//Serial.print("calibrating sensor ");
//for (int i = 0; i < calibrationTime; i++){
// Serial.print(".");
// delay(1000);
//}
//Serial.println(" done");
//Serial.println("SENSOR ACTIVE");
delay(50);
}
}
//*****************************************************************************
// Keep Track of Sensor Readings
//int currentLight;
int currentFridgeHumidity;
int currentFreezerHumidity;
int currentMoistcrispHumidity;
int currentOthercrispHumidity;
int currentOvenTemperature;
int currentBroilerTemperature;
int currentFridgeTemperature;
int currentFreezerTemperature;
int currentMoistcrispTemperature;
int currentOthercrispTemperature;
// Intervals
unsigned long humidityInterval = (25 * 1000);
unsigned long temperatureInterval = (25 * 1000);
unsigned long reportInterval = (2 * 60 * 1000);
unsigned long lastHumidityCheckAt = 0;
unsigned long lastTempCheckAt = 0;
unsigned long lastReportAt = 0;
void loop()
{
// run smartthing logic
smartthing.run();
// Timing code
unsigned long currentMillis = millis();
// First and at checkInterval
if (currentMillis - lastHumidityCheckAt > humidityInterval || lastHumidityCheckAt == 0)
{
lastHumidityCheckAt = currentMillis;
// Do a check
checkHumidity();
}
if (currentMillis - lastTempCheckAt > temperatureInterval || lastTempCheckAt == 0)
{
lastTempCheckAt = currentMillis;
// Do a check
checkTemperature();
}
// First and at reportInterval
if (currentMillis - lastReportAt > reportInterval || lastReportAt == 0)
{
lastReportAt = currentMillis;
// Do a report
reportData();
}
setNetworkStateLED();
}
void checkData()
{
checkHumidity();
checkTemperature();
}
void checkHumidity()
{
Serial.println("Checking humidity...");
// Read humidity
float hFreezer = dhtFreezer.readHumidity();
float hFridge = dhtFridge.readHumidity();
float hMoistcrisp = dhtMoistcrisp.readHumidity();
float hOthercrisp = dhtOthercrisp.readHumidity();
// Discard any data that is NaN
if (isnan(hFreezer) || isnan(hFridge) || isnan(hMoistcrisp) || isnan(hOthercrisp))
{
Serial.println("Failed to read from one or more of the DHTs");
}
else {
Serial.print("Fridge Humidity:");
Serial.println(hFridge);
currentFridgeHumidity = hFridge;
Serial.print("Freezer Humidity:");
Serial.println(hFreezer);
currentFreezerHumidity = hFreezer;
Serial.print("Moist Crisper Humidity:");
Serial.println(hMoistcrisp);
currentMoistcrispHumidity = hMoistcrisp;
Serial.print("Other Crisper Humidity:");
Serial.println(hOthercrisp);
currentOthercrispHumidity = hOthercrisp;
}
}
void checkTemperature()
{
Serial.println("Checking temperature...");
// Read temperature
//Tcouples first
double cOven = thermocouple_oven.readCelsius();
double cBroiler = thermocouple_broiler.readCelsius();
if (isnan(cOven) || isnan(cBroiler)){
Serial.println("Error with Tcouple(s)");
}
else {
Serial.print("Tcouple Oven Temp:");
Serial.println(cOven);
currentOvenTemperature = cOven;
Serial.print("Tcouple Broiler Temp:");
Serial.println(cBroiler);
currentBroilerTemperature = cBroiler;
}
//DHTs next
float tFreezer = dhtFreezer.readTemperature(true);
float tFridge = dhtFridge.readTemperature(true);
float tMoistcrisp = dhtMoistcrisp.readTemperature(true);
float tOthercrisp = dhtOthercrisp.readTemperature(true);
// Discard any data that is NaN
if (isnan(tFreezer) || isnan(tFridge) || isnan(tMoistcrisp) || isnan(tOthercrisp))
{
Serial.println("Failed to read from one or more of the DHTs");
}
else {
Serial.print("Fridge Temp:");
Serial.println(tFridge);
currentFridgeTemperature = tFridge;
Serial.print("Freezer Temp:");
Serial.println(tFreezer);
currentFreezerTemperature = tFreezer;
Serial.print("Moist Crisper Temp:");
Serial.println(tMoistcrisp);
currentMoistcrispTemperature = tMoistcrisp;
Serial.print("Other Crisper Temp:");
Serial.println(tOthercrisp);
currentOthercrispTemperature = tOthercrisp;
}
}
void reportData()
{
Serial.println("Reporting data...");
// We must insist on actually having some data to send
if (isnan(currentFridgeHumidity) || isnan(currentFridgeTemperature)) {
Serial.println("We're not in a loop are we?");
checkData();
reportData();
return;
}
// Report humidity
String humidityFridgeMessage = "humidityFridge";
humidityFridgeMessage.concat(currentFridgeHumidity);
smartthing.send(humidityFridgeMessage);
Serial.println(humidityFridgeMessage);
String humidityFreezerMessage = "humidityFreezer";
humidityFreezerMessage.concat(currentFreezerHumidity);
smartthing.send(humidityFreezerMessage);
Serial.println(humidityFreezerMessage);
String humidityOthercrispMessage = "humidityOthercrisp";
humidityOthercrispMessage.concat(currentOthercrispHumidity);
smartthing.send(humidityOthercrispMessage);
Serial.println(humidityOthercrispMessage);
String humidityMoistcrispMessage = "humidityMoistcrisp";
humidityMoistcrispMessage.concat(currentMoistcrispHumidity);
smartthing.send(humidityMoistcrispMessage);
Serial.println(humidityMoistcrispMessage);
// Report Temps
String tempOvenMessage = "tempOven";
tempOvenMessage.concat(currentOvenTemperature);
smartthing.send(tempOvenMessage);
String tempBroilerMessage = "tempBroiler";
tempBroilerMessage.concat(currentBroilerTemperature);
smartthing.send(tempBroilerMessage);
String tempFridgeMessage = "tempFridge";
tempFridgeMessage.concat(currentFridgeTemperature);
smartthing.send(tempFridgeMessage);
String tempFreezerMessage = "tempFreezer";
tempFreezerMessage.concat(currentFreezerTemperature);
smartthing.send(tempFreezerMessage);
String tempOthercrispMessage = "tempOthercrisp";
tempOthercrispMessage.concat(currentOthercrispTemperature);
smartthing.send(tempOthercrispMessage);
String tempMoistcrispMessage = "tempMoistcrisp";
tempMoistcrispMessage.concat(currentMoistcrispTemperature);
smartthing.send(tempMoistcrispMessage);
}
//*****************************************************************************
void messageCallout(String message)
{
// if debug is enabled print out the received message
if (isDebugEnabled)
{
Serial.print("Received message: '");
Serial.print(message);
Serial.println("' ");
}
// if message contents equals to 'on' then call on() function
// else if message contents equals to 'off' then call off() function
if (message.equals("on"))
{
on();
}
else if (message.equals("off"))
{
off();
}
else if (message.equals("poll"))
{
reportData();
}
}