Complex DIY Hubduino project for automating Front Door is complete, debugged and integrated
with HE. This custom controller will replace Door Sensor, 2 Dry Contact Relays, RGB LED Strip
Controller and will add NFC RFID Card Reader support. Smart Phone with NFC (basically any
modern phone) can be used as RFID Tag.
@ogiewon
I still need couple minor improvements (these are not a show stoppers).
- In the Child RGB Driver "Set Color" button is not doing anything. It will be nice to have it
working. I will try to fix it myself but I am not a SW guru and may not find a solution.
- Since I am not a SW guru all RFID reader related code simple added at the end of the
void loop(). Everything is working just fine but I am sure, it must be better way to add
new features to the Hubduino.
So, only if you have few spare minutes could you help me with these two issues?
Here is a final (I think) sketch code:
//******************************************************************************************
//
// File: ST_Anything_Relays_ESP8266.ino
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//
// Summary: This Arduino Sketch, along with the ST_Anything library and the revised SmartThings
// library, demonstrates the ability of one NodeMCU ESP8266 to
// implement a multi input/output custom device for integration into SmartThings.
//
// The ST_Anything library takes care of all of the work to schedule device updates
// as well as all communications with the NodeMCU ESP8266’s WiFi.
//
// ST_Anything_Relays_ESP8266 implements the following ST Capabilities as a demo of what is possible with a single NodeMCU ESP8266
// - 3 x Relay Switch devices
//
//
// Change History:
//
// Date Who What
// ---- --- ----
// 2015-01-03 Dan & Daniel Original Creation
// 2017-02-12 Dan Ogorchock Revised to use the new SMartThings v2.0 library
// 2017-04-17 Dan Ogorchock New example showing use of Multiple device of same ST Capability
// used with new Parent/Child Device Handlers (i.e. Composite DH)
// 2017-05-25 Dan Ogorchock Revised example sketch, taking into account limitations of NodeMCU GPIO pins
// 2017-11-27 Kai Lenk Modified to 3 relaySwitch
// 2017-11-29 Dan Ogorchock Revisions to make sure works for Kai Lenk
// 2018-02-09 Dan Ogorchock Added support for Hubitat Elevation Hub
//
//******************************************************************************************
//******************************************************************************************
// SmartThings Library for ESP32WiFi
//******************************************************************************************
#include <SmartThingsESP32WiFi.h>
//******************************************************************************************
// ST_Anything Library
//******************************************************************************************
#include <Constants.h> //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h> //Generic Device Class, inherited by Sensor and Executor classes
#include <Sensor.h> //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc…)
#include <Executor.h> //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#include <InterruptSensor.h> //Generic Interrupt "Sensor" Class, waits for change of state on digital input
#include <PollingSensor.h> //Generic Polling "Sensor" Class, polls Arduino pins periodically
#include <IS_Button.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses
#include <IS_Contact.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <EX_Switch.h> //Implements an Executor (EX) via a digital output to a relay
#include <EX_RGB_Dim.h> //Implements an Executor (EX) for a RGB LED or strip with PWM using 3 digital output pins
#include <Everything.h> //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications
// For the RC522 RFID Reader
#include <SPI.h>
#include <MFRC522.h>
//*************************************************************************************************
// WiFi Credentials
#include "credentials.h"
//*************************************************************************************************
// ESP32 WDOOM IO Pins
// Contact Sensor
#define IN_SENSOR_1 14
// Dry Contact Relay
#define OUT_RELAY_1 16
#define OUT_RELAY_2 17
// RGB LEDs
#define OUT_RGB1_Red 25
#define OUT_RGB1_Green 26
#define OUT_RGB1_Blue 27
// CR522 RFID Reader
#define SS_PIN 5
#define RST_PIN 21
// All standard ESP32 SPI Pins are used in addition
// MOSI GPIO23
// MISO GPIO19
// CLK GPIO18
// Instantiate RC522 RFID Reader
MFRC522 rfid(SS_PIN, RST_PIN);
//******************************************************************************************
//Define which Arduino Pins will be used for each device
//******************************************************************************************
#define PIN_CONTACT_1 IN_SENSOR_1 //Hubitat Capabilities - DIO Pin (Normally Open!)
#define PIN_RELAY_1 OUT_RELAY_1 //SmartThings Capability "Relay Switch"
#define PIN_RELAY_2 OUT_RELAY_2 //SmartThings Capability "Relay Switch"
#define PIN_RGB1_Red OUT_RGB1_Red
#define PIN_RGB1_Green OUT_RGB1_Green
#define PIN_RGB1_Blue OUT_RGB1_Blue
//******************************************************************************************
//ESP832 WiFi Information
//******************************************************************************************
// Set your WiFi details so the board can connect to the WiFi and Internet
// Get Credentials from the credentials.h file
const char* str_ssid = mySSID;
const char* str_password = myPASSWORD;
IPAddress ip (192, 168, 20, 151); // Device IP Address // <---You must edit this line!
IPAddress gateway (192, 168, 20, 1); // Router Gateway // <---You must edit this line!
IPAddress subnet (255, 255, 255, 0); // LAN Subnet Mask // <---You must edit this line!
IPAddress dnsserver (192, 168, 20, 1); // DNS Server // <---You must edit this line!
const unsigned int serverPort = 8090; // Port to run the HTTP Server on
// Hubitat Hub TCP/IP Address
IPAddress hubIp (192, 168, 20, 90); // Hubitat Hub IP // <---You must edit this line!
// Hubitat Hub TCP/IP Address
const unsigned int hubPort = 39501; // Hubitat Nub Port
//******************************************************************************************
//st::Everything::callOnMsgSend() optional callback routine. This is a sniffer to monitor
// data being sent to ST. This allows a user to act on data changes locally within the
// Arduino sktech.
//******************************************************************************************
void callback(const String &msg)
{
// Serial.print(F("ST_Anything Callback: Sniffed data = "));
// Serial.println(msg);
//TODO: Add local logic here to take action when a device's value/state is changed
//Masquerade as the ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line)
//st::receiveSmartString("Put your command here!"); //use same strings that the Device Handler would send
}
//-------------------------------------------------------------------------------
// Variables for integration with Hubitat
String str_Card_ID;
String msg_Card_ID;
unsigned int cardCode;
//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{
//******************************************************************************************
//Declare each Device that is attached to the Arduino
// Notes: - For each device, there is typically a corresponding "tile" defined in your
// SmartThings Device Hanlder Groovy code, except when using new COMPOSITE Device Handler
// - For details on each device's constructor arguments below, please refer to the
// corresponding header (.h) and program (.cpp) files.
// - The name assigned to each device (1st argument below) must match the Groovy
// Device Handler names. (Note: "temphumid" below is the exception to this rule
// as the DHT sensors produce both "temperature" and "humidity". Data from that
// particular sensor is sent to the ST Hub in two separate updates, one for
// "temperature" and one for "humidity")
// - The new Composite Device Handler is comprised of a Parent DH and various Child
// DH's. The names used below MUST not be changed for the Automatic Creation of
// child devices to work properly. Simply increment the number by +1 for each duplicate
// device (e.g. contact1, contact2, contact3, etc...) You can rename the Child Devices
// to match your specific use case in the ST Phone Application.
//******************************************************************************************
//Polling Sensors
//Interrupt Sensors
// Name, IO Pin, Initial State, Internal Pullup, Number of Loop Counts
static st::IS_Contact sensor1(F("contact1"), PIN_CONTACT_1, LOW, true, 20);
//EX_Switch arguments(Name, Pin, Initial State, Invert Logic) change last 2 args as needed for your application
static st::EX_Switch executor1(F("switch1"), PIN_RELAY_1, LOW, true);
static st::EX_Switch executor2(F("switch2"), PIN_RELAY_2, LOW, true);
// RGB Dimmer
static st::EX_RGB_Dim executor3(F("rgbSwitch1"), PIN_RGB1_Red, PIN_RGB1_Green, PIN_RGB1_Blue, false, 0, 1, 2); // channels (0,1,2) must be unique per ESP32
//*****************************************************************************
// Configure debug print output from each main class
// -Note: Set these to "false" if using Hardware Serial on pins 0 & 1
// to prevent communication conflicts with the ST Shield communications
//*****************************************************************************
st::Everything::debug = true;
st::Executor::debug = true;
st::Device::debug = true;
st::PollingSensor::debug = true;
st::InterruptSensor::debug = true;
//*****************************************************************************
//Initialize the "Everything" Class
//*****************************************************************************
//Initialize the optional local callback routine (safe to comment out if not desired)
st::Everything::callOnMsgSend = callback;
//Create the SmartThings ESP32WiFi Communications Object
//STATIC IP Assignment - Recommended
st::Everything::SmartThing = new st::SmartThingsESP32WiFi(str_ssid, str_password, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);
//DHCP IP Assigment - Must set your router's DHCP server to provice a static IP address for this device's MAC address
//st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, serverPort, hubIp, hubPort, st::receiveSmartString);
//Run the Everything class' init() routine which establishes WiFi communications with SmartThings Hub
st::Everything::init();
//*****************************************************************************
//Add each sensor to the "Everything" Class
//*****************************************************************************
st::Everything::addSensor(&sensor1);
//*****************************************************************************
//Add each executor to the "Everything" Class
//*****************************************************************************
st::Everything::addExecutor(&executor1);
st::Everything::addExecutor(&executor2);
st::Everything::addExecutor(&executor3);
//*****************************************************************************
//Initialize each of the devices which were added to the Everything Class
//*****************************************************************************
st::Everything::initDevices();
// Fot the RC522 RFID Reader
Serial.begin(115200); // Serial Port Baud Rate
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader");
}
//*******************************************************************************
//Arduino Loop() routine
//*******************************************************************************
void loop()
{
//*****************************************************************************
//Execute the Everything run method which takes care of "Everything"
//*****************************************************************************
st::Everything::run();
//*****************************************************************************
//Read RFID Tag
//*****************************************************************************
if (rfid.PICC_IsNewCardPresent()) // New Tag is available
{
if (rfid.PICC_ReadCardSerial()) // NUID has been readed
{
MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
Serial.print("RFID/NFC Tag Type: ");
Serial.println(rfid.PICC_GetTypeName(piccType));
// print UID in Serial Monitor in the hex format
Serial.print("UID:");
for (int i = 0; i < rfid.uid.size; i++)
{
Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(rfid.uid.uidByte[i], HEX);
}
Serial.println();
// Reset cardCode
cardCode = 0;
// Combine Bytes into single Word
// Only last 4 Bytes (32 Bits) will be used as a Card ID Code
for (int i = 0; i < rfid.uid.size; i++)
{
cardCode = ((cardCode << 8) + rfid.uid.uidByte[i]);
}
rfid.PICC_HaltA(); // halt PICC
rfid.PCD_StopCrypto1(); // stop encryption on PCD
// Send a Valid Card ID to Hubitat
str_Card_ID = String(cardCode, DEC);
msg_Card_ID = "voltage1 " + str_Card_ID;
st::Everything::sendSmartString(msg_Card_ID);
// Send Trigger Event to the Hubitat
st::Everything::sendSmartString("button1 pushed");
}
}
//*****************************************************************************
}
Here is an error from RGB Child:
UPDATE
RGB Child Component is not working as expected.
On, Off, All preset colors buttons are working just fine.
Set Color, Set Saturation and Set Hue buttons are not working and producing Java Errors:
There is no way I can fix this myself (not enough programming skills).
Ideally I would like to see a Button for the direct RGB settings say, in hex format 0xRRGGBB
I am sure, this could be added relatively easy.