IP Configuration
This commit is contained in:
12
lib/ST_Anything/Constants.cpp
Normal file
12
lib/ST_Anything/Constants.cpp
Normal file
@@ -0,0 +1,12 @@
|
||||
#include "Constants.h"
|
||||
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
|
||||
|
||||
}
|
||||
154
lib/ST_Anything/Constants.h
Normal file
154
lib/ST_Anything/Constants.h
Normal file
@@ -0,0 +1,154 @@
|
||||
//******************************************************************************************
|
||||
// File: Constants.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: This file contains a number of user-definable settings that affect the
|
||||
// ST_Anything library. This is the main file where user specific settings
|
||||
// should be made to adjust the behavior of SmartThings Shield communications.
|
||||
//
|
||||
// Notes:
|
||||
// -The SmartThings Shield uses Pins 0,1 or Pins 2,3 for serial communications based
|
||||
// on the user selectable switch on the shield.
|
||||
// -The SmartThings Shield reserves Pin 6 as well. Best to avoid using it.
|
||||
// -The Arduino UNO R3 defaults to using the SoftwareSerial library since the UNO has
|
||||
// only one Hardware UART port ("Serial") which is used by the USB port for
|
||||
// programming and debugging typically.
|
||||
// -You can use Hardware Serial with an UNO or Leonardo if desired, but you must suppress
|
||||
// all "Serial.Print()" calls in your sketch, and make sure your Serial.begin() call
|
||||
// is suppressed or set to use 2400 baud.
|
||||
// -Arduino MEGA defaults to using the MEGA's "Serial3" Hardware UART serial port.
|
||||
// This port uses pins 14(Tx) and 15(Rx). Wire Pin14 to Pin2 and Pin15 to Pin3.
|
||||
// Be certain to not use Pins 2 & 3 in your Arduino sketch since they are still
|
||||
// electrically connected to the ThingShield.
|
||||
// -The SoftwareSerial library has the following known limitations:
|
||||
// -If using multiple software serial ports, only one can receive data at a time.
|
||||
// - Not all pins on the Mega and Mega 2560 support change interrupts, so only
|
||||
// the following can be used for RX: 10, 11, 12, 13, 14, 15, 50, 51, 52, 53,
|
||||
// A8(62), A9(63), A10(64), A11(65), A12(66), A13(67), A14(68), A15(69).
|
||||
// - Not all pins on the Leonardo and Micro support change interrupts, so only
|
||||
// the following can be used for RX : 8, 9, 10, 11, 14 (MISO), 15 (SCK), 16 (MOSI).
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-28 Dan Ogorchock Change the default DEV_REFRESH_INTERVAL to 300 seconds. Was interfering with normal operations.
|
||||
// Added SENDSTRINGS_INTERVAL to throttle the rate at which data is sent to the ThingShield. Events were being missed.
|
||||
// Added DISABLE_REFRESH feature - commented out by default. Allows user to disable the automatic refresh feature as it can interfere with normal operations.
|
||||
// Adjusted MAX Sensor and Executor counts for the Arduino MEGA to allow 16 relay system to function properly.
|
||||
// 2016-06-04 Dan Ogorchock Added improved support for Arduino Leonardo
|
||||
// 2017-02-07 Dan Ogorchock Added support for new SmartThings v2.0 library (ThingShield, W5100, ESP8266)
|
||||
// 2017-08-14 Dan Ogorchock Added support for ESP32
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_CONSTANTS_H
|
||||
#define ST_CONSTANTS_H
|
||||
|
||||
//#include "Arduino.h"
|
||||
#include "SmartThings.h"
|
||||
|
||||
//#define ENABLE_SERIAL //If uncommented, will allow you to type in commands via the Arduino Serial Console Window (useful for debugging)
|
||||
//#define DISABLE_SMARTTHINGS //If uncommented, will disable all ST Shield Library calls (e.g. you want to use this library without SmartThings for a different application)
|
||||
//#define DISABLE_REFRESH //If uncommented, will disable periodic refresh of the sensors and executors states to the ST Cloud - improves performance, but may reduce data integrity
|
||||
|
||||
#if defined(__AVR_ATmega168__) || defined(__AVR_ATmega328__) || defined(__AVR_ATmega328P__) || defined(ARDUINO_AVR_UNO)
|
||||
#define BOARD_UNO
|
||||
#elif defined(__AVR_ATmega32U4__) || defined(ARDUINO_AVR_LEONARDO)
|
||||
#define BOARD_LEONARDO
|
||||
#elif defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__) || defined(ARDUINO_AVR_MEGA2560)
|
||||
#define BOARD_MEGA
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
#define BOARD_MKR1000
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
#define BOARD_ESP8266
|
||||
#elif defined(ARDUINO_ARCH_ESP32)
|
||||
#define BOARD_ESP32
|
||||
#else
|
||||
#define BOARD_UNO //assume user is using an UNO for the unknown case
|
||||
#endif
|
||||
|
||||
namespace st
|
||||
{
|
||||
class Constants
|
||||
{
|
||||
public:
|
||||
//Max name length (including null terminator!)
|
||||
static const byte MAX_NAME_LENGTH=30;
|
||||
|
||||
//Serial debug console baud rate
|
||||
static const unsigned long SERIAL_BAUDRATE=115200; //Uncomment If NOT using pins 0,1 for ST Shield communications (default)
|
||||
//static const unsigned int SERIAL_BAUDRATE=2400; //Uncomment if using Pins 0,1 for ST Shield Communications
|
||||
#if defined(BOARD_MEGA) || defined(BOARD_MKR1000) || defined(BOARD_ESP8266) || defined(BOARD_ESP32)
|
||||
//Maximum number of SENSOR objects
|
||||
static const byte MAX_SENSOR_COUNT=30; //Used to limit the number of sensor devices allowed. Be careful on Arduino UNO due to 2K SRAM limitation
|
||||
//Maximum number of EXECUTOR objects
|
||||
static const byte MAX_EXECUTOR_COUNT=20; //Used to limit the number of executor devices allowed. Be careful on Arduino UNO due to 2K SRAM limitation
|
||||
#else
|
||||
//Maximum number of SENSOR objects
|
||||
static const byte MAX_SENSOR_COUNT = 10; //Used to limit the number of sensor devices allowed. Be careful on Arduino UNO due to 2K SRAM limitation
|
||||
//Maximum number of EXECUTOR objects
|
||||
static const byte MAX_EXECUTOR_COUNT = 10; //Used to limit the number of executor devices allowed. Be careful on Arduino UNO due to 2K SRAM limitation
|
||||
#endif
|
||||
//Size of reserved return string
|
||||
static const byte RETURN_STRING_RESERVE = (MAX_SENSOR_COUNT + MAX_EXECUTOR_COUNT) * 5; //Do not make too large due to UNO's 2K SRAM limitation
|
||||
//Interval on which Device's refresh methods are called (in seconds) - most useful for Executors and InterruptSensors - only works if DISABLE_REFRESH is not defined above
|
||||
static const int DEV_REFRESH_INTERVAL=300; //seconds - Used to make sure the ST Cloud is kept current with device status (in case of missed updates to the ST Cloud) - primarily for Executors and InterruptSensors - only works if DISABLE_REFRESH is not defined above
|
||||
|
||||
//NOTE: The following constant was removed and replaced by a user defineable interval in the SmartThings library constaructors to permit different values for each communication method (i.e. ThingShield requires 1000ms, whereas Ethernet is ~100ms)
|
||||
//Minumum interval between sending packets of data to ThingShield (in milliseconds) - noticed issue where ST Hub/Cloud could not keep up with rapid data transfer
|
||||
//static const int SENDSTRINGS_INTERVAL = 100;
|
||||
// -------------------------------------------------------------------------------
|
||||
// --- SmartThings specific items
|
||||
// -------------------------------------------------------------------------------
|
||||
|
||||
//--- if true, the sketch will stall until the ST ThingShield has joined the ST Hub (set to false for debugging without a ST ThingShield, but with SmartThings code still enabled)
|
||||
static const bool WAIT_FOR_JOIN_AT_START = true;
|
||||
|
||||
//Select whether to use Hardware or Software Serial Communications - will result in the correct SmartThings constructor being called in Everything.cpp
|
||||
//#if defined(BOARD_UNO)
|
||||
// #define ST_SOFTWARE_SERIAL //Use Software Serial for UNO by default
|
||||
// //#define ST_HARDWARE_SERIAL
|
||||
//#elif defined(BOARD_MEGA) || defined(BOARD_LEONARDO)
|
||||
// //#define ST_SOFTWARE_SERIAL
|
||||
// #define ST_HARDWARE_SERIAL //Use Hardware Serial for MEGA or LEONARDO by default
|
||||
//#else
|
||||
// #define ST_SOFTWARE_SERIAL
|
||||
// //#define ST_HARDWARE_SERIAL
|
||||
//#endif
|
||||
|
||||
//---
|
||||
//--- if using SoftwareSerial
|
||||
//--- -set the following based on the pins you desire
|
||||
//--- -NOTE: you must use the SoftwareSerial version of the SmartThings Constructor
|
||||
//---
|
||||
//#if defined(BOARD_UNO)
|
||||
// static const uint8_t pinRX = 3; //Rx Pin3 - works for UNO R3, but not for Leonardo or Mega
|
||||
//#else
|
||||
// static const uint8_t pinRX = 10; //Rx Pin10 - works for Leonardo or Mega - You MUST jumper Pin10 to Pin3 - do not use Pin3 or Pin10 in your sketch!
|
||||
//#endif
|
||||
//
|
||||
// static const uint8_t pinTX = 2; //Tx Pin2 - works for UNO R3, Leonardo, and Mega
|
||||
|
||||
//---
|
||||
//--- if using Hardware Serial
|
||||
//--- -set the following based on the pins you desire (HW_SERIAL, Mega Only(HW_SERIAL1, HW_SERIAL2, HW_SERIAL3))
|
||||
//--- -NOTE: you must use the HardwareSerial version of the SmartThings Constructor
|
||||
//---
|
||||
//#if defined(BOARD_UNO)
|
||||
// static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL; //UNO - You MUST move ThingShield switch to D0/D1 position after loading program and then reset the Arduino
|
||||
//#elif defined(BOARD_LEONARDO)
|
||||
// static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL1; //Leonardo - You MUST move ThingShield switch to D0/D1 position
|
||||
//#elif defined(BOARD_MEGA)
|
||||
// //static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL; //MEGA - You MUST move ThingShield switch to D0/D1 position after loading program and then reset the Arduino
|
||||
// //static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL1; //MEGA - You MUST jumper Pin18 to Pin2 AND Pin19 to Pin3 - do not use Pin2 or Pin3 in your sketch!
|
||||
// //static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL2; //MEGA - You MUST jumper Pin16 to Pin2 AND Pin17 to Pin3 - do not use Pin2 or Pin3 in your sketch!
|
||||
// static const SmartThingsSerialType_t SERIAL_TYPE = HW_SERIAL3; //MEGA - You MUST jumper Pin14 to Pin2 AND Pin15 to Pin3 - do not use Pin2 or Pin3 in your sketch!
|
||||
//#endif
|
||||
// -------------------------------------------------------------------------------
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
68
lib/ST_Anything/Device.cpp
Normal file
68
lib/ST_Anything/Device.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
//******************************************************************************************
|
||||
// File: Device.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Device is the highest level generic class for either a st::Sensor or
|
||||
// st::Executor subclass.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2018-08-15 Dan Ogorchock Workaround for strcpy_P() ESP32 crash bug
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "Device.h"
|
||||
#include "Everything.h"
|
||||
#include "Constants.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
Device::Device(const __FlashStringHelper *name):
|
||||
m_pName(name)
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Device: New Device ID: "));
|
||||
Serial.println(getName());
|
||||
}
|
||||
}
|
||||
|
||||
//destructor
|
||||
Device::~Device()
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Device: Destroyed Device ID: "));
|
||||
Serial.println(getName());
|
||||
}
|
||||
}
|
||||
|
||||
void Device::refresh()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
const String Device::getName() const
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
return String((const char*)m_pName); //strcpy_P() causes ESP32 to crash
|
||||
#else
|
||||
char tmp[Constants::MAX_NAME_LENGTH];
|
||||
strcpy_P(tmp, (const char*)m_pName);
|
||||
return String(tmp);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
bool Device::debug=false;
|
||||
}
|
||||
57
lib/ST_Anything/Device.h
Normal file
57
lib/ST_Anything/Device.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//******************************************************************************************
|
||||
// File: Device.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Device is the highest level generic class for either a st::Sensor or
|
||||
// st::Executor subclass.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2019-02-09 Dan Ogorchock Moved update() from Sensor to Device
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_DEVICE_H
|
||||
#define ST_DEVICE_H
|
||||
|
||||
#include <Arduino.h>
|
||||
//#include <avr/pgmspace.h>
|
||||
|
||||
namespace st
|
||||
{
|
||||
class Device
|
||||
{
|
||||
private:
|
||||
const __FlashStringHelper *m_pName;
|
||||
|
||||
public:
|
||||
//constructor
|
||||
Device(const __FlashStringHelper *name);
|
||||
|
||||
//destructor
|
||||
virtual ~Device();
|
||||
|
||||
//initialization routine - This pure virtual function must be implemented by all derived classes
|
||||
virtual void init()=0;
|
||||
virtual void update() = 0;
|
||||
|
||||
//function used by all devices to process data from SmartThings Shield - all derived classes must implement this pure virtual function
|
||||
virtual void beSmart(const String &str)=0;
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of each Device subclass object
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
const String getName() const;
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
static bool debug;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
191
lib/ST_Anything/EX_Alarm.cpp
Normal file
191
lib/ST_Anything/EX_Alarm.cpp
Normal file
@@ -0,0 +1,191 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Alarm.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: EX_Alarm is a class which implements the SmartThings "Alarm" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version implements the Siren as
|
||||
// a digital output (uses a relay to switch the Siren on or off)
|
||||
//
|
||||
// TODO: Possibly add Strobe capability in the future
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Alarm executor2(F("alarm1"), PIN_ALARM, LOW, true, PIN_STROBE);
|
||||
//
|
||||
// st::EX_Alarm() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
// - byte pinStrobe - OPTOINAL - If supplied, will allow separate SIREN and STROBE outputs
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-04-20 Dan Ogorchock Add optional Strobe functionality
|
||||
// 2017-04-26 Dan Ogorchock Improved Logic if Strobe pin not defined
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "EX_Alarm.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_Alarm::writeStateToPin()
|
||||
{
|
||||
if (m_nCurrentAlarmState == both) {
|
||||
digitalWrite(m_nPin, m_bInvertLogic ? LOW : HIGH);
|
||||
if (m_bUseStrobe) { digitalWrite(m_nPinStrobe, m_bInvertLogic ? LOW : HIGH); }
|
||||
}
|
||||
else if(m_nCurrentAlarmState == siren) {
|
||||
digitalWrite(m_nPin, m_bInvertLogic ? LOW : HIGH);
|
||||
if (m_bUseStrobe) { digitalWrite(m_nPinStrobe, m_bInvertLogic ? HIGH : LOW); }
|
||||
}
|
||||
else if(m_nCurrentAlarmState == strobe) {
|
||||
digitalWrite(m_nPin, m_bInvertLogic ? HIGH : LOW);
|
||||
if (m_bUseStrobe) { digitalWrite(m_nPinStrobe, m_bInvertLogic ? LOW : HIGH); }
|
||||
}
|
||||
else if(m_nCurrentAlarmState == off) {
|
||||
digitalWrite(m_nPin, m_bInvertLogic ? HIGH : LOW);
|
||||
if (m_bUseStrobe) { digitalWrite(m_nPinStrobe, m_bInvertLogic ? HIGH : LOW); }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_Alarm::EX_Alarm(const __FlashStringHelper *name, byte pin, bool startingState, bool invertLogic, byte pinStrobe) :
|
||||
Executor(name),
|
||||
m_nPin(pin),
|
||||
m_bInvertLogic(invertLogic),
|
||||
m_nPinStrobe(pinStrobe)
|
||||
{
|
||||
m_nCurrentAlarmState = off;
|
||||
m_bUseStrobe = false;
|
||||
|
||||
setPin(pin);
|
||||
//If user has supplied a pin for Strobe Light
|
||||
if (pinStrobe < 255) {
|
||||
m_bUseStrobe = true;
|
||||
setPin(pinStrobe);
|
||||
}
|
||||
//else
|
||||
//{
|
||||
// m_bUseStrobe = false;
|
||||
//}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_Alarm::~EX_Alarm()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//initialization routine
|
||||
void EX_Alarm::init()
|
||||
{
|
||||
refresh(); //update ST Cloud with initial data
|
||||
}
|
||||
|
||||
//called periodically to ensure state of the Alarm Siren is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
void EX_Alarm::refresh()
|
||||
{
|
||||
//if (debug) {
|
||||
// Serial.print(F("EX_Alarm:: UseStrobe = "));
|
||||
// Serial.println(m_bUseStrobe);
|
||||
//}
|
||||
|
||||
if (m_nCurrentAlarmState == both) {
|
||||
Everything::sendSmartString(getName() + F(" both"));
|
||||
}
|
||||
else if(m_nCurrentAlarmState == siren) {
|
||||
Everything::sendSmartString(getName() + F(" siren"));
|
||||
}
|
||||
else if(m_nCurrentAlarmState == strobe) {
|
||||
Everything::sendSmartString(getName() + F(" strobe"));
|
||||
}
|
||||
else if(m_nCurrentAlarmState == off) {
|
||||
//else {
|
||||
Everything::sendSmartString(getName() + F(" off"));
|
||||
}
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "both" or "off" the Alarm (digital output)
|
||||
void EX_Alarm::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (debug) {
|
||||
Serial.print(F("EX_Alarm::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
//if (m_bUseStrobe) {
|
||||
if (s == F("both")) {
|
||||
if (m_bUseStrobe) {
|
||||
m_nCurrentAlarmState = both;
|
||||
}
|
||||
else {
|
||||
m_nCurrentAlarmState = siren;
|
||||
if (debug) {
|
||||
Serial.println(F("EX_Alarm::beSmart - Strobe Pin not defined. Defaulting to Siren!"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(s == F("siren")) {
|
||||
m_nCurrentAlarmState = siren;
|
||||
}
|
||||
else if(s == F("strobe")) {
|
||||
if (m_bUseStrobe) {
|
||||
m_nCurrentAlarmState = strobe;
|
||||
}
|
||||
else {
|
||||
m_nCurrentAlarmState = siren;
|
||||
if (debug) {
|
||||
Serial.println(F("EX_Alarm::beSmart - Strobe Pin not defined. Defaulting to Siren!"));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if(s == F("off")) {
|
||||
m_nCurrentAlarmState = off;
|
||||
}
|
||||
//}
|
||||
//else {
|
||||
// if (s == F("both") {
|
||||
// m_nCurrentAlarmState = both;
|
||||
// }
|
||||
// else if(s == F("siren")) {
|
||||
// m_nCurrentAlarmState = siren;
|
||||
// }
|
||||
// else if(s == F("strobe")) {
|
||||
// m_nCurrentAlarmState = siren;
|
||||
// }
|
||||
// else if(s == F("off")) {
|
||||
// m_nCurrentAlarmState = off;
|
||||
// }
|
||||
//}
|
||||
|
||||
writeStateToPin();
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void EX_Alarm::setPin(byte pin)
|
||||
{
|
||||
//m_nPin = pin;
|
||||
digitalWrite(pin, m_bInvertLogic ? HIGH : LOW);
|
||||
pinMode(pin, OUTPUT);
|
||||
writeStateToPin();
|
||||
}
|
||||
}
|
||||
82
lib/ST_Anything/EX_Alarm.h
Normal file
82
lib/ST_Anything/EX_Alarm.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Alarm.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: EX_Alarm is a class which implements the SmartThings "Alarm" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version implements the Siren as
|
||||
// a digital output (uses a relay to switch the Siren on or off)
|
||||
//
|
||||
// TODO: Possibly add Strobe capability in the future
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Alarm executor2(F("alarm1"), PIN_ALARM, LOW, true, PIN_STROBE);
|
||||
//
|
||||
// st::EX_Alarm() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
// - byte pinStrobe - OPTOINAL - If supplied, will allow separate SIREN and STROBE outputs
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-04-20 Dan Ogorchock Add optional Strobe functionality
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_EX_Alarm_H
|
||||
#define ST_EX_Alarm_H
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
enum Alarm_States { off, both, siren, strobe};
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_Alarm : public Executor
|
||||
{
|
||||
|
||||
private:
|
||||
|
||||
bool m_bInvertLogic;
|
||||
byte m_nPin;
|
||||
byte m_nPinStrobe;
|
||||
bool m_bUseStrobe;
|
||||
Alarm_States m_nCurrentAlarmState;
|
||||
|
||||
void writeStateToPin();
|
||||
|
||||
public:
|
||||
//constructor
|
||||
EX_Alarm(const __FlashStringHelper *name, byte Pin, bool startingState = LOW, bool invertLogic = false, byte pinStrobe = 255);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_Alarm();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically to ensure state of the Alarm Siren is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "both" or "off" the Alarm (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//gets
|
||||
virtual byte getPin() const { return m_nPin; }
|
||||
virtual byte getStrobePin() const { return m_nPinStrobe; }
|
||||
|
||||
//sets
|
||||
virtual void setPin(byte pin);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
201
lib/ST_Anything/EX_PWM_Dim.cpp
Normal file
201
lib/ST_Anything/EX_PWM_Dim.cpp
Normal file
@@ -0,0 +1,201 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_PWM_Dim.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_PWM_Dim is a class which implements the SmartThings "Switch" and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_PWM_Dim executor1(F("dimmerSwitch1"), PIN_SWITCH, PIN_LEVEL, LOW, true);
|
||||
//
|
||||
// st::EX_PWM_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-08-30 Dan Ogorchock Adding reporting of 'level'
|
||||
// 2018-12-06 Dan Ogorchock Fixed Comments
|
||||
// 2019-04-10 Dan Ogorchock Corrected analogWrite() call for ESP8266 platform
|
||||
// 2019-12-19 Doug Johnson Created new file based on EX_Switch_Dim to remove separate switch, and add dedicated smoothing
|
||||
// 2020-04-01 Dan Ogorchock Added compatability for traditional Arduino Boards
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "EX_PWM_Dim.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
void EX_PWM_Dim::writeLevelToPin()
|
||||
{
|
||||
if((m_nCurrentLevel == 0) && (m_bSetState == HIGH))
|
||||
{
|
||||
for(int i=1; i < m_nSetLevel; i++)
|
||||
{
|
||||
m_nCurrentLevel++;
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Switch_Dim:: analogWrite not currently supported on ESP32!"));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 255));
|
||||
#endif
|
||||
delay(7);
|
||||
}
|
||||
}
|
||||
if((m_nCurrentLevel > 0) && (m_bSetState == LOW))
|
||||
{
|
||||
for(int i=m_nCurrentLevel; i > 0; i--)
|
||||
{
|
||||
m_nCurrentLevel--;
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Switch_Dim:: analogWrite not currently supported on ESP32!"));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 255));
|
||||
#endif
|
||||
delay(7);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if((m_nCurrentLevel < m_nSetLevel)&& (m_bSetState == HIGH))
|
||||
{
|
||||
for(int i=m_nCurrentLevel; i < m_nSetLevel; i++)
|
||||
{
|
||||
m_nCurrentLevel++;
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Switch_Dim:: analogWrite not currently supported on ESP32!"));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 255));
|
||||
#endif
|
||||
delay(7);
|
||||
}
|
||||
}
|
||||
if(m_nCurrentLevel > m_nSetLevel)
|
||||
{
|
||||
for(int i=m_nCurrentLevel; i > m_nSetLevel; i--)
|
||||
{
|
||||
m_nCurrentLevel--;
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Switch_Dim:: analogWrite not currently supported on ESP32!"));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 255));
|
||||
#endif
|
||||
delay(7);
|
||||
}
|
||||
}
|
||||
if(m_nCurrentLevel == 0)
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_PWM_Dim::EX_PWM_Dim(const __FlashStringHelper *name, byte pinPWM, bool startingState, bool invertLogic) :
|
||||
Executor(name),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic)
|
||||
{
|
||||
m_nCurrentLevel = startingState == HIGH ? 100 : 0;
|
||||
setPWMPin(pinPWM);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_PWM_Dim::~EX_PWM_Dim()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_PWM_Dim::init()
|
||||
{
|
||||
//Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
refresh();
|
||||
}
|
||||
|
||||
void EX_PWM_Dim::beSmart(const String &str)
|
||||
{
|
||||
//String s = str.substring(str.indexOf(' ') + 1, str.indexOf(':'));
|
||||
//String dur = str.substring(str.indexOf(':') + 1);
|
||||
//dur.trim();
|
||||
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_PWM_Dim::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if (s == F("on"))
|
||||
{
|
||||
m_bSetState = HIGH;
|
||||
}
|
||||
else if (s == F("off"))
|
||||
{
|
||||
m_bSetState = LOW;
|
||||
}
|
||||
else //must be a set level command
|
||||
{
|
||||
s.trim();
|
||||
m_nSetLevel = byte(s.toInt());
|
||||
if (m_nSetLevel == 0)
|
||||
{
|
||||
m_bSetState = LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bSetState = HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
writeLevelToPin();
|
||||
|
||||
//Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
refresh();
|
||||
|
||||
}
|
||||
|
||||
void EX_PWM_Dim::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
Everything::sendSmartString(getName() + " " + m_nSetLevel);
|
||||
}
|
||||
|
||||
|
||||
void EX_PWM_Dim::setPWMPin(byte pin)
|
||||
{
|
||||
m_nPinPWM = pin;
|
||||
pinMode(m_nPinPWM, OUTPUT);
|
||||
writeLevelToPin();
|
||||
}
|
||||
}
|
||||
82
lib/ST_Anything/EX_PWM_Dim.h
Normal file
82
lib/ST_Anything/EX_PWM_Dim.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_PWM_Dim.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_PWM_Dim is a class which implements the SmartThings "Switch" and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_PWM_Dim executor1(F("dimmerSwitch1"), PIN_SWITCH, PIN_LEVEL, LOW, true);
|
||||
//
|
||||
// st::EX_PWM_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-12-06 Dan Ogorchock Fixed Comments
|
||||
// 2019-04-10 Dan Ogorchock Corrected analogWrite() call for ESP8266 platform
|
||||
// 2019-12-19 Doug Johnson Created new file based on EX_Switch_Dim to remove separate switch, and add dedicated smoothing
|
||||
// 2020-04-01 Dan Ogorchock Added compatability for traditional Arduino Boards
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_PWM_DIM
|
||||
#define ST_EX_PWM_DIM
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_PWM_Dim: public Executor
|
||||
{
|
||||
private:
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
bool m_bSetState;
|
||||
//byte m_nPinSwitch; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
byte m_nPinPWM; //Arduino Pin used as a PWM Output for the switch level capability
|
||||
byte m_nCurrentLevel; //Switch Level value from SmartThings (0 to 100)
|
||||
byte m_nSetLevel;
|
||||
|
||||
//void writeStateToPin(); //function to update the Arduino Digital Output Pin
|
||||
void writeLevelToPin(); //function to update the Arduino PWM Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_PWM_Dim(const __FlashStringHelper *name, byte pinPWM, bool startingState = LOW, bool invertLogic = false);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_PWM_Dim();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output) and the LEVEL (PWM Output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getPWMPin() const { return m_nPinPWM; }
|
||||
|
||||
virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
|
||||
virtual bool getLevel() const { return m_nCurrentLevel; } //Dim Level of the switch
|
||||
|
||||
//sets
|
||||
//virtual void setSwitchPin(byte pin);
|
||||
virtual void setPWMPin(byte pin);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
239
lib/ST_Anything/EX_RGBW_Dim.cpp
Normal file
239
lib/ST_Anything/EX_RGBW_Dim.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_RGBW_Dim.h
|
||||
// Authors: Allan (vseven) based on EX_Switch_Dim by Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_RGBW_Dim is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_RGBW_Dim executor1("rgbwSwitch1", PIN_R, PIN_G, PIN_B, PIN_W, true, 0, 1, 2, 3);
|
||||
//
|
||||
// st::EX_RGBW_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin_r - REQUIRED - the Arduino Pin to be used as a digital output for Red.
|
||||
// - byte pin_g - REQUIRED - the Arduino Pin to be used as a digital output for Green.
|
||||
// - byte pin_b - REQUIRED - the Arduino Pin to be used as a digital output for Blue.
|
||||
// - byte pin_w - REQUIRED - the Arduino Pin to be used as a digital output for White.
|
||||
// - bool commonAnode - REQUIRED - determines whether the LED uses a common Anode or Cathode. True for Anode.
|
||||
// - byte channel_r - OPTIONAL - PWM channel used for Red on a ESP32.
|
||||
// - byte channel_g - OPTIONAL - PWM channel used for Green on a ESP32.
|
||||
// - byte channel_b - OPTIONAL - PWM channel used for Blue on a ESP32.
|
||||
// - byte channel_w - OPTIONAL - PWM channel used for Whitw on a ESP32.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-08 Allan (vseven) Modified original code from EX_RGBW_Dim to be used for RGB lighting
|
||||
// 2017-10-12 Allan (vseven) Modified EX_RGBW_Dim for support of a White LED channel
|
||||
// 2018-04-02 Dan Ogorchock Fixed Typo
|
||||
// 2020-06-09 Dan Ogorchock Scaled the 8bit values to 10bit for ESP8266 "analogWrite()"
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "EX_RGBW_Dim.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_RGBW_Dim::writeRGBWToPins()
|
||||
{
|
||||
int subStringR;
|
||||
int subStringG;
|
||||
int subStringB;
|
||||
int subStringW;
|
||||
|
||||
if (m_bCurrentState == HIGH) {
|
||||
// Our status is on so get the RGBW value from the hex
|
||||
String hexstring = m_sCurrentHEX;
|
||||
unsigned long number = (unsigned long) strtoul( &hexstring[1], NULL, 16);
|
||||
// Split them up into r, g, b, w values
|
||||
subStringR = number >> 24;
|
||||
subStringG = number >> 16 & 0xFF;
|
||||
subStringB = number >> 8 & 0xFF;
|
||||
subStringW = number & 0xFF;
|
||||
} else {
|
||||
// Status is off so turn off LED
|
||||
subStringR = 00;
|
||||
subStringG = 00;
|
||||
subStringB = 00;
|
||||
subStringW = 00;
|
||||
}
|
||||
|
||||
if(m_bCommonAnode) {
|
||||
// A hex value of 00 will translate to 255 for a common anode. However the
|
||||
// ledcWrite seems to need a 256 to turn off so we are adding one here.
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
subStringR = 255 - subStringR + 1;
|
||||
subStringG = 255 - subStringG + 1;
|
||||
subStringB = 255 - subStringB + 1;
|
||||
subStringW = 255 - subStringW + 1;
|
||||
#else
|
||||
subStringR = 255 - subStringR;
|
||||
subStringG = 255 - subStringG;
|
||||
subStringB = 255 - subStringB;
|
||||
subStringW = 255 - subStringW;
|
||||
#endif
|
||||
}
|
||||
// Write to outputs. Use ledc for ESP32, analogWrite for everything else.
|
||||
|
||||
if (st::Executor::debug) {
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
Serial.print(F("subString R:G:B:W = "));
|
||||
Serial.println(String(subStringR) + ":" + String(subStringG) + ":" + String(subStringB) + ":" + String(subStringW));
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
Serial.print(F("subString R:G:B:W = "));
|
||||
Serial.println(String(map(subStringR, 0, 255, 0, 1023)) + ":" + String(map(subStringG, 0, 255, 0, 1023)) + ":" + String(map(subStringB, 0, 255, 0, 1023)) + ":" + String(map(subStringW, 0, 255, 0, 1023)));
|
||||
#else
|
||||
Serial.print(F("subString R:G:B:W = "));
|
||||
Serial.println(String(subStringR) + ":" + String(subStringG) + ":" + String(subStringB) + ":" + String(subStringW));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Any adjustments to the colors can be done here before sending the commands. For example if red is always too bright reduce it:
|
||||
// subStringR = subStringR * 0.95
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelR, subStringR);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinR, map(subStringR, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinR, subStringR);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelG, subStringG);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinG, map(subStringG, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinG, subStringG);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelB, subStringB);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinB, map(subStringB, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinB, subStringB);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelW, subStringW);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinW, map(subStringW, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinW, subStringW);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_RGBW_Dim::EX_RGBW_Dim(const __FlashStringHelper *name, byte pinR, byte pinG, byte pinB, byte pinW, bool commonAnode, byte channelR, byte channelG, byte channelB, byte channelW):
|
||||
Executor(name),
|
||||
m_bCommonAnode(commonAnode)
|
||||
{
|
||||
setRedPin(pinR, channelR);
|
||||
setGreenPin(pinG, channelG);
|
||||
setBluePin(pinB, channelB);
|
||||
setWhitePin(pinW, channelW);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_RGBW_Dim::~EX_RGBW_Dim()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_RGBW_Dim::init()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
void EX_RGBW_Dim::beSmart(const String &str)
|
||||
{
|
||||
String s=str.substring(str.indexOf(' ')+1);
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_RGBW_Dim::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if(s==F("on"))
|
||||
{
|
||||
m_bCurrentState=HIGH;
|
||||
}
|
||||
else if(s==F("off"))
|
||||
{
|
||||
m_bCurrentState=LOW;
|
||||
}
|
||||
else //must be a set color command
|
||||
{
|
||||
s.trim();
|
||||
m_sCurrentHEX = s;
|
||||
}
|
||||
|
||||
writeRGBWToPins();
|
||||
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_RGBW_Dim::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_RGBW_Dim::setRedPin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinR = pin;
|
||||
m_nChannelR = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinR, m_nChannelR);
|
||||
ledcSetup(m_nChannelR, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinR, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
void EX_RGBW_Dim::setGreenPin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinG = pin;
|
||||
m_nChannelG = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinG, m_nChannelG);
|
||||
ledcSetup(m_nChannelG, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinG, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
void EX_RGBW_Dim::setBluePin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinB = pin;
|
||||
m_nChannelB = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinB, m_nChannelB);
|
||||
ledcSetup(m_nChannelB, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinB, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
void EX_RGBW_Dim::setWhitePin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinW = pin;
|
||||
m_nChannelW = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinW, m_nChannelW);
|
||||
ledcSetup(m_nChannelW, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinW, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
98
lib/ST_Anything/EX_RGBW_Dim.h
Normal file
98
lib/ST_Anything/EX_RGBW_Dim.h
Normal file
@@ -0,0 +1,98 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_RGBW_Dim.h
|
||||
// Authors: Allan (vseven) based on EX_Switch_Dim by Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_RGBW_Dim is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_RGBW_Dim executor1("rgbwSwitch1", PIN_R, PIN_G, PIN_B, PIN_W, true, 0, 1, 2, 3);
|
||||
//
|
||||
// st::EX_RGBW_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name.
|
||||
// - byte pin_r - REQUIRED - the Arduino Pin to be used as a digital output for Red.
|
||||
// - byte pin_g - REQUIRED - the Arduino Pin to be used as a digital output for Green.
|
||||
// - byte pin_b - REQUIRED - the Arduino Pin to be used as a digital output for Blue.
|
||||
// - byte pin_w - REQUIRED - the Arduino Pin to be used as a digital output for White.
|
||||
// - bool commonAnode - REQUIRED - determines whether the LED uses a common Anode or Cathode. True for Anode.
|
||||
// - byte channel_r - OPTIONAL - PWM channel used for Red on a ESP32.
|
||||
// - byte channel_g - OPTIONAL - PWM channel used for Green on a ESP32.
|
||||
// - byte channel_b - OPTIONAL - PWM channel used for Blue on a ESP32.
|
||||
// - byte channel_w - OPTIONAL - PWM channel used for Whitw on a ESP32.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-06 Allan (vseven) Modified original code from EX_Switch_Dim to be used for RGB lighting
|
||||
// 2017-10-12 Allan (vseven) Modified EX_RGB_Dim for support of a White LEd channel
|
||||
// 2020-06-09 Dan Ogorchock Scaled the 8bit values to 10bit for ESP8266 "analogWrite()"
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_RGBW_Dim
|
||||
#define ST_EX_RGBW_Dim
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_RGBW_Dim: public Executor
|
||||
{
|
||||
private:
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bCommonAnode; //TRUE or FALSE
|
||||
byte m_nPinR; //Arduino Pin used as a PWM Output for Red
|
||||
byte m_nPinG; //Arduino Pin used as a PWM Output for Green
|
||||
byte m_nPinB; //Arduino Pin used as a PWM Output for Blue
|
||||
byte m_nPinW; //Arduino Pin used as a PWM Output for White
|
||||
byte m_nChannelR; //PWM Channel used for Red output
|
||||
byte m_nChannelG; //PWM Channel used for Green output
|
||||
byte m_nChannelB; //PWM Channel used for Blue output
|
||||
byte m_nChannelW; //PWM Channel used for White output
|
||||
String m_sCurrentHEX; //HEX value of color currently set
|
||||
|
||||
void writeRGBWToPins(); //function to update the Arduino PWM Output Pins
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_RGBW_Dim(const __FlashStringHelper *name, byte pinR, byte pinG, byte pinB, byte pinW, bool commonAnode, byte channelR = 0, byte channelG = 0, byte channelB = 0, byte channelW = 0);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_RGBW_Dim();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch along with HEX value for LEDs)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getRedPin() const { return m_nPinR; }
|
||||
virtual byte getGreenPin() const { return m_nPinG; }
|
||||
virtual byte getBluePin() const { return m_nPinB; }
|
||||
virtual byte getWhitePin() const { return m_nPinW; }
|
||||
|
||||
virtual byte getRedChannel() const { return m_nChannelR; }
|
||||
virtual byte getGreenChannel() const { return m_nChannelG; }
|
||||
virtual byte getBlueChannel() const { return m_nChannelB; }
|
||||
virtual byte getWhiteChannel() const { return m_nChannelW; }
|
||||
|
||||
virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
|
||||
virtual String getHEX() const { return m_sCurrentHEX; } // color value in HEX
|
||||
|
||||
//sets
|
||||
virtual void setRedPin(byte pin,byte channel);
|
||||
virtual void setGreenPin(byte pin,byte channel);
|
||||
virtual void setBluePin(byte pin,byte channel);
|
||||
virtual void setWhitePin(byte pin,byte channel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
213
lib/ST_Anything/EX_RGB_Dim.cpp
Normal file
213
lib/ST_Anything/EX_RGB_Dim.cpp
Normal file
@@ -0,0 +1,213 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_RGB_Dim.h
|
||||
// Authors: Allan (vseven) based on EX_Switch_Dim by Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_RGB_Dim is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_RGB_Dim executor1("rgbSwitch1", PIN_R, PIN_G, PIN_B, true, 0, 1, 2);
|
||||
//
|
||||
// st::EX_RGB_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin_r - REQUIRED - the Arduino Pin to be used as a digital output for Red
|
||||
// - byte pin_g - REQUIRED - the Arduino Pin to be used as a digital output for Green
|
||||
// - byte pin_b - REQUIRED - the Arduino Pin to be used as a digital output for Blue
|
||||
// - bool commonAnode - REQUIRED - determines whether the Arduino Digital Output should use inverted logic
|
||||
// - byte channel_r - OPTIONAL - PWM channel used for Red on a ESP32
|
||||
// - byte channel_g - OPTIONAL - PWM channel used for Green on a ESP32
|
||||
// - byte channel_b - OPTIONAL - PWM channel used for Blue on a ESP32
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-08 Allan (vseven) Modified original code from EX_Switch_Dim to be used for RGB lighting
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2020-03-29 DOUG (M2) Scaled the 8bit values to 10bit for ESP8266 "analogWrite()"
|
||||
// 2020-04-01 Dan Ogorchock Added back in functionality for traditional Arduino Boards
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "EX_RGB_Dim.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_RGB_Dim::writeRGBToPins()
|
||||
{
|
||||
int subStringR;
|
||||
int subStringG;
|
||||
int subStringB;
|
||||
|
||||
if (m_bCurrentState == HIGH)
|
||||
{
|
||||
// Our status is on so get the RGB value from the hex
|
||||
String hexstring = m_sCurrentHEX;
|
||||
long number = (long) strtol( &hexstring[1], NULL, 16);
|
||||
// Split them up into r, g, b values
|
||||
subStringR = number >> 16;
|
||||
subStringG = number >> 8 & 0xFF;
|
||||
subStringB = number & 0xFF;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Status is off so turn off LED
|
||||
subStringR = 00;
|
||||
subStringG = 00;
|
||||
subStringB = 00;
|
||||
}
|
||||
|
||||
if(m_bCommonAnode)
|
||||
{
|
||||
// A hex value of 00 will translate to 255 for a common anode. However the
|
||||
// ledcWrite seems to need a 256 to turn off so we are adding one here.
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
subStringR = 255 - subStringR + 1;
|
||||
subStringG = 255 - subStringG + 1;
|
||||
subStringB = 255 - subStringB + 1;
|
||||
#else
|
||||
subStringR = 255 - subStringR;
|
||||
subStringG = 255 - subStringG;
|
||||
subStringB = 255 - subStringB;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Write to outputs. Use ledc for ESP32, analogWrite for everything else.
|
||||
if (st::Executor::debug) {
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
Serial.print(F("subString R:G:B = "));
|
||||
Serial.println(String(subStringR) + ":" + String(subStringG) + ":" + String(subStringB));
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
Serial.print(F("subString 10bit R:G:B = "));
|
||||
Serial.println(String(map(subStringR, 0, 255, 0, 1023)) + ":" + String(map(subStringG, 0, 255, 0, 1023)) + ":" + String(map(subStringB, 0, 255, 0, 1023)));
|
||||
#else
|
||||
Serial.print(F("subString R:G:B = "));
|
||||
Serial.println(String(subStringR) + ":" + String(subStringG) + ":" + String(subStringB));
|
||||
#endif
|
||||
}
|
||||
|
||||
// Any adjustments to the colors can be done here before sending the commands. For example if red is always too bright reduce it:
|
||||
// subStringR = subStringR * 0.95
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelR, subStringR);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinR, map(subStringR, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinR, subStringR);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelG, subStringG);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinG, map(subStringG, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinG, subStringG);
|
||||
#endif
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcWrite(m_nChannelB, subStringB);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinB, map(subStringB, 0, 255, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinB, subStringB);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_RGB_Dim::EX_RGB_Dim(const __FlashStringHelper *name, byte pinR, byte pinG, byte pinB, bool commonAnode, byte channelR, byte channelG, byte channelB):
|
||||
Executor(name),
|
||||
m_bCommonAnode(commonAnode)
|
||||
{
|
||||
setRedPin(pinR, channelR);
|
||||
setGreenPin(pinG, channelG);
|
||||
setBluePin(pinB, channelB);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_RGB_Dim::~EX_RGB_Dim()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_RGB_Dim::init()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
void EX_RGB_Dim::beSmart(const String &str)
|
||||
{
|
||||
String s=str.substring(str.indexOf(' ')+1);
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_RGB_Dim::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if(s==F("on"))
|
||||
{
|
||||
m_bCurrentState=HIGH;
|
||||
}
|
||||
else if(s==F("off"))
|
||||
{
|
||||
m_bCurrentState=LOW;
|
||||
}
|
||||
else //must be a set color command
|
||||
{
|
||||
s.trim();
|
||||
m_sCurrentHEX = s;
|
||||
}
|
||||
|
||||
writeRGBToPins();
|
||||
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_RGB_Dim::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_RGB_Dim::setRedPin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinR = pin;
|
||||
m_nChannelR = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinR, m_nChannelR);
|
||||
ledcSetup(m_nChannelR, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinR, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
void EX_RGB_Dim::setGreenPin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinG = pin;
|
||||
m_nChannelG = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinG, m_nChannelG);
|
||||
ledcSetup(m_nChannelG, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinG, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
void EX_RGB_Dim::setBluePin(byte pin, byte channel)
|
||||
{
|
||||
m_nPinB = pin;
|
||||
m_nChannelB = channel;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
ledcAttachPin(m_nPinB, m_nChannelB);
|
||||
ledcSetup(m_nChannelB, 5000, 8);
|
||||
#else
|
||||
pinMode(m_nPinB, OUTPUT);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
91
lib/ST_Anything/EX_RGB_Dim.h
Normal file
91
lib/ST_Anything/EX_RGB_Dim.h
Normal file
@@ -0,0 +1,91 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_RGB_Dim.h
|
||||
// Authors: Allan (vseven) based on EX_Switch_Dim by Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_RGB_Dim is a class which implements the SmartThings "Color Control", "Switch", and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_RGB_Dim executor1("rgbSwitch1", PIN_R, PIN_G, PIN_B, true, 0, 1, 2);
|
||||
//
|
||||
// st::EX_RGB_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name.
|
||||
// - byte pin_r - REQUIRED - the Arduino Pin to be used as a digital output for Red.
|
||||
// - byte pin_g - REQUIRED - the Arduino Pin to be used as a digital output for Green.
|
||||
// - byte pin_b - REQUIRED - the Arduino Pin to be used as a digital output for Blue.
|
||||
// - bool commonAnode - REQUIRED - determines whether the LED uses a common Anode or Cathode. True for Anode.
|
||||
// - byte channel_r - OPTIONAL - PWM channel used for Red on a ESP32.
|
||||
// - byte channel_g - OPTIONAL - PWM channel used for Green on a ESP32.
|
||||
// - byte channel_b - OPTIONAL - PWM channel used for Blue on a ESP32.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-06 Allan (vseven) Modified original code from EX_Switch_Dim to be used for RGB lighting
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2020-03-29 DOUG (M2) Scaled the 8bit values to 10bit for ESP8266 "analogWrite()"
|
||||
// 2020-04-01 Dan Ogorchock Added back in functionality for traditional Arduino Boards
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_RGB_DIM
|
||||
#define ST_EX_RGB_DIM
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_RGB_Dim: public Executor
|
||||
{
|
||||
private:
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bCommonAnode; //TRUE or FALSE
|
||||
byte m_nPinR; //Arduino Pin used as a PWM Output for Red
|
||||
byte m_nPinG; //Arduino Pin used as a PWM Output for Green
|
||||
byte m_nPinB; //Arduino Pin used as a PWM Output for Blue
|
||||
byte m_nChannelR; //PWM Channel used for Red output
|
||||
byte m_nChannelG; //PWM Channel used for Green output
|
||||
byte m_nChannelB; //PWM Channel used for Blue output
|
||||
String m_sCurrentHEX; //HEX value of color currently set
|
||||
|
||||
void writeRGBToPins(); //function to update the Arduino PWM Output Pins
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_RGB_Dim(const __FlashStringHelper *name, byte pinR, byte pinG, byte pinB, bool commonAnode, byte channelR = 0, byte channelG = 0, byte channelB = 0);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_RGB_Dim();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch along with HEX value for LEDs)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getRedPin() const { return m_nPinR; }
|
||||
virtual byte getGreenPin() const { return m_nPinG; }
|
||||
virtual byte getBluePin() const { return m_nPinB; }
|
||||
|
||||
virtual byte getRedChannel() const { return m_nChannelR; }
|
||||
virtual byte getGreenChannel() const { return m_nChannelG; }
|
||||
virtual byte getBlueChannel() const { return m_nChannelB; }
|
||||
|
||||
virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
|
||||
virtual String getHEX() const { return m_sCurrentHEX; } // color value in HEX
|
||||
|
||||
//sets
|
||||
virtual void setRedPin(byte pin,byte channel);
|
||||
virtual void setGreenPin(byte pin,byte channel);
|
||||
virtual void setBluePin(byte pin,byte channel);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
198
lib/ST_Anything/EX_Servo.cpp
Normal file
198
lib/ST_Anything/EX_Servo.cpp
Normal file
@@ -0,0 +1,198 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Servo.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_Servo is a class which implements the SmartThings/Hubitat "Switch Level" device capability.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Servo executor1(F("servo1"), PIN_SERVO, 90, true, 1000, 0, 180, 2000, 544, 2400);
|
||||
//
|
||||
// st::EX_Servo() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - int startingAngle - OPTIONAL - the value desired for the initial angle of the servo motor (0 to 180, defaults to 90)
|
||||
// - bool detachAfterMove - OPTIONAL - determines if servo motor is powered down after move (defaults to false)
|
||||
// - int servoDetachTime - OPTIONAL - determines how long after the servo is moved that the servo is powered down if detachAfterMove is true (defaults to 1000ms)
|
||||
// - int minLevelAngle - OPTIONAL - servo angle in degrees to map to level 0 (defaults to 0 degrees)
|
||||
// - int maxLevelAngle - OPTIONAL - servo angle in degrees to map to level 100 (defaults to 180 degrees)
|
||||
// - int servoRate - OPTIONAL - initial servo rate in ms/degree (defaults to 2000, used to ensure a gentle move during startup, afterwards comes from SmartThings/Hubitat with each move request)
|
||||
// - int minPulseWidth - OPTIONAL - minimum pulse width in milliseconds, defaults to 544 (see Arduino servo attach() function)
|
||||
// - int maxPulseWidth - OPTIONAL - maximum pulse width in milliseconds, defaults to 2400 (see Arduino servo attach() function)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2018-06-23 Dan Ogorchock Original Creation
|
||||
// 2018-06-24 Dan Ogorchock Since ESP32 does not support SERVO library, exclude all code to prevent compiler error
|
||||
// 2018-08-19 Dan Ogorchock Added feature to optionally allow servo to be powered down after a move
|
||||
// 2019-02-02 Jeff Albers Added Parameters to map servo endpoints, actively control rate of servo motion via duration input to device driver, intializes to level instead of angle
|
||||
// 2019-02-09 Dan Ogorchock Adding Asynchronous Motion to eliminate blocking calls and to allow simultaneous motion across multiple servos
|
||||
// 2019-03-04 Dan Ogorchock Added optional min and max pulse width parameters to allow servo specific adjustments
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "EX_Servo.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
#if not defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_Servo::writeAngleToPin()
|
||||
{
|
||||
if(m_bMoveActive == true) {
|
||||
m_bMoveActive = false;
|
||||
}
|
||||
|
||||
if (!m_Servo.attached()) {
|
||||
m_Servo.attach(m_nPinPWM, m_nMinPulseWidth, m_nMaxPulseWidth);
|
||||
}
|
||||
|
||||
if ((m_nTargetAngle < m_nMinLevelAngle) and (m_nTargetAngle < m_nMaxLevelAngle)) {
|
||||
if (m_nMinLevelAngle < m_nMaxLevelAngle) {
|
||||
m_nTargetAngle = m_nMinLevelAngle;
|
||||
}
|
||||
else {
|
||||
m_nTargetAngle = m_nMaxLevelAngle;
|
||||
}
|
||||
}
|
||||
if ((m_nTargetAngle > m_nMaxLevelAngle) and (m_nTargetAngle > m_nMinLevelAngle)) {
|
||||
if (m_nMaxLevelAngle > m_nMinLevelAngle) {
|
||||
m_nTargetAngle = m_nMaxLevelAngle;
|
||||
}
|
||||
else {
|
||||
m_nTargetAngle = m_nMinLevelAngle;
|
||||
}
|
||||
}
|
||||
|
||||
m_nTimeStep = abs(m_nCurrentRate / (m_nMaxLevelAngle - m_nMinLevelAngle)); //Constant servo step rate assumes duration is the time desired for maximum level change of 100
|
||||
m_nCurrentAngle = m_nOldAngle; //preserver original angular position
|
||||
m_bMoveActive = true; //start the move (the update() function will take care of the actual motion)
|
||||
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_Servo:: Servo motor angle set to "));
|
||||
Serial.println(m_nTargetAngle);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_Servo::EX_Servo(const __FlashStringHelper *name, byte pinPWM, int startingAngle, bool detachAfterMove, long servoDetachTime, int minLevelAngle, int maxLevelAngle, int servoRate, int minPulseWidth, int maxPulseWidth) :
|
||||
Executor(name),
|
||||
m_Servo(),
|
||||
m_nTargetAngle(startingAngle),
|
||||
m_bDetachAfterMove(detachAfterMove),
|
||||
m_nDetachTime(servoDetachTime),
|
||||
m_nMinLevelAngle(minLevelAngle),
|
||||
m_nMaxLevelAngle(maxLevelAngle),
|
||||
m_nCurrentRate(servoRate),
|
||||
m_bMoveActive(false),
|
||||
m_bDetachTmrActive(false),
|
||||
m_nMinPulseWidth(minPulseWidth),
|
||||
m_nMaxPulseWidth(maxPulseWidth)
|
||||
{
|
||||
setPWMPin(pinPWM);
|
||||
m_nOldAngle = (minLevelAngle + maxLevelAngle) / 2;
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_Servo::~EX_Servo()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_Servo::init()
|
||||
{
|
||||
writeAngleToPin();
|
||||
refresh();
|
||||
}
|
||||
|
||||
void EX_Servo::update()
|
||||
{
|
||||
if (m_bMoveActive) {
|
||||
if ((millis() - m_nPrevMillis) > m_nTimeStep) {
|
||||
m_nPrevMillis = millis();
|
||||
if (m_nCurrentAngle != m_nTargetAngle) {
|
||||
if (m_nTargetAngle >= m_nOldAngle) {
|
||||
m_nCurrentAngle = m_nCurrentAngle + 1;
|
||||
}
|
||||
else {
|
||||
m_nCurrentAngle = m_nCurrentAngle - 1;
|
||||
}
|
||||
m_Servo.write(m_nCurrentAngle);
|
||||
}
|
||||
else {
|
||||
m_bMoveActive = false;
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Servo::update() move complete"));
|
||||
}
|
||||
if (m_bDetachAfterMove) {
|
||||
m_bDetachTmrActive = true;
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bDetachTmrActive) {
|
||||
if ((millis() - m_nPrevMillis) > m_nDetachTime) {
|
||||
m_bDetachTmrActive = false;
|
||||
m_Servo.detach();
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Servo::update() detach complete"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EX_Servo::beSmart(const String &str)
|
||||
{
|
||||
String level = str.substring(str.indexOf(' ') + 1, str.indexOf(':'));
|
||||
String rate = str.substring(str.indexOf(':') + 1);
|
||||
|
||||
level.trim();
|
||||
rate.trim();
|
||||
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_Servo::beSmart level = "));
|
||||
Serial.println(level);
|
||||
Serial.print(F("EX_Servo::beSmart rate = "));
|
||||
Serial.println(rate);
|
||||
}
|
||||
|
||||
m_nCurrentLevel = int(level.toInt());
|
||||
m_nCurrentRate = long(rate.toInt());
|
||||
m_nOldAngle = m_nCurrentAngle;
|
||||
m_nTargetAngle = map(m_nCurrentLevel, 0, 100, m_nMinLevelAngle, m_nMaxLevelAngle);
|
||||
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_Servo::beSmart OldAngle = "));
|
||||
Serial.println(m_nOldAngle);
|
||||
Serial.print(F("EX_Servo::beSmart TargetAngle = "));
|
||||
Serial.println(m_nTargetAngle);
|
||||
Serial.print(F("EX_Servo::beSmart CurrentRate = "));
|
||||
Serial.println(m_nCurrentRate);
|
||||
}
|
||||
writeAngleToPin();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EX_Servo::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + String(m_nCurrentLevel) + ":" + String(m_nTargetAngle) + ":" + String(m_nCurrentRate));
|
||||
}
|
||||
|
||||
void EX_Servo::setPWMPin(byte pin)
|
||||
{
|
||||
m_nPinPWM = pin;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
102
lib/ST_Anything/EX_Servo.h
Normal file
102
lib/ST_Anything/EX_Servo.h
Normal file
@@ -0,0 +1,102 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Servo.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_Servo is a class which implements the SmartThings/Hubitat "Switch Level" device capability.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Servo executor1(F("servo1"), PIN_SERVO, 90, true, 1000, 0, 180, 2000, 544, 2400);
|
||||
//
|
||||
// st::EX_Servo() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - int startingAngle - OPTIONAL - the value desired for the initial angle of the servo motor (0 to 180, defaults to 90)
|
||||
// - bool detachAfterMove - OPTIONAL - determines if servo motor is powered down after move (defaults to false)
|
||||
// - int servoDetachTime - OPTIONAL - determines how long after the servo is moved that the servo is powered down if detachAfterMove is true (defaults to 1000ms)
|
||||
// - int minLevelAngle - OPTIONAL - servo angle in degrees to map to level 0 (defaults to 0 degrees)
|
||||
// - int maxLevelAngle - OPTIONAL - servo angle in degrees to map to level 100 (defaults to 180 degrees)
|
||||
// - int servoRate - OPTIONAL - initial servo rate in ms/degree (defaults to 2000, used to ensure a gentle move during startup, afterwards comes from SmartThings/Hubitat with each move request)
|
||||
// - int minPulseWidth - OPTIONAL - minimum pulse width in milliseconds, defaults to 544 (see Arduino servo attach() function)
|
||||
// - int maxPulseWidth - OPTIONAL - maximum pulse width in milliseconds, defaults to 2400 (see Arduino servo attach() function)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2018-06-23 Dan Ogorchock Original Creation
|
||||
// 2018-06-24 Dan Ogorchock Since ESP32 does not support SERVO library, exclude all code to prevent compiler error
|
||||
// 2018-08-19 Dan Ogorchock Added feature to optionally allow servo to be powered down after a move
|
||||
// 2019-02-02 Jeff Albers Added Parameters to map servo endpoints, actively control rate of servo motion via duration input to device driver, intializes to level instead of angle
|
||||
// 2019-02-09 Dan Ogorchock Adding Asynchronous Motion to eliminate blocking calls and to allow simultaneous motion across multiple servos
|
||||
// 2019-03-04 Dan Ogorchock Added optional min and max pulse width parameters to allow servo specific adjustments
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_SERVO
|
||||
#define ST_EX_SERVO
|
||||
|
||||
#if not defined(ARDUINO_ARCH_ESP32)
|
||||
|
||||
#include "Executor.h"
|
||||
#include <Servo.h>
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_Servo: public Executor
|
||||
{
|
||||
private:
|
||||
Servo m_Servo; //Servo object
|
||||
byte m_nPinPWM; //Arduino Pin used as a PWM Output for the switch level capability
|
||||
int m_nCurrentLevel; //Servo Level value from SmartThings/Hubitat (0 to 100%)
|
||||
int m_nOldAngle; //starting angle for servo move
|
||||
int m_nTargetAngle; //ending angle for servo move, value mapped to Servo Level (0 to 180 degrees maximum range)
|
||||
int m_nCurrentAngle; //servo angle output while stepping from OldAngle to TargetAngle
|
||||
long m_nCurrentRate; //Servo move Duration value from SmartThings/Hubitat (0 to 10000 milliseconds)
|
||||
long m_nDetachTime; //Servo Detach Time in milliseconds
|
||||
bool m_bDetachAfterMove; //Issue a servo.detach() after servo move is complete
|
||||
int m_nMinLevelAngle; //Angle (0-180 degrees)to map to level 0
|
||||
int m_nMaxLevelAngle; //Angle (0-180 degrees)to map to level 100
|
||||
bool m_bMoveActive; //True if servo move is active (asynchronous motion)
|
||||
bool m_bDetachTmrActive; //True if servo is waiting to power off
|
||||
long m_nTimeStep; //Number of milliseconds per servo motor degree (i.e. rate of change for the servo)
|
||||
long m_nPrevMillis; //Previous millis() value
|
||||
int m_nMinPulseWidth; //Minimum Servo Pulse Width
|
||||
int m_nMaxPulseWidth; //Maximum Servo Pulse Width
|
||||
|
||||
|
||||
void writeAngleToPin(); //function to update the Arduino PWM Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_Servo(const __FlashStringHelper *name, byte pinPWM, int startingAngle = 90, bool detachAfterMove = false, long servoDetachTime = 1000, int minLevelAngle = 0, int maxLevelAngle = 180, int servoRate = 2000, int minPulseWidth = 544, int maxPulseWidth = 2400);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_Servo();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
void update();
|
||||
|
||||
//SmartThings Shield data handler (receives Level and Duration from ST/Hubitat)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud / Hubitat Hub (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getPWMPin() const { return m_nPinPWM; }
|
||||
|
||||
virtual bool getAngle() const { return m_nTargetAngle; } //Angle of the Servo mapped to Level
|
||||
virtual bool getLevel() const { return m_nCurrentLevel; } //Servo Level from ST/Hubitat
|
||||
virtual bool getRate() const { return m_nCurrentRate; } //Duration from ST/Hubitat
|
||||
|
||||
//sets
|
||||
virtual void setPWMPin(byte pin);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
95
lib/ST_Anything/EX_Switch.cpp
Normal file
95
lib/ST_Anything/EX_Switch.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Switch.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: EX_Switch is a class which implements the SmartThings "Switch" device capability.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Switch executor1(F("switch1"), PIN_SWITCH, LOW, true);
|
||||
//
|
||||
// st::EX_Switch() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "EX_Switch.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_Switch::writeStateToPin()
|
||||
{
|
||||
digitalWrite(m_nPin, m_bInvertLogic ? !m_bCurrentState : m_bCurrentState);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_Switch::EX_Switch(const __FlashStringHelper *name, byte pin, bool startingState, bool invertLogic) :
|
||||
Executor(name),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic)
|
||||
{
|
||||
setPin(pin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_Switch::~EX_Switch()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_Switch::init()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
void EX_Switch::beSmart(const String &str)
|
||||
{
|
||||
String s=str.substring(str.indexOf(' ')+1);
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_Switch::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if(s==F("on"))
|
||||
{
|
||||
m_bCurrentState=HIGH;
|
||||
}
|
||||
else if(s==F("off"))
|
||||
{
|
||||
m_bCurrentState=LOW;
|
||||
}
|
||||
|
||||
writeStateToPin();
|
||||
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_Switch::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH?F("on"):F("off")));
|
||||
}
|
||||
|
||||
void EX_Switch::setPin(byte pin)
|
||||
{
|
||||
m_nPin=pin;
|
||||
pinMode(m_nPin, OUTPUT);
|
||||
writeStateToPin();
|
||||
}
|
||||
}
|
||||
69
lib/ST_Anything/EX_Switch.h
Normal file
69
lib/ST_Anything/EX_Switch.h
Normal file
@@ -0,0 +1,69 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Switch.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: EX_Switch is a class which implements the SmartThings "Switch" device capability.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Switch executor1(F("switch1"), PIN_SWITCH, LOW, true);
|
||||
//
|
||||
// st::EX_Switch() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_SWITCH
|
||||
#define ST_EX_SWITCH
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_Switch: public Executor
|
||||
{
|
||||
private:
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
byte m_nPin; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
|
||||
void writeStateToPin(); //function to update the Arduino Digital Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_Switch(const __FlashStringHelper *name, byte pin, bool startingState = LOW, bool invertLogic = false);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_Switch();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getPin() const {return m_nPin;}
|
||||
|
||||
virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
|
||||
|
||||
//sets
|
||||
virtual void setPin(byte pin);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
137
lib/ST_Anything/EX_Switch_Dim.cpp
Normal file
137
lib/ST_Anything/EX_Switch_Dim.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Switch_Dim.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_Switch_Dim is a class which implements the SmartThings "Switch" and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Switch_Dim executor1(F("dimmerSwitch1"), PIN_SWITCH, PIN_LEVEL, LOW, true);
|
||||
//
|
||||
// st::EX_Switch_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-08-30 Dan Ogorchock Adding reporting of 'level'
|
||||
// 2018-12-06 Dan Ogorchock Fixed Comments
|
||||
// 2019-04-10 Dan Ogorchock Corrected analogWrite() call for ESP8266 platform
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "EX_Switch_Dim.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_Switch_Dim::writeStateToPin()
|
||||
{
|
||||
digitalWrite(m_nPinSwitch, m_bInvertLogic ? !m_bCurrentState : m_bCurrentState);
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::writeLevelToPin()
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_ESP32)
|
||||
if (st::Executor::debug) {
|
||||
Serial.println(F("EX_Switch_Dim:: analogWrite not currently supported on ESP32!"));
|
||||
}
|
||||
#elif defined(ARDUINO_ARCH_ESP8266)
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 1023));
|
||||
#else
|
||||
analogWrite(m_nPinPWM, map(m_nCurrentLevel, 0, 100, 0, 255));
|
||||
#endif
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_Switch_Dim::EX_Switch_Dim(const __FlashStringHelper *name, byte pinSwitch, byte pinPWM, bool startingState, bool invertLogic) :
|
||||
Executor(name),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic)
|
||||
{
|
||||
m_nCurrentLevel = startingState == HIGH ? 100 : 0;
|
||||
setSwitchPin(pinSwitch);
|
||||
setPWMPin(pinPWM);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_Switch_Dim::~EX_Switch_Dim()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::init()
|
||||
{
|
||||
//Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
refresh();
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::Executor::debug) {
|
||||
Serial.print(F("EX_Switch_Dim::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if (s == F("on"))
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
}
|
||||
else if (s == F("off"))
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
}
|
||||
else //must be a set level command
|
||||
{
|
||||
s.trim();
|
||||
m_nCurrentLevel = byte(s.toInt());
|
||||
if (m_nCurrentLevel == 0)
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
}
|
||||
}
|
||||
|
||||
writeStateToPin();
|
||||
writeLevelToPin();
|
||||
|
||||
//Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
refresh();
|
||||
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
Everything::sendSmartString(getName() + " " + m_nCurrentLevel);
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::setSwitchPin(byte pin)
|
||||
{
|
||||
m_nPinSwitch = pin;
|
||||
pinMode(m_nPinSwitch, OUTPUT);
|
||||
writeStateToPin();
|
||||
}
|
||||
|
||||
void EX_Switch_Dim::setPWMPin(byte pin)
|
||||
{
|
||||
m_nPinPWM = pin;
|
||||
pinMode(m_nPinPWM, OUTPUT);
|
||||
writeLevelToPin();
|
||||
}
|
||||
}
|
||||
79
lib/ST_Anything/EX_Switch_Dim.h
Normal file
79
lib/ST_Anything/EX_Switch_Dim.h
Normal file
@@ -0,0 +1,79 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_Switch_Dim.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_Switch_Dim is a class which implements the SmartThings "Switch" and "Switch Level" device capabilities.
|
||||
// It inherits from the st::Executor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_Switch_Dim executor1(F("dimmerSwitch1"), PIN_SWITCH, PIN_LEVEL, LOW, true);
|
||||
//
|
||||
// st::EX_Switch_Dim() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pin_pwm - REQUIRED - the Arduino Pin to be used as a pwm output
|
||||
// - bool startingState - OPTIONAL - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - OPTIONAL - determines whether the Arduino Digital Output should use inverted logic
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2016-04-30 Dan Ogorchock Original Creation
|
||||
// 2018-08-14 Dan Ogorchock Modified to avoid compiler errors on ESP32 since it currently does not support "analogWrite()"
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-12-06 Dan Ogorchock Fixed Comments
|
||||
// 2019-04-10 Dan Ogorchock Corrected analogWrite() call for ESP8266 platform
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_EX_SWITCH_DIM
|
||||
#define ST_EX_SWITCH_DIM
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_Switch_Dim: public Executor
|
||||
{
|
||||
private:
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
byte m_nPinSwitch; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
byte m_nPinPWM; //Arduino Pin used as a PWM Output for the switch level capability
|
||||
byte m_nCurrentLevel; //Switch Level value from SmartThings (0 to 100)
|
||||
|
||||
void writeStateToPin(); //function to update the Arduino Digital Output Pin
|
||||
void writeLevelToPin(); //function to update the Arduino PWM Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_Switch_Dim(const __FlashStringHelper *name, byte pinSwitch, byte pinPWM, bool startingState = LOW, bool invertLogic = false);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_Switch_Dim();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output) and the LEVEL (PWM Output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically to ensure state of the switch is up to date in the SmartThings Cloud (in case an event is missed)
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getSwitchPin() const {return m_nPinSwitch;}
|
||||
virtual byte getPWMPin() const { return m_nPinPWM; }
|
||||
|
||||
virtual bool getStatus() const { return m_bCurrentState; } //whether the switch is HIGH or LOW
|
||||
virtual bool getLevel() const { return m_nCurrentLevel; } //Dim Level of the switch
|
||||
|
||||
//sets
|
||||
virtual void setSwitchPin(byte pin);
|
||||
virtual void setPWMPin(byte pin);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
177
lib/ST_Anything/EX_TimedRelayPair.cpp
Normal file
177
lib/ST_Anything/EX_TimedRelayPair.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_TimedRelayPair.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_TimedRelayPair is a class which implements the "Valve" device capability, where output1 opens a valve, and
|
||||
// output2 closes a valve. It features optional automatic-turn-off time delay times for for both outputs.
|
||||
//
|
||||
// It inherits from the st::Executor class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_TimedRelayPair executor1(F("valve1"), PIN_RELAY1, PIN_RELAY2, LOW, true, 1000, 1000);
|
||||
//
|
||||
// st::EX_TimedRelayPair() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinOutput1 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pinOutput2 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "closed", HIGH = "open"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic (e.g. active high versus active low relays)
|
||||
// - long Output1Time - REQUIRED - the number of milliseconds to keep the output1 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - long Output2Time - REQUIRED - the number of milliseconds to keep the output2 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-10-30 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "EX_TimedRelayPair.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void EX_TimedRelayPair::writeStateToPin(byte pin, bool state)
|
||||
{
|
||||
digitalWrite(pin, m_bInvertLogic ? !state : state);
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
EX_TimedRelayPair::EX_TimedRelayPair(const __FlashStringHelper *name, byte pinOutput1, byte pinOutput2, bool startingState, bool invertLogic, unsigned long Output1Time, unsigned long Output2Time) :
|
||||
Executor(name),
|
||||
m_nOutputPin1(pinOutput1),
|
||||
m_nOutputPin2(pinOutput2),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic),
|
||||
m_lOutput1Time(Output1Time),
|
||||
m_lOutput2Time(Output2Time),
|
||||
m_lTimeChanged(0),
|
||||
m_bTimerPending(false)
|
||||
|
||||
{
|
||||
//set pin mode
|
||||
pinMode(m_nOutputPin1, OUTPUT);
|
||||
pinMode(m_nOutputPin2, OUTPUT);
|
||||
//update the digital outputs
|
||||
if (((m_bCurrentState == HIGH) && (m_lOutput1Time > 0)) || ((m_bCurrentState == LOW) && (m_lOutput2Time > 0)))
|
||||
{
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
m_lTimeChanged = millis();
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
}
|
||||
|
||||
//destructor
|
||||
EX_TimedRelayPair::~EX_TimedRelayPair()
|
||||
{
|
||||
}
|
||||
|
||||
void EX_TimedRelayPair::init()
|
||||
{
|
||||
refresh();
|
||||
}
|
||||
|
||||
//update function
|
||||
void EX_TimedRelayPair::update()
|
||||
{
|
||||
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if ((m_bCurrentState == HIGH) && (millis() - m_lTimeChanged >= m_lOutput1Time))
|
||||
{
|
||||
writeStateToPin(m_nOutputPin1, LOW);
|
||||
}
|
||||
else if ((m_bCurrentState == LOW) && (millis() - m_lTimeChanged >= m_lOutput2Time))
|
||||
{
|
||||
writeStateToPin(m_nOutputPin2, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EX_TimedRelayPair::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::Device::debug) {
|
||||
Serial.print(F("EX_TimedRelayPair::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
//if ((s == F("open")) && (m_bCurrentState == LOW))
|
||||
if (s == F("open"))
|
||||
{
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
|
||||
m_bCurrentState = HIGH;
|
||||
|
||||
//Save time turned on
|
||||
m_lTimeChanged = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if ((!m_bTimerPending) && (m_lOutput1Time > 0))
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
//Queue the relay status update the ST Cloud
|
||||
refresh();
|
||||
|
||||
//update the digital outputs
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
}
|
||||
//else if ((s == F("close")) && (m_bCurrentState == HIGH))
|
||||
else if (s == F("close"))
|
||||
{
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
|
||||
m_bCurrentState = LOW;
|
||||
|
||||
//Save time turned on
|
||||
m_lTimeChanged = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if ((!m_bTimerPending) && (m_lOutput2Time > 0))
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
|
||||
//Queue the relay status update the ST Cloud
|
||||
refresh();
|
||||
|
||||
//update the digital outputs
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void EX_TimedRelayPair::refresh()
|
||||
{
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("open") : F("closed")));
|
||||
}
|
||||
|
||||
//void EX_TimedRelayPair::setOutputPin(byte pin)
|
||||
//{
|
||||
// pinMode(pin, OUTPUT);
|
||||
//}
|
||||
|
||||
}
|
||||
84
lib/ST_Anything/EX_TimedRelayPair.h
Normal file
84
lib/ST_Anything/EX_TimedRelayPair.h
Normal file
@@ -0,0 +1,84 @@
|
||||
//******************************************************************************************
|
||||
// File: EX_TimedRelayPair.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: EX_TimedRelayPair is a class which implements the "Valve" device capability, where output1 opens a valve, and
|
||||
// output2 closes a valve. It features optional automatic-turn-off time delay times for for both outputs.
|
||||
//
|
||||
// It inherits from the st::Executor class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::EX_TimedRelayPair executor1(F("valve1"), PIN_RELAY1, PIN_RELAY2, LOW, true, 1000, 1000);
|
||||
//
|
||||
// st::EX_TimedRelayPair() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinOutput1 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pinOutput2 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "closed", HIGH = "open"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic (e.g. active high versus active low relays)
|
||||
// - long Output1Time - REQUIRED - the number of milliseconds to keep the output1 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - long Output2Time - REQUIRED - the number of milliseconds to keep the output2 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-10-30 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_EX_TimedRelayPair_H
|
||||
#define ST_EX_TimedRelayPair_H
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class EX_TimedRelayPair : public Executor //inherits from parent Executor Class
|
||||
{
|
||||
private:
|
||||
|
||||
//following are for the digital output
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
byte m_nOutputPin1; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
byte m_nOutputPin2; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
unsigned long m_lOutput1Time; //number of milliseconds to keep digital output HIGH before automatically turning off
|
||||
unsigned long m_lOutput2Time; //number of milliseconds to keep digital output HIGH before automatically turning off
|
||||
unsigned long m_lTimeChanged; //time when the digital output was last changed
|
||||
bool m_bTimerPending; //true if waiting on relay timer to expire
|
||||
|
||||
void writeStateToPin(byte, bool); //function to update the Arduino Digital Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
EX_TimedRelayPair(const __FlashStringHelper *name, byte pinOutput1, byte pinOutput2, bool startingState = LOW, bool invertLogic = false, unsigned long Output1Time = 1000, unsigned long Output2Time = 1000);
|
||||
|
||||
//destructor
|
||||
virtual ~EX_TimedRelayPair();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
void update();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
//virtual byte getPin() const { return m_nOutputPin; }
|
||||
virtual bool getTimerActive() const { return m_bTimerPending; }
|
||||
virtual bool getStatus() const { return m_bCurrentState; }
|
||||
|
||||
//sets
|
||||
//virtual void setOutputPin(byte pin);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
428
lib/ST_Anything/Everything.cpp
Normal file
428
lib/ST_Anything/Everything.cpp
Normal file
@@ -0,0 +1,428 @@
|
||||
//******************************************************************************************
|
||||
// File: Everything.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Everything is a generic class which essentially acts as the main() routine.
|
||||
// All st::Device type objects are managed by st::Everything. It is responsible for
|
||||
// for calling the correct functions within each object it is responsible for at the
|
||||
// proper time. It handles all initialization of and use of the SmarThings Shield library.
|
||||
//
|
||||
// THere are user-definable settings which will impact the st::Everything class stored in
|
||||
// Constants.h. Please edit Constants.h to adjust these settings.
|
||||
//
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-01-10 Dan Ogorchock Minor improvements to support Door Control Capability
|
||||
// 2015-03-14 Dan Ogorchock Added public setLED() function to control ThingShield LED
|
||||
// 2015-03-28 Dan Ogorchock Added throttling capability to sendStrings to improve success rate of ST Cloud getting the data ("SENDSTRINGS_INTERVAL" is in CONSTANTS.H)
|
||||
// 2017-02-07 Dan Ogorchock Added support for new SmartThings v2.0 library (ThingShield, W5100, ESP8266)
|
||||
// 2017-02-19 Dan Ogorchock Fixed bug in throttling capability
|
||||
// 2017-04-26 Dan Ogorchock Allow each communication method to specify unique ST transmission throttling delay
|
||||
// 2019-02-09 Dan Ogorchock Add update() call to Executors in support of devices like EX_Servo that need a non-blocking mechanism
|
||||
// 2019-02-24 Dan Ogorchock Added new special callOnMsgRcvd2 callback capability. Allows recvd string to be manipulated in the sketch before being processed by Everything.
|
||||
// 2021-01-31 Marcus van Ierssel Improved the automatic refresh to prevent it from blocking other updates.
|
||||
// 2021-05-23 Dan Ogorchock Address EXP8266 v3.0.0 board support package compatibility issue with Strings
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
//#include <Arduino.h>
|
||||
//#include <avr/pgmspace.h>
|
||||
#include "Everything.h"
|
||||
|
||||
long freeRam(); //freeRam() function prototype - useful in determining how much SRAM is available on Arduino
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
extern "C" char* sbrk(int incr);
|
||||
#endif
|
||||
namespace st
|
||||
{
|
||||
|
||||
//private
|
||||
void Everything::updateDevices()
|
||||
{
|
||||
for(unsigned int index=0; index<m_nSensorCount; ++index)
|
||||
{
|
||||
m_Sensors[index]->update();
|
||||
sendStrings();
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i<m_nExecutorCount; ++i)
|
||||
{
|
||||
m_Executors[i]->update();
|
||||
sendStrings();
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ENABLE_SERIAL)
|
||||
void Everything::readSerial()
|
||||
{
|
||||
String message;
|
||||
while(Serial.available()>0)
|
||||
{
|
||||
char c=Serial.read();
|
||||
message+=c;
|
||||
delay(10);
|
||||
}
|
||||
if(message.length()>0)
|
||||
{
|
||||
receiveSmartString(message);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void Everything::sendStrings()
|
||||
{
|
||||
unsigned int index;
|
||||
//Loop through the Return_String buffer and send each "|" delimited string to ST Shield
|
||||
while(Return_String.length()>=1 && Return_String[0]!='|')
|
||||
{
|
||||
index=Return_String.indexOf("|");
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Everything: Sending: "));
|
||||
Serial.println(Return_String.substring(0, index));
|
||||
//Serial.print(F("Everything: getTransmitInterval() = "));
|
||||
//Serial.println(SmartThing->getTransmitInterval());
|
||||
}
|
||||
#ifndef DISABLE_SMARTTHINGS
|
||||
// if (millis() - sendstringsLastMillis < Constants::SENDSTRINGS_INTERVAL)
|
||||
if (millis() - sendstringsLastMillis < SmartThing->getTransmitInterval())
|
||||
{
|
||||
// delay(Constants::SENDSTRINGS_INTERVAL - (millis() - sendstringsLastMillis)); //Added due to slow ST Hub/Cloud Processing. Events were being missed. DGO 2015-03-28
|
||||
delay(SmartThing->getTransmitInterval() - (millis() - sendstringsLastMillis)); //modified to allow different values for each method of communicating to ST cloud. DGO 2017-04-26
|
||||
}
|
||||
SmartThing->send(Return_String.substring(0, index));
|
||||
sendstringsLastMillis = millis();
|
||||
#endif
|
||||
#if defined(ENABLE_SERIAL) && defined(DISABLE_SMARTTHINGS)
|
||||
Serial.println(Return_String.substring(0, index));
|
||||
#endif
|
||||
|
||||
if(callOnMsgSend!=0)
|
||||
{
|
||||
callOnMsgSend(Return_String.substring(0, index));
|
||||
}
|
||||
|
||||
Return_String=Return_String.substring(index+1);
|
||||
}
|
||||
Return_String.remove(0); //clear the Return_String buffer
|
||||
}
|
||||
|
||||
void Everything::refreshDevices()
|
||||
{
|
||||
static int refresh_Executor = 0;
|
||||
static int refresh_Sensor = 0;
|
||||
/*
|
||||
for(unsigned int i=0; i<m_nExecutorCount; ++i)
|
||||
{
|
||||
m_Executors[i]->refresh();
|
||||
sendStrings();
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i<m_nSensorCount; ++i)
|
||||
{
|
||||
m_Sensors[i]->refresh();
|
||||
sendStrings();
|
||||
}
|
||||
*/
|
||||
if (refresh_Executor < m_nExecutorCount) {
|
||||
m_Executors[refresh_Executor]->refresh();
|
||||
sendStrings();
|
||||
refresh_Executor++;
|
||||
refLastMillis = millis() - long(Constants::DEV_REFRESH_INTERVAL) * 1000 + 4 * SmartThing->getTransmitInterval();
|
||||
}
|
||||
else if (refresh_Sensor < m_nSensorCount) {
|
||||
m_Sensors[refresh_Sensor]->refresh();
|
||||
sendStrings();
|
||||
refresh_Sensor++;
|
||||
refLastMillis = millis() - long(Constants::DEV_REFRESH_INTERVAL) * 1000 + 4 * SmartThing->getTransmitInterval();
|
||||
}
|
||||
else {
|
||||
refLastMillis = millis();
|
||||
refresh_Executor = 0;
|
||||
refresh_Sensor = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//public
|
||||
void Everything::init()
|
||||
{
|
||||
Serial.begin(Constants::SERIAL_BAUDRATE);
|
||||
Return_String.reserve(st::Constants::RETURN_STRING_RESERVE); //allocate Return_String buffer one time to prevent Heap Fragmentation. RETURN_STRING_RESERVE is set in Constants.h
|
||||
|
||||
if(debug)
|
||||
{
|
||||
Serial.println(F("Everything: init started"));
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
|
||||
#ifndef DISABLE_SMARTTHINGS
|
||||
SmartThing->init();
|
||||
#endif
|
||||
|
||||
|
||||
if(debug)
|
||||
{
|
||||
Serial.println(F("Everything: init ended"));
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
}
|
||||
|
||||
void Everything::initDevices()
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Serial.println(F("Everything: initDevices started"));
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
|
||||
for(unsigned int index=0; index<m_nSensorCount; ++index)
|
||||
{
|
||||
m_Sensors[index]->init();
|
||||
sendStrings();
|
||||
}
|
||||
|
||||
for(unsigned int index=0; index<m_nExecutorCount; ++index)
|
||||
{
|
||||
m_Executors[index]->init();
|
||||
sendStrings();
|
||||
}
|
||||
|
||||
if(debug)
|
||||
{
|
||||
Serial.println(F("Everything: initDevices ended"));
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
|
||||
refLastMillis = millis(); //avoid immediately refreshing after initialization
|
||||
}
|
||||
|
||||
void Everything::run()
|
||||
{
|
||||
updateDevices(); //call each st::Sensor object to refresh data
|
||||
|
||||
#ifndef DISABLE_SMARTTHINGS
|
||||
SmartThing->run(); //call the ST Shield Library to receive any data from the ST Hub
|
||||
#endif
|
||||
|
||||
#if defined(ENABLE_SERIAL)
|
||||
readSerial(); //read data from the Arduino IDE Serial Monitor window (useful for debugging sometimes)
|
||||
#endif
|
||||
|
||||
sendStrings(); //send any pending updates to ST Cloud
|
||||
|
||||
#ifndef DISABLE_REFRESH //Added new check to allow user to disable REFRESH feature - setting is in Constants.h)
|
||||
if ((bTimersPending == 0) && ((millis() - refLastMillis) >= long(Constants::DEV_REFRESH_INTERVAL) * 1000)) //DEV_REFRESH_INTERVAL is set in Constants.h
|
||||
{
|
||||
//refLastMillis = millis();
|
||||
refreshDevices(); //call each st::Device object to refresh data (this is just a safeguard to ensure the state of the Arduino and the ST Cloud stay in synch should an event be missed)
|
||||
}
|
||||
#endif
|
||||
|
||||
if((debug) && (millis()%60000==0) && (millis()!=lastmillis))
|
||||
{
|
||||
lastmillis = millis();
|
||||
Serial.print(F("Everything: Free Ram = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
}
|
||||
|
||||
bool Everything::sendSmartString(const String &str)
|
||||
{
|
||||
//while(str.length()>1 && str[0]=='|') //get rid of leading pipes (messes up sendStrings()'s parsing technique)
|
||||
//{
|
||||
// str=str.substring(1);
|
||||
//}
|
||||
if((str.length()==1 && str[0]=='|') || str.length()==0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Return_String.length()+str.length()>=Constants::RETURN_STRING_RESERVE)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Serial.print(F("Everything: ERROR: \""));
|
||||
Serial.print(str);
|
||||
Serial.println(F("\" would overflow the Return_String 'buffer'"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
Return_String+=str+"|"; //add the new message to the queue to be sent to ST Shield with a "|" delimiter
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool Everything::sendSmartStringNow(const String &str)
|
||||
{
|
||||
bool queued = sendSmartString(str);
|
||||
if (queued) sendStrings(); //send any pending updates to ST Cloud immediately
|
||||
return queued;
|
||||
}
|
||||
|
||||
Device* Everything::getDeviceByName(const String &str)
|
||||
{
|
||||
for(unsigned int index=0; index<m_nSensorCount; ++index)
|
||||
{
|
||||
if(m_Sensors[index]->getName()==str)
|
||||
return (Device*)m_Sensors[index];
|
||||
}
|
||||
|
||||
for(unsigned int index=0; index<m_nExecutorCount; ++index)
|
||||
{
|
||||
if(m_Executors[index]->getName()==str)
|
||||
return (Device*)m_Executors[index];
|
||||
}
|
||||
|
||||
return 0; //null if no such device present
|
||||
}
|
||||
|
||||
bool Everything::addSensor(Sensor *sensor)
|
||||
{
|
||||
if(m_nSensorCount>=Constants::MAX_SENSOR_COUNT)
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Did not add sensor named "));
|
||||
Serial.print(sensor->getName());
|
||||
Serial.println(F("(You've exceeded maximum number of sensors; edit Constants.h)"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Sensors[m_nSensorCount]=sensor;
|
||||
++m_nSensorCount;
|
||||
}
|
||||
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Everything: adding sensor named "));
|
||||
Serial.println(sensor->getName());
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Everything::addExecutor(Executor *executor)
|
||||
{
|
||||
if(m_nExecutorCount>=Constants::MAX_EXECUTOR_COUNT)
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Did not add executor named "));
|
||||
Serial.print(executor->getName());
|
||||
Serial.println(F("(You've exceeded maximum number of executors; edit Constants.h)"));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_Executors[m_nExecutorCount]=executor;
|
||||
++m_nExecutorCount;
|
||||
}
|
||||
|
||||
if(debug)
|
||||
{
|
||||
Serial.print(F("Everything: adding executor named "));
|
||||
Serial.println(executor->getName());
|
||||
Serial.print(F("Everything: Free RAM = "));
|
||||
Serial.println(freeRam());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//friends!
|
||||
void receiveSmartString(String message)
|
||||
{
|
||||
message.trim();
|
||||
if(Everything::debug && message.length()>1)
|
||||
{
|
||||
Serial.print(F("Everything: Received: "));
|
||||
Serial.println(message);
|
||||
}
|
||||
|
||||
if (Everything::callOnMsgRcvd2 != 0)
|
||||
{
|
||||
Everything::callOnMsgRcvd2(message);
|
||||
}
|
||||
|
||||
if (message == "refresh")
|
||||
{
|
||||
Everything::refreshDevices();
|
||||
}
|
||||
else if (message.length() > 1) //ignore empty string messages from the ST Hub
|
||||
{
|
||||
Device *p = Everything::getDeviceByName(message.substring(0, message.indexOf(' ')));
|
||||
if (p != 0)
|
||||
{
|
||||
p->beSmart(message); //pass the incoming SmartThings Shield message to the correct Device's beSmart() routine
|
||||
}
|
||||
}
|
||||
|
||||
if(Everything::callOnMsgRcvd!=0)
|
||||
{
|
||||
Everything::callOnMsgRcvd(message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//initialize static members
|
||||
st::SmartThings* Everything::SmartThing=0; //initialize pointer to null
|
||||
String Everything::Return_String;
|
||||
Sensor* Everything::m_Sensors[Constants::MAX_SENSOR_COUNT];
|
||||
Executor* Everything::m_Executors[Constants::MAX_EXECUTOR_COUNT];
|
||||
byte Everything::m_nSensorCount=0;
|
||||
byte Everything::m_nExecutorCount=0;
|
||||
unsigned long Everything::lastmillis=0;
|
||||
unsigned long Everything::refLastMillis=0;
|
||||
unsigned long Everything::sendstringsLastMillis=0;
|
||||
bool Everything::debug=false;
|
||||
byte Everything::bTimersPending=0; //initialize variable
|
||||
void (*Everything::callOnMsgSend)(const String &msg)=0; //initialize this callback function to null
|
||||
void (*Everything::callOnMsgRcvd)(const String &msg)=0; //initialize this callback function to null
|
||||
void(*Everything::callOnMsgRcvd2)(String &msg) = 0; //initialize this callback function to null
|
||||
|
||||
//SmartThings static members
|
||||
//#ifndef DISABLE_SMARTTHINGS
|
||||
// // Please refer to Constants.h for settings that affect whether a board uses SoftwareSerial or Hardware Serial calls
|
||||
// #if defined(ST_SOFTWARE_SERIAL) //use Software Serial
|
||||
// SmartThingsThingShield Everything::SmartThing(Constants::pinRX, Constants::pinTX, receiveSmartString);
|
||||
// #elif defined(ST_HARDWARE_SERIAL) //use Hardware Serial
|
||||
// SmartThingsThingShield Everything::SmartThing(Constants::SERIAL_TYPE, receiveSmartString);
|
||||
// #endif
|
||||
|
||||
// SmartThingsNetworkState_t Everything::stNetworkState=(SmartThingsNetworkState_t)99; //bogus value for first pass through Everything::updateNetworkState()
|
||||
//#endif
|
||||
}
|
||||
|
||||
//freeRam() function - useful in determining how much SRAM is available on Arduino
|
||||
long freeRam()
|
||||
{
|
||||
#if defined(ARDUINO_ARCH_AVR)
|
||||
extern int __heap_start, *__brkval;
|
||||
int v;
|
||||
return (int)&v - (__brkval == 0 ? (int)&__heap_start : (int)__brkval);
|
||||
#elif defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
return ESP.getFreeHeap();
|
||||
#elif defined(ARDUINO_ARCH_SAMD)
|
||||
char top;
|
||||
return &top - reinterpret_cast<char*>(sbrk(0));
|
||||
#else
|
||||
return -1;
|
||||
#endif // !
|
||||
|
||||
|
||||
}
|
||||
|
||||
109
lib/ST_Anything/Everything.h
Normal file
109
lib/ST_Anything/Everything.h
Normal file
@@ -0,0 +1,109 @@
|
||||
//******************************************************************************************
|
||||
// File: Everything.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Everything is a static class which essentially acts as the main() routine for
|
||||
// a ST_Anything application.
|
||||
// -All st::Device type objects (Sensors and Executors) are managed by st::Everything.
|
||||
// -It calls the correct functions within each object it
|
||||
// is responsible for at the proper time.
|
||||
// -It handles all initialization of and use of the SmarThings Shield library.
|
||||
//
|
||||
// User-definable settings which will impact the st::Everything class are stored in
|
||||
// Constants.h. Please edit Constants.h to adjust these settings.
|
||||
//
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-01-10 Dan Ogorchock Minor improvements to support Door Control Capability
|
||||
// 2015-03-14 Dan Ogorchock Added public setLED() function to control ThingShield LED
|
||||
// 2015-03-28 Dan Ogorchock Added throttling capability to sendStrings to improve success rate of ST Cloud getting the data ("SENDSTRINGS_INTERVAL" is in CONSTANTS.H)
|
||||
// 2017-02-07 Dan Ogorchock Added support for new SmartThings v2.0 library (ThingShield, W5100, ESP8266)
|
||||
// 2019-02-09 Dan Ogorchock Add update() call to Executors in support of devices like EX_Servo that need a non-blocking mechanism
|
||||
// 2019-02-24 Dan Ogorchock Added new special callOnMsgRcvd2 callback capability. Allows recvd string to be manipulated in the sketch before being processed by Everything.
|
||||
// 2021-05-23 Dan Ogorchock Address EXP8266 v3.0.0 board support package compatibility issue with Strings
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_EVERYTHING_H
|
||||
#define ST_EVERYTHING_H
|
||||
|
||||
//#include "Arduino.h"
|
||||
#include "Constants.h"
|
||||
#include "Sensor.h"
|
||||
#include "Executor.h"
|
||||
|
||||
#include "SmartThings.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
SmartThingsCallout_t receiveSmartString; //function prototype for ST Library callback function
|
||||
|
||||
class Everything
|
||||
{
|
||||
private:
|
||||
static Sensor* m_Sensors[Constants::MAX_SENSOR_COUNT]; //array of Sensor objects that st::Everything will keep track of
|
||||
static byte m_nSensorCount; //number of st::Sensor objects added to st::Everything in your sketch Setup() routine
|
||||
|
||||
static Executor* m_Executors[Constants::MAX_EXECUTOR_COUNT]; //array of Executor objects that st::Everything will keep track of
|
||||
static byte m_nExecutorCount;//number of st::Executor objects added to st::Everything in your sketch Setup() routine
|
||||
|
||||
|
||||
//static SmartThingsNetworkState_t stNetworkState;
|
||||
|
||||
//static void updateNetworkState(); //keeps track of the current ST Shield to Hub network status
|
||||
static void updateDevices(); //simply calls update on all the sensors
|
||||
static void sendStrings(); //sends all updates from the devices in Return_String
|
||||
static unsigned long sendstringsLastMillis; //keep track of how long since last time we sent data to ST Cloud, to enable throttling
|
||||
|
||||
static unsigned long lastmillis; //used to keep track of last time run() has output freeRam() info
|
||||
|
||||
//stuff for refreshing Devices
|
||||
static unsigned long refLastMillis; //used to keep track of last time run() has called refreshDevices()
|
||||
static void refreshDevices(); //simply calls refresh on all the Devices
|
||||
|
||||
#ifdef ENABLE_SERIAL
|
||||
static void readSerial(); //reads data from Arduino IDE Serial Monitor, if enabled in Constants.h
|
||||
#endif
|
||||
|
||||
static String Return_String; //static buffer for string data queued for transfer to SmartThings Shield - prevents dynamic memory allocation heap fragmentation
|
||||
|
||||
public:
|
||||
static void init(); //st::Everything initialization routine called in your sketch setup() routine
|
||||
static void initDevices(); //calls the init() routine of every object added to st::Everything in your sketch setup() routine
|
||||
static void run(); //st::Everything initialization routine called in your sketch loop() routine
|
||||
|
||||
static bool sendSmartString(const String &str); //sendSmartString() may edit the string reference passed to it - queues messages - preferable
|
||||
static bool sendSmartStringNow(const String &str); //sendSmartStringNow() may edit the string reference passed to it - sends messages immediate - only for special circumstances
|
||||
|
||||
static Device* getDeviceByName(const String &str); //returns pointer to Device object by name
|
||||
|
||||
static bool addSensor(Sensor *sensor); //adds a Sensor object to st::Everything's m_Sensors[] array - called in your sketch setup() routine
|
||||
static bool addExecutor(Executor *executor);//adds a Executor object to st::Everything's m_Executors[] array - called in your sketch setup() routine
|
||||
|
||||
static byte bTimersPending; //number of time critical events in progress - if > 0, do NOT perform refreshDevices() routine
|
||||
|
||||
static bool debug; //debug flag to determine if debug print statements are executed - set value in your sketch's setup() routine
|
||||
|
||||
static void (*callOnMsgSend)(const String &msg); //If this function pointer is assigned, the function it points to will be called upon every time a string is sent to the cloud.
|
||||
static void (*callOnMsgRcvd)(const String &msg); //If this function pointer is assigned, the function it points to will be called upon every time a string is received from the cloud.
|
||||
static void(*callOnMsgRcvd2)(String &msg); //If this function pointer is assigned, the function it points to will be called upon every time a string is received from the cloud.
|
||||
|
||||
//SmartThings Object
|
||||
#ifndef DISABLE_SMARTTHINGS
|
||||
static st::SmartThings* SmartThing; //SmartThings Shield Library object
|
||||
#endif
|
||||
|
||||
friend SmartThingsCallout_t receiveSmartString; //callback function to act on data received from SmartThings Shield - called from SmartThings Shield Library
|
||||
|
||||
//SmartThings Object
|
||||
//#ifndef DISABLE_SMARTTHINGS
|
||||
// static void setLED(uint8_t red, uint8_t green, uint8_t blue) {SmartThing.shieldSetLED(red, green, blue);}
|
||||
//#endif
|
||||
};
|
||||
}
|
||||
#endif
|
||||
59
lib/ST_Anything/Executor.cpp
Normal file
59
lib/ST_Anything/Executor.cpp
Normal file
@@ -0,0 +1,59 @@
|
||||
//******************************************************************************************
|
||||
// File: Executor.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Executor is a generic class which inherits from st::Device. This is the
|
||||
// parent class for the st::EX_Switch class.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2019-02-09 Dan Ogorchock Added update() function
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
|
||||
#include "Executor.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace
|
||||
st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
|
||||
//public
|
||||
//constructor
|
||||
Executor::Executor(const __FlashStringHelper *name):
|
||||
Device(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
Executor::~Executor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Executor::init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Executor::update()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
bool Executor::debug=false;
|
||||
|
||||
}
|
||||
54
lib/ST_Anything/Executor.h
Normal file
54
lib/ST_Anything/Executor.h
Normal file
@@ -0,0 +1,54 @@
|
||||
//******************************************************************************************
|
||||
// File: Executor.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Executor is a generic class which inherits from st::Device. This is the
|
||||
// parent class for the st::EX_Switch class.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2019-02-09 Dan Ogorchock Added update() function
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_EXECUTOR_H
|
||||
#define ST_EXECUTOR_H
|
||||
|
||||
#include "Device.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class Executor: public Device
|
||||
{
|
||||
private:
|
||||
//Inherits private members from parent st::Device class
|
||||
|
||||
public:
|
||||
//constructor
|
||||
Executor(const __FlashStringHelper *name);
|
||||
|
||||
//destructor
|
||||
virtual ~Executor();
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
virtual void update();
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
static bool debug;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
117
lib/ST_Anything/IS_Button.cpp
Normal file
117
lib/ST_Anything/IS_Button.cpp
Normal file
@@ -0,0 +1,117 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Button.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Button is a class which implements the SmartThings "Contact Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Button sensor(F("button1"), PIN_BUTTON1, 1000, LOW, true, 500);
|
||||
//
|
||||
// st::IS_Button() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - should be "button1", "button2", "button3", etc...
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - long reqNumMillisHeld - Required - number of milliseconds required needed to detect a "Held" condition versus a "Pushed" (default = 1000)
|
||||
// - bool iState - OPTIONAL - LOW or HIGH - determines which value indicates the interrupt is true (default = HIGH)
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP (default - true)
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false triggers) (default = 500)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2017-03-25 Dan Original Creation
|
||||
// 2019-09-7 Dan Ogorchock Send Button 'init' messages for automatic setting of numberOfButtons attribute
|
||||
// 2020-09-19 Dan Ogorchock Modified to not wait until button is released to send 'held' event, also added released events
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_Button.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Button::IS_Button(const __FlashStringHelper *name, byte pin, long reqNumMillisHeld, bool iState, bool internalPullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, internalPullup, numReqCounts), //use parent class' constructor
|
||||
m_lreqNumMillisHeld(reqNumMillisHeld)
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Button::~IS_Button()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Button::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
//m_lTimeBtnPressed = 0;
|
||||
refresh();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept up yo date. HOWEVER, not useful for the IS_Button.
|
||||
void IS_Button::refresh()
|
||||
{
|
||||
//Send 'init' message to allow Parent Driver to set numberOfButtons attribute automatically
|
||||
Everything::sendSmartString(getName() + F(" init"));
|
||||
}
|
||||
|
||||
void IS_Button::update()
|
||||
{
|
||||
InterruptSensor::update();
|
||||
|
||||
if (getStatus())
|
||||
{
|
||||
if (((millis() - m_lTimeBtnPressed) >= m_lreqNumMillisHeld) && (!m_bHeldSent))
|
||||
{
|
||||
m_bHeldSent = true;
|
||||
//add the "held" event to the buffer to be queued for transfer to SmartThings
|
||||
Everything::sendSmartString(getName() + F(" held"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void IS_Button::runInterrupt()
|
||||
{
|
||||
//Capture time of button down event so we can figure it whether to send "pushed" or "held" on button release
|
||||
m_lTimeBtnPressed = millis();
|
||||
|
||||
//Serial.println("IS_Button: in runInterrupt()");
|
||||
}
|
||||
|
||||
void IS_Button::runInterruptEnded()
|
||||
{
|
||||
//Serial.println("IS_Button: in runInterruptEnded()");
|
||||
//Serial.println(millis());
|
||||
//Serial.println(m_lTimeBtnPressed);
|
||||
//Serial.println(m_lreqNumMillisHeld);
|
||||
|
||||
if (!m_bFirstRun) //Prevent sending data to SmartThings during initial startup
|
||||
{
|
||||
if ((millis() - m_lTimeBtnPressed) < m_lreqNumMillisHeld)
|
||||
{
|
||||
//immediately send the "pushed" event to the Hub (to make sure it arrives before the 'released' event)
|
||||
Everything::sendSmartStringNow(getName() + F(" pushed"));
|
||||
}
|
||||
//add the "released" event to the buffer to be queued for transfer to Hub
|
||||
Everything::sendSmartString(getName() + F(" released"));
|
||||
|
||||
m_bHeldSent = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_bFirstRun = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
68
lib/ST_Anything/IS_Button.h
Normal file
68
lib/ST_Anything/IS_Button.h
Normal file
@@ -0,0 +1,68 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Button.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Button is a class which implements the SmartThings "Contact Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Button sensor(F("button1"), PIN_BUTTON1, 1000, LOW, true, 500);
|
||||
//
|
||||
// st::IS_Button() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - should be "button1", "button2", "button3", etc...
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - long reqNumMillisHeld - Required - number of milliseconds required needed to detect a "Held" condition versus a "Pushed" (default = 1000)
|
||||
// - bool iState - OPTIONAL - LOW or HIGH - determines which value indicates the interrupt is true (default = HIGH)
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP (default - true)
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false triggers) (default = 500)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2017-03-25 Dan Ogorchock Original Creation
|
||||
// 2020-09-19 Dan Ogorchock Modified to not wait until button is released to send 'held' event, also added released events
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_BUTTON_H
|
||||
#define ST_IS_BUTTON_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Button: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
unsigned long m_lTimeBtnPressed; //time when the digital input went high
|
||||
unsigned long m_lreqNumMillisHeld; //amount of time required to trigger "held" instead of "pushed"
|
||||
bool m_bFirstRun = true; //used to prevent sending inadvertent button pushed/held message on startup
|
||||
bool m_bHeldSent = false; //used to prevent sending multiple 'held' messages
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Button(const __FlashStringHelper *name, byte pin, long reqNumMillisHeld = 1000, bool iState = LOW, bool internalPullup = true, long numReqCounts = 500); //(defaults to using internal pullup resistors)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Button();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept up to date. Not used for IS_Button.
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
//override update method
|
||||
virtual void update();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
73
lib/ST_Anything/IS_CarbonMonoxide.cpp
Normal file
73
lib/ST_Anything/IS_CarbonMonoxide.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_CarbonMonoxide.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Smoke is a class which implements the SmartThings "Carbon Monoxide Detector" device capability.
|
||||
// It inherits from the st::IS_Smoke class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_CarbonMonoxide sensor6("carbonMonoxide1", PIN_CO, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_CarbonMonoxide() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-04-19 Dan & Daniel Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_CarbonMonoxide.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_CarbonMonoxide::IS_CarbonMonoxide(const __FlashStringHelper *name, byte pin, bool iState, bool pullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, pullup, numReqCounts) //use parent class' constructor
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_CarbonMonoxide::~IS_CarbonMonoxide()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_CarbonMonoxide::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void IS_CarbonMonoxide::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" clear") : F(" detected")));
|
||||
}
|
||||
|
||||
void IS_CarbonMonoxide::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" clear"));
|
||||
}
|
||||
|
||||
void IS_CarbonMonoxide::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" detected"));
|
||||
}
|
||||
|
||||
}
|
||||
63
lib/ST_Anything/IS_CarbonMonoxide.h
Normal file
63
lib/ST_Anything/IS_CarbonMonoxide.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_CarbonMonoxide.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Smoke is a class which implements the SmartThings "Carbon Monoxide Detector" device capability.
|
||||
// It inherits from the st::IS_Smoke class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_CarbonMonoxide sensor6("carbonMonoxide1", PIN_CO, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_CarbonMonoxide() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-04-19 Dan & Daniel Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_CARBONMONOXIDE_H
|
||||
#define ST_IS_CARBONMONOXIDE_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_CarbonMonoxide: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent IS_Smoke Class
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_CarbonMonoxide(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_CarbonMonoxide();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
74
lib/ST_Anything/IS_Contact.cpp
Normal file
74
lib/ST_Anything/IS_Contact.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Contact.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Contact is a class which implements the SmartThings "Contact Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Contact sensor6(F("contact1"), PIN_CONTACT, HIGH, true, 500);
|
||||
//
|
||||
// st::IS_Contact() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_Contact.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Contact::IS_Contact(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, internalPullup, numReqCounts) //use parent class' constructor
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Contact::~IS_Contact()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Contact::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void IS_Contact::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" closed") : F(" open")));
|
||||
}
|
||||
|
||||
void IS_Contact::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" closed"));
|
||||
}
|
||||
|
||||
void IS_Contact::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" open"));
|
||||
}
|
||||
|
||||
}
|
||||
64
lib/ST_Anything/IS_Contact.h
Normal file
64
lib/ST_Anything/IS_Contact.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Contact.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Contact is a class which implements the SmartThings "Contact Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Contact sensor6(F("contact1"), PIN_CONTACT, HIGH, true, 500);
|
||||
//
|
||||
// st::IS_Contact() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_CONTACT_H
|
||||
#define ST_IS_CONTACT_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Contact: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Contact(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Contact();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
162
lib/ST_Anything/IS_DoorControl.cpp
Normal file
162
lib/ST_Anything/IS_DoorControl.cpp
Normal file
@@ -0,0 +1,162 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_DoorControl.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_DoorControl is a class which implements the SmartThings "Door Control" device capability. It features
|
||||
// an automatic-turn-off time delay for a relay to actuate a button press. This is useful for controlling
|
||||
// a garage door. Use the input to monitor a magnetic door contact sensor. Use the output to control a relay to
|
||||
// "press the garage door button" to open/close the garage door.
|
||||
//
|
||||
// It inherits from the st::InterruptSensor class and clones much from the st::Executor Class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_DoorControl sensor3(F("doorControl1"), PIN_CONTACT_DOOR_1, LOW, true, PIN_RELAY_DOOR_1, LOW, true, 1000, 1000, true);
|
||||
//
|
||||
// st::IS_DoorControl() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinInput - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - REQUIRED - true == INTERNAL_PULLUP
|
||||
// - byte pinOutput - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic
|
||||
// - long delayTime - REQUIRED - the number of milliseconds to keep the output on
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
// - bool useMomentary - OPTIONAL - use momentary output (true) or standard switch (false) (defaults to true)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-07 Dan Ogorchock Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-11-07 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2019-07-24 Dan Ogorchock Added parameter to use output as a simple switch instead of momentary output
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_DoorControl.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void IS_DoorControl::writeStateToPin()
|
||||
{
|
||||
digitalWrite(m_nOutputPin, m_bInvertLogic ? !m_bCurrentState : m_bCurrentState);
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_DoorControl::IS_DoorControl(const __FlashStringHelper *name, byte pinInput, bool iState, bool pullup, byte pinOutput, bool startingState, bool invertLogic, unsigned long delayTime, long numReqCounts, bool useMomentary) :
|
||||
InterruptSensor(name, pinInput, iState, pullup, numReqCounts), //use parent class' constructor
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic),
|
||||
m_lDelayTime(delayTime),
|
||||
m_bUseMomentary(useMomentary),
|
||||
m_lTimeTurnedOn(0),
|
||||
m_bTimerPending(false)
|
||||
{
|
||||
setOutputPin(pinOutput);
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_DoorControl::~IS_DoorControl()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_DoorControl::init()
|
||||
{
|
||||
//get current status of contact sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//update function
|
||||
void IS_DoorControl::update()
|
||||
{
|
||||
if (m_bTimerPending) {
|
||||
//Turn off digital output if timer has expired
|
||||
if ((m_bCurrentState == HIGH) && (millis() - m_lTimeTurnedOn >= m_lDelayTime))
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
writeStateToPin();
|
||||
//Decrement number of active timers
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
}
|
||||
//check to see if input pin has changed state
|
||||
InterruptSensor::update();
|
||||
}
|
||||
|
||||
void IS_DoorControl::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::InterruptSensor::debug) {
|
||||
Serial.print(F("IS_ContactRelay::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
if ( (s == F("on")) || (m_bUseMomentary && (s == F("off"))))
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
|
||||
if (m_bUseMomentary) {
|
||||
//Save time turned on
|
||||
m_lTimeTurnedOn = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if (!m_bTimerPending)
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
}
|
||||
if (m_bUseMomentary) {
|
||||
//Queue the door status update the ST Cloud
|
||||
Everything::sendSmartStringNow(getName() + (getStatus() ? F(" opening") : F(" closing")));
|
||||
}
|
||||
}
|
||||
else if (s == F("off"))
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
|
||||
//Decrement number of active timers
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
|
||||
//update the digital output
|
||||
writeStateToPin();
|
||||
}
|
||||
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void IS_DoorControl::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" closed") : F(" open")));
|
||||
}
|
||||
|
||||
void IS_DoorControl::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" closed"));
|
||||
}
|
||||
|
||||
void IS_DoorControl::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" open"));
|
||||
}
|
||||
|
||||
void IS_DoorControl::setOutputPin(byte pin)
|
||||
{
|
||||
m_nOutputPin = pin;
|
||||
pinMode(m_nOutputPin, OUTPUT);
|
||||
writeStateToPin();
|
||||
}
|
||||
|
||||
}
|
||||
97
lib/ST_Anything/IS_DoorControl.h
Normal file
97
lib/ST_Anything/IS_DoorControl.h
Normal file
@@ -0,0 +1,97 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_DoorControl.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_DoorControl is a class which implements the SmartThings "Door Control" device capability. It features
|
||||
// an automatic-turn-off time delay for a relay to actuate a button press. This is useful for controlling
|
||||
// a garage door. Use the input to monitor a magnetic door contact sensor. Use the output to control a relay to
|
||||
// "press the garage door button" to open/close the garage door.
|
||||
//
|
||||
// It inherits from the st::InterruptSensor class and clones much from the st::Executor Class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_DoorControl sensor3(F("doorControl1"), PIN_CONTACT_DOOR_1, LOW, true, PIN_RELAY_DOOR_1, LOW, true, 1000, 1000, true);
|
||||
//
|
||||
// st::IS_DoorControl() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinInput - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - REQUIRED - true == INTERNAL_PULLUP
|
||||
// - byte pinOutput - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic
|
||||
// - long delayTime - REQUIRED - the number of milliseconds to keep the output on
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
// - bool useMomentary - OPTIONAL - use momentary output (true) or standard switch (false) (defaults to true)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-07 Dan Ogorchock Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2018-11-07 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2019-07-24 Dan Ogorchock Added parameter to use output as a simple switch instead of momentary output
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_DOORCONTROL_H
|
||||
#define ST_IS_DOORCONTROL_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_DoorControl : public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class for the Contact Sensor
|
||||
|
||||
//following are for the digital output
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
bool m_bUseMomentary; //determines whether the output should be momentary or simple switch
|
||||
byte m_nOutputPin; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
unsigned long m_lDelayTime; //number of milliseconds to keep digital output active before automatically turning off
|
||||
unsigned long m_lTimeTurnedOn; //time when the digital output was turned on
|
||||
bool m_bTimerPending; //true if waiting on relay timer to expire
|
||||
|
||||
void writeStateToPin(); //function to update the Arduino Digital Output Pin
|
||||
|
||||
|
||||
public:
|
||||
//constructor - momentary output - called in your sketch's global variable declaration section
|
||||
IS_DoorControl(const __FlashStringHelper *name, byte pinInput, bool iState, bool pullup, byte pinOutput, bool startingState, bool invertLogic, unsigned long delayTime, long numReqCounts = 0, bool useMomentary = true);
|
||||
|
||||
//destructor
|
||||
virtual ~IS_DoorControl();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
void update();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
//gets
|
||||
virtual byte getPin() const { return m_nOutputPin; }
|
||||
|
||||
//sets
|
||||
virtual void setOutputPin(byte pin);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
206
lib/ST_Anything/IS_LatchingRelaySwitch.cpp
Normal file
206
lib/ST_Anything/IS_LatchingRelaySwitch.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_LatchingRelaySwitch.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: IS_LatchingRelaySwitch is a class which implements the "Valve" device capability, where output1 opens a valve, and
|
||||
// output2 closes a valve. It features optional automatic-turn-off time delay times for for both outputs.
|
||||
//
|
||||
// It inherits from the st::InterruptSensor class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_LatchingRelaySwitch sensor1(F("switch1"), PIN_INPUT, HIGH, true, 500, PIN_RELAY1, PIN_RELAY2, LOW, true, 1000, 1000);
|
||||
//
|
||||
// st::IS_LatchingRelaySwitch() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinInput - REQUIRED - the Arduino Pin to be used as a digital input to determine the switch state of latching relay
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - REQUIRED - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - REQUIRED - number of counts before changing state of input (prevent false alarms)
|
||||
// - byte pinOutput1 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pinOutput2 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "closed", HIGH = "open"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic (e.g. active high versus active low relays)
|
||||
// - long Output1Time - REQUIRED - the number of milliseconds to keep the output1 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - long Output2Time - REQUIRED - the number of milliseconds to keep the output2 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - bool initializeOutputs - OPTIONAL - determines if the digital outputs are activated during initialization/startup, defaults to 'false'
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2020-06-26 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_LatchingRelaySwitch.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void IS_LatchingRelaySwitch::writeStateToPin(byte pin, bool state)
|
||||
{
|
||||
digitalWrite(pin, m_bInvertLogic ? !state : state);
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_LatchingRelaySwitch::IS_LatchingRelaySwitch(const __FlashStringHelper *name, byte pinInput, bool iState, bool internalPullup, long numReqCounts, byte pinOutput1, byte pinOutput2, bool startingState, bool invertLogic, unsigned long Output1Time, unsigned long Output2Time, bool initializeOutputs) :
|
||||
InterruptSensor(name, pinInput, iState, internalPullup, numReqCounts), //use parent class' constructor,
|
||||
m_nOutputPin1(pinOutput1),
|
||||
m_nOutputPin2(pinOutput2),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic),
|
||||
m_lOutput1Time(Output1Time),
|
||||
m_lOutput2Time(Output2Time),
|
||||
m_lTimeChanged(0),
|
||||
m_bTimerPending(false)
|
||||
|
||||
{
|
||||
//set pin mode
|
||||
pinMode(m_nOutputPin1, OUTPUT);
|
||||
pinMode(m_nOutputPin2, OUTPUT);
|
||||
|
||||
if (initializeOutputs)
|
||||
{
|
||||
//update the digital outputs
|
||||
if (((m_bCurrentState == HIGH) && (m_lOutput1Time > 0)) || ((m_bCurrentState == LOW) && (m_lOutput2Time > 0)))
|
||||
{
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
m_lTimeChanged = millis();
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Make sure both digital outputs are 'off' if initializeOutputs == false
|
||||
writeStateToPin(m_nOutputPin1, LOW);
|
||||
writeStateToPin(m_nOutputPin2, LOW);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_LatchingRelaySwitch::~IS_LatchingRelaySwitch()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_LatchingRelaySwitch::init()
|
||||
{
|
||||
//get current status of switch by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
//refresh();
|
||||
}
|
||||
|
||||
//update function
|
||||
void IS_LatchingRelaySwitch::update()
|
||||
{
|
||||
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if ((m_bCurrentState == HIGH) && (millis() - m_lTimeChanged >= m_lOutput1Time))
|
||||
{
|
||||
writeStateToPin(m_nOutputPin1, LOW);
|
||||
}
|
||||
else if ((m_bCurrentState == LOW) && (millis() - m_lTimeChanged >= m_lOutput2Time))
|
||||
{
|
||||
writeStateToPin(m_nOutputPin2, LOW);
|
||||
}
|
||||
}
|
||||
|
||||
//make sure to call the parent class' update() since we overrode it for the above timer logic
|
||||
InterruptSensor::update();
|
||||
}
|
||||
|
||||
void IS_LatchingRelaySwitch::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::Device::debug) {
|
||||
Serial.print(F("IS_LatchingRelaySwitch::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
|
||||
//if ((s == F("open")) && (m_bCurrentState == LOW))
|
||||
if (s == F("on"))
|
||||
{
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
|
||||
m_bCurrentState = HIGH;
|
||||
|
||||
//Save time turned on
|
||||
m_lTimeChanged = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if ((!m_bTimerPending) && (m_lOutput1Time > 0))
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
//Queue the relay status update the ST Cloud
|
||||
//refresh();
|
||||
|
||||
//update the digital outputs
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
}
|
||||
//else if ((s == F("close")) && (m_bCurrentState == HIGH))
|
||||
else if (s == F("off"))
|
||||
{
|
||||
if (m_bTimerPending)
|
||||
{
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
}
|
||||
|
||||
m_bCurrentState = LOW;
|
||||
|
||||
//Save time turned on
|
||||
m_lTimeChanged = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if ((!m_bTimerPending) && (m_lOutput2Time > 0))
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
|
||||
//Queue the relay status update the Hub
|
||||
//refresh();
|
||||
|
||||
//update the digital outputs
|
||||
writeStateToPin(m_nOutputPin1, m_bCurrentState);
|
||||
writeStateToPin(m_nOutputPin2, !m_bCurrentState);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure Hub is kept consistent with the state of the contact sensor
|
||||
void IS_LatchingRelaySwitch::refresh()
|
||||
{
|
||||
//Queue the relay status update the Hub
|
||||
//Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" off") : F(" on")));
|
||||
}
|
||||
|
||||
void IS_LatchingRelaySwitch::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" off"));
|
||||
}
|
||||
|
||||
void IS_LatchingRelaySwitch::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" on"));
|
||||
}
|
||||
|
||||
}
|
||||
93
lib/ST_Anything/IS_LatchingRelaySwitch.h
Normal file
93
lib/ST_Anything/IS_LatchingRelaySwitch.h
Normal file
@@ -0,0 +1,93 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_LatchingRelaySwitch.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: IS_LatchingRelaySwitch is a class which implements the "Valve" device capability, where output1 opens a valve, and
|
||||
// output2 closes a valve. It features optional automatic-turn-off time delay times for for both outputs.
|
||||
//
|
||||
// It inherits from the st::InterruptSensor class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_LatchingRelaySwitch sensor1(F("switch1"), PIN_INPUT, HIGH, true, 500, PIN_RELAY1, PIN_RELAY2, LOW, true, 1000, 1000);
|
||||
//
|
||||
// st::IS_LatchingRelaySwitch() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinInput - REQUIRED - the Arduino Pin to be used as a digital input to determine switch the state of latching relay
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - REQUIRED - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - REQUIRED - number of counts before changing state of input (prevent false alarms)
|
||||
// - byte pinOutput1 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - byte pinOutput2 - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "closed", HIGH = "open"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Output should use inverted logic (e.g. active high versus active low relays)
|
||||
// - long Output1Time - REQUIRED - the number of milliseconds to keep the output1 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - long Output2Time - REQUIRED - the number of milliseconds to keep the output2 on, DEFAULTS to 1000 milliseconds, 0 = will stay on
|
||||
// - bool initializeOutputs - OPTIONAL - determines if the digital outputs are activated during initialization/startup, defaults to 'false'
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2020-06-26 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_LatchingRelaySwitch_H
|
||||
#define ST_IS_LatchingRelaySwitch_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_LatchingRelaySwitch : public InterruptSensor //inherits from parent InterruptSensor Class
|
||||
{
|
||||
private:
|
||||
|
||||
//following are for the digital output
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
byte m_nOutputPin1; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
byte m_nOutputPin2; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
unsigned long m_lOutput1Time; //number of milliseconds to keep digital output HIGH before automatically turning off
|
||||
unsigned long m_lOutput2Time; //number of milliseconds to keep digital output HIGH before automatically turning off
|
||||
unsigned long m_lTimeChanged; //time when the digital output was last changed
|
||||
bool m_bTimerPending; //true if waiting on relay timer to expire
|
||||
|
||||
void writeStateToPin(byte, bool); //function to update the Arduino Digital Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_LatchingRelaySwitch(const __FlashStringHelper *name, byte pinInput, bool iState, bool internalPullup, long numReqCounts, byte pinOutput1, byte pinOutput2, bool startingState = LOW, bool invertLogic = false, unsigned long Output1Time = 1000, unsigned long Output2Time = 1000, bool initializeOutputs = false);
|
||||
|
||||
//destructor
|
||||
virtual ~IS_LatchingRelaySwitch();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
void update();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
//gets
|
||||
//virtual byte getPin() const { return m_nOutputPin; }
|
||||
virtual bool getTimerActive() const { return m_bTimerPending; }
|
||||
virtual bool getStatus() const { return m_bCurrentState; }
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
118
lib/ST_Anything/IS_Motion.cpp
Normal file
118
lib/ST_Anything/IS_Motion.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Motion.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Motion is a class which implements the SmartThings "Motion Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Motion sensor5(F("motion1"), PIN_MOTION, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_Motion() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool iState - OPTIONAL - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
// - long inactiveTimeout - OPTIONAL - number of milliseconds motion must be inactive before sending update to hub (default = 0)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2016-09-03 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2017-01-25 Dan Ogorchock Corrected issue with INPUT_PULLUP per request of Jiri Culik
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2020-01-31 Dan Ogorchock Added optional inactivity timeout
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_Motion.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Motion::IS_Motion(const __FlashStringHelper *name, byte pin, bool iState, bool pullup, long numReqCounts, long inactiveTimeout) :
|
||||
InterruptSensor(name, pin, iState, pullup, numReqCounts), //use parent class' constructor
|
||||
calibrated(false),
|
||||
m_inactiveTimeout(inactiveTimeout),
|
||||
m_inactiveTimerRunning(false)
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Motion::~IS_Motion()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Motion::init()
|
||||
{
|
||||
if (debug){
|
||||
Serial.println(F("IS_Motion: 30 second Motion Sensor Calibration Started..."));
|
||||
}
|
||||
//calibrate the PIR Motion Sensor
|
||||
digitalWrite(getInterruptPin(), LOW);
|
||||
timer=millis();
|
||||
//delay(30000);
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the motion sensor
|
||||
void IS_Motion::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" active") : F(" inactive")));
|
||||
}
|
||||
|
||||
void IS_Motion::runInterrupt()
|
||||
{
|
||||
if (m_inactiveTimerRunning == false) {
|
||||
//add the "active" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" active"));
|
||||
}
|
||||
//cancel any inactivity timer that may be running
|
||||
m_inactiveTimerRunning = false;
|
||||
|
||||
}
|
||||
|
||||
void IS_Motion::runInterruptEnded()
|
||||
{
|
||||
//start inactivity timer
|
||||
m_inactiveTimer = millis();
|
||||
m_inactiveTimerRunning = true;
|
||||
}
|
||||
|
||||
void IS_Motion::update()
|
||||
{
|
||||
if (calibrated) {
|
||||
InterruptSensor::update();
|
||||
|
||||
if ((m_inactiveTimerRunning == true) && (millis() > m_inactiveTimer + m_inactiveTimeout)) {
|
||||
m_inactiveTimerRunning = false;
|
||||
//add the "inactive" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" inactive"));
|
||||
}
|
||||
}
|
||||
else
|
||||
if(millis()>timer+30000)
|
||||
{
|
||||
calibrated=true;
|
||||
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
setInterruptPin(getInterruptPin());
|
||||
InterruptSensor::init();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Serial.println(F("IS_Motion: Motion Sensor Calibration Finished"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
76
lib/ST_Anything/IS_Motion.h
Normal file
76
lib/ST_Anything/IS_Motion.h
Normal file
@@ -0,0 +1,76 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Motion.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Motion is a class which implements the SmartThings "Motion Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Motion sensor5(F("motion1"), PIN_MOTION, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_Motion() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool iState - OPTIONAL - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
// - long inactiveTimeout - OPTIONAL - number of milliseconds motion must be inactive before sending update to hub (default = 0)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2016-09-03 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2017-01-25 Dan Ogorchock Corrected issue with INPUT_PULLUP per request of Jiri Culik
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2020-01-31 Dan Ogorchock Added optional inactivity timeout
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_MOTION_H
|
||||
#define ST_IS_MOTION_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Motion: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class
|
||||
|
||||
long timer;
|
||||
bool calibrated;
|
||||
long m_inactiveTimeout;
|
||||
bool m_inactiveTimerRunning;
|
||||
long m_inactiveTimer;
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Motion(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0, long inactiveTimeout = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Motion();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the motion sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
//override update method
|
||||
virtual void update();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
72
lib/ST_Anything/IS_Presence.cpp
Normal file
72
lib/ST_Anything/IS_Presence.cpp
Normal file
@@ -0,0 +1,72 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Presence.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Presence is a class which implements the SmartThings "Presence Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Presence sensor1(F("presence1"), PIN_PRESENCE, LOW, true, 5000);
|
||||
//
|
||||
// st::IS_Presence() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-10-12 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_Presence.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Presence::IS_Presence(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, internalPullup, numReqCounts) //use parent class' constructor
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Presence::~IS_Presence()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Presence::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the presence sensor
|
||||
void IS_Presence::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" present") : F(" notpresent")));
|
||||
}
|
||||
|
||||
void IS_Presence::runInterrupt()
|
||||
{
|
||||
//add the "present" event to the buffer to be queued for transfer to Hubitat/SmartThings
|
||||
Everything::sendSmartString(getName() + F(" present"));
|
||||
}
|
||||
|
||||
void IS_Presence::runInterruptEnded()
|
||||
{
|
||||
//add the "notpresent" event to the buffer to be queued for transfer to Hubitat/SmartThings
|
||||
Everything::sendSmartString(getName() + F(" notpresent"));
|
||||
}
|
||||
|
||||
}
|
||||
62
lib/ST_Anything/IS_Presence.h
Normal file
62
lib/ST_Anything/IS_Presence.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Presence.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Presence is a class which implements the SmartThings "Presence Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Presence sensor1(F("presence1"), PIN_PRESENCE, LOW, true, 5000);
|
||||
//
|
||||
// st::IS_Presence() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-10-12 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_PRESENCE_H
|
||||
#define ST_IS_PRESENCE_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Presence: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Presence(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Presence();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the presence sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
75
lib/ST_Anything/IS_Smoke.cpp
Normal file
75
lib/ST_Anything/IS_Smoke.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Smoke.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Smoke is a class which implements the SmartThings "Smoke Detector" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::IS_Smoke sensor6(F("smoke1"), PIN_SMOKE, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_Smoke() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-11-04 Dan Ogorchock Updated Comments
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "IS_Smoke.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Smoke::IS_Smoke(const __FlashStringHelper *name, byte pin, bool iState, bool pullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, pullup, numReqCounts) //use parent class' constructor
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Smoke::~IS_Smoke()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Smoke::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void IS_Smoke::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" clear") : F(" detected")));
|
||||
}
|
||||
|
||||
void IS_Smoke::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" clear"));
|
||||
}
|
||||
|
||||
void IS_Smoke::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the ST Shield
|
||||
Everything::sendSmartString(getName() + F(" detected"));
|
||||
}
|
||||
|
||||
}
|
||||
65
lib/ST_Anything/IS_Smoke.h
Normal file
65
lib/ST_Anything/IS_Smoke.h
Normal file
@@ -0,0 +1,65 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Smoke.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Smoke is a class which implements the SmartThings "Smoke Detector" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::IS_Smoke sensor6(F("smoke1"), PIN_SMOKE, HIGH, false, 500);
|
||||
//
|
||||
// st::IS_Smoke() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Ogorchock Added optional "numReqCounts" constructor argument/capability
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-11-04 Dan Ogorchock Updated Comments
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_SMOKE_H
|
||||
#define ST_IS_SMOKE_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Smoke: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Smoke(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Smoke();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
73
lib/ST_Anything/IS_Water.cpp
Normal file
73
lib/ST_Anything/IS_Water.cpp
Normal file
@@ -0,0 +1,73 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Water.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Water is a class which implements the Hubitat "Water Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Water sensor6(F("water1"), PIN_WATER, HIGH, true, 500);
|
||||
//
|
||||
// st::IS_Water() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2020-06-30 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
|
||||
#include "IS_Water.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor
|
||||
IS_Water::IS_Water(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup, long numReqCounts) :
|
||||
InterruptSensor(name, pin, iState, internalPullup, numReqCounts) //use parent class' constructor
|
||||
{
|
||||
}
|
||||
|
||||
//destructor
|
||||
IS_Water::~IS_Water()
|
||||
{
|
||||
}
|
||||
|
||||
void IS_Water::init()
|
||||
{
|
||||
//get current status of motion sensor by calling parent class's init() routine - no need to duplicate it here!
|
||||
InterruptSensor::init();
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure the Hub is kept consistent with the state of the water sensor
|
||||
void IS_Water::refresh()
|
||||
{
|
||||
Everything::sendSmartString(getName() + (getStatus() ? F(" wet") : F(" dry")));
|
||||
}
|
||||
|
||||
void IS_Water::runInterrupt()
|
||||
{
|
||||
//add the "closed" event to the buffer to be queued for transfer to the hub
|
||||
Everything::sendSmartString(getName() + F(" wet"));
|
||||
}
|
||||
|
||||
void IS_Water::runInterruptEnded()
|
||||
{
|
||||
//add the "open" event to the buffer to be queued for transfer to the hub
|
||||
Everything::sendSmartString(getName() + F(" dry"));
|
||||
}
|
||||
|
||||
}
|
||||
62
lib/ST_Anything/IS_Water.h
Normal file
62
lib/ST_Anything/IS_Water.h
Normal file
@@ -0,0 +1,62 @@
|
||||
//******************************************************************************************
|
||||
// File: IS_Water.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: IS_Water is a class which implements the Hubitat "Water Sensor" device capability.
|
||||
// It inherits from the st::InterruptSensor class.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::IS_Water sensor6(F("water1"), PIN_WATER, HIGH, true, 500);
|
||||
//
|
||||
// st::IS_Water() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital input
|
||||
// - bool iState - REQUIRED - LOW or HIGH - determines which value indicates the interrupt is true
|
||||
// - bool internalPullup - OPTIONAL - true == INTERNAL_PULLUP
|
||||
// - long numReqCounts - OPTIONAL - number of counts before changing state of input (prevent false alarms)
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2020-06-30 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_IS_WATER_H
|
||||
#define ST_IS_WATER_H
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class IS_Water: public InterruptSensor
|
||||
{
|
||||
private:
|
||||
//inherits everything necessary from parent InterruptSensor Class
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
IS_Water(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup = false, long numReqCounts = 0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~IS_Water();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure the Hub is kept consistent with the state of the water sensor
|
||||
virtual void refresh();
|
||||
|
||||
//handles what to do when interrupt is triggered
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
151
lib/ST_Anything/InterruptSensor.cpp
Normal file
151
lib/ST_Anything/InterruptSensor.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//******************************************************************************************
|
||||
// File: InterruptSensor.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::InterruptSensor is a generic class which inherits from st::Sensor. This is the
|
||||
// parent class for the st::IS_Motion, IS_Contact, and IS_DoorControl classes.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Added optional "numReqCounts" constructor argument/capability
|
||||
// 2019-09-22 Dan Ogorchock ESP8266 support for using A0 pin as a digital input
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "InterruptSensor.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//Checks to see if the pin has changed state. If so calls appropriate function.
|
||||
void InterruptSensor::checkIfTriggered()
|
||||
{
|
||||
bool inputState;
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
if (m_nInterruptPin == A0)
|
||||
{
|
||||
if (m_nLoopCounter == 1000) { //reading an analog input every pass through loop() is too slow
|
||||
inputState = analogRead(A0) > 512 ? HIGH : LOW;
|
||||
m_nLoopCounter = 0;
|
||||
}
|
||||
else {
|
||||
m_nLoopCounter++;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else {
|
||||
inputState = digitalRead(m_nInterruptPin);
|
||||
}
|
||||
#else
|
||||
inputState = digitalRead(m_nInterruptPin);
|
||||
#endif
|
||||
if (inputState == m_bInterruptState && !m_bStatus) //new interrupt
|
||||
{
|
||||
m_nCurrentDownCount = m_nRequiredCounts;
|
||||
m_nCurrentUpCount++;
|
||||
if (m_nCurrentUpCount >= m_nRequiredCounts)
|
||||
{
|
||||
m_bStatus = true;
|
||||
m_bInitRequired = false;
|
||||
runInterrupt();
|
||||
}
|
||||
}
|
||||
else if ((inputState != m_bInterruptState && m_bStatus) || m_bInitRequired) //interrupt has ended OR Init called us
|
||||
{
|
||||
m_nCurrentUpCount = 0;
|
||||
m_nCurrentDownCount--;
|
||||
if (m_nCurrentDownCount <= 0)
|
||||
{
|
||||
m_bStatus = false;
|
||||
m_bInitRequired = false;
|
||||
runInterruptEnded();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
InterruptSensor::InterruptSensor(const __FlashStringHelper *name, byte pin, bool iState, bool pullup, long numReqCounts) :
|
||||
Sensor(name),
|
||||
m_bInterruptState(iState),
|
||||
m_bStatus(false),
|
||||
m_bPullup(pullup),
|
||||
m_bInitRequired(true),
|
||||
m_nRequiredCounts(numReqCounts),
|
||||
m_nCurrentUpCount(0),
|
||||
m_nCurrentDownCount(numReqCounts),
|
||||
m_nLoopCounter(0)
|
||||
{
|
||||
setInterruptPin(pin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
InterruptSensor::~InterruptSensor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//initialization function
|
||||
void InterruptSensor::init()
|
||||
{
|
||||
checkIfTriggered();
|
||||
}
|
||||
|
||||
//update function
|
||||
void InterruptSensor::update()
|
||||
{
|
||||
checkIfTriggered();
|
||||
}
|
||||
|
||||
//handles start of an interrupt - all derived classes should implement this virtual function
|
||||
void InterruptSensor::runInterrupt()
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Everything::sendSmartString(getName()+F(" triggered ") + (m_bInterruptState?F("HIGH"):F("LOW)")));
|
||||
}
|
||||
}
|
||||
|
||||
//handles the end of an interrupt - all derived classes should implement this virtual function
|
||||
void InterruptSensor::runInterruptEnded()
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Everything::sendSmartString(getName()+F(" ended ") + (m_bInterruptState?F("LOW)"):F("HIGH)")));
|
||||
}
|
||||
}
|
||||
|
||||
//sets the pin to be monitored, and set the Arduino pinMode based on constructor data
|
||||
void InterruptSensor::setInterruptPin(byte pin)
|
||||
{
|
||||
m_nInterruptPin=pin;
|
||||
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
if (pin == A0)
|
||||
{
|
||||
pinMode(m_nInterruptPin, INPUT);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
if(!m_bPullup)
|
||||
{
|
||||
pinMode(m_nInterruptPin, INPUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
pinMode(m_nInterruptPin, INPUT_PULLUP);
|
||||
}
|
||||
}
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
bool InterruptSensor::debug=false;
|
||||
}
|
||||
78
lib/ST_Anything/InterruptSensor.h
Normal file
78
lib/ST_Anything/InterruptSensor.h
Normal file
@@ -0,0 +1,78 @@
|
||||
//******************************************************************************************
|
||||
// File: InterruptSensor.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::InterruptSensor is a generic class which inherits from st::Sensor. This is the
|
||||
// parent class for the st::IS_Motion, IS_Contact, and IS_DoorControl classes.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-03-17 Dan Added optional "numReqCounts" constructor argument/capability
|
||||
// 2019-09-22 Dan Ogorchock ESP8266 support for using A0 pin as a digital input
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_INTERRUPTSENSOR_H
|
||||
#define ST_INTERRUPTSENSOR_H
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class InterruptSensor: public Sensor
|
||||
{
|
||||
private:
|
||||
byte m_nInterruptPin; //pin that will be monitored for change of state
|
||||
bool m_bInterruptState; //LOW or HIGH - determines which value indicates the interrupt is true (i.e. LOW=Falling Edge, HIGH=Rising Edge)
|
||||
bool m_bStatus; //true == interrupted
|
||||
bool m_bPullup; //true == Internal Pullup resistor required, set in constructor call in your sketch
|
||||
bool m_bInitRequired; //
|
||||
long m_nRequiredCounts; //Number of required counts (checks of the pin) before believing the pin is high/low
|
||||
long m_nCurrentUpCount;
|
||||
long m_nCurrentDownCount;
|
||||
long m_nLoopCounter;
|
||||
|
||||
void checkIfTriggered();
|
||||
|
||||
public:
|
||||
//constructor
|
||||
InterruptSensor(const __FlashStringHelper *name, byte pin, bool iState, bool internalPullup=false, long numReqCounts=0); //(defaults to NOT using internal pullup resistors, and required counts = 0)
|
||||
|
||||
//destructor
|
||||
virtual ~InterruptSensor();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
virtual void update();
|
||||
|
||||
//handles what to do when interrupt is triggered - all derived classes should implement this virtual function
|
||||
virtual void runInterrupt();
|
||||
|
||||
//handles what to do when interrupt is ended - all derived classes should implement this virtual function
|
||||
virtual void runInterruptEnded();
|
||||
|
||||
//gets
|
||||
inline byte getInterruptPin() const {return m_nInterruptPin;}
|
||||
inline bool getInterruptState() const {return m_bInterruptState;}
|
||||
inline bool getStatus() const {return m_bStatus;} //whether or not the device is currently interrupted
|
||||
|
||||
|
||||
//sets
|
||||
void setInterruptPin(byte pin);
|
||||
void setInterruptState(bool b) {m_bInterruptState=b;}
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
static bool debug;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
136
lib/ST_Anything/PS_10kThermistor.cpp
Normal file
136
lib/ST_Anything/PS_10kThermistor.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_10kThermistor.cpp
|
||||
// Authors: D. Johnson (_M2) based on the work of Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_10kThermistor is a class which implements the Hubitat "Temperature Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value of a simple thermal resistor using another 10k resistor as a voltage divider.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to configure the resistance of the parts.
|
||||
// The first number is the resistance of the thermistor. Second is R1. Third is the thermistor coefficient. Last is your preference of units.
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_10kThermistor sensor1(F("temperature1"), 120, 0, PIN_THERMISTOR, 10000, 10000, 3300, "F");
|
||||
//
|
||||
// st::PS_10kThermistor() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int tl - OPTIONAL - resistance of the thermocouple at the nominal temperature (usually 25C, 77F)
|
||||
// - int r1 - OPTIONAL - actual measured resistance of the voltage divider resistor
|
||||
// - int BCOEFF - OPTIONAL - The beta coefficient of the thermistor (usually 3000-4000). Tweak this number to calibrate.
|
||||
// - int tempNOM - OPTIONAL - The nominal temperature of the thermistor @10k (usually 25C, 77F).
|
||||
// - int unit - OPTIONAL - Use the letter F for Farhenheit, C for Celsius
|
||||
//
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-12-23 D. Johnson Created 10k_Thermistor using PS_Illuminance as example
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PS_10kThermistor.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_10kThermistor::PS_10kThermistor(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int t1, int r1, int BCOEFF, int tempNom, char unit):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nSensorValue(0),
|
||||
thermResistance(t1),
|
||||
r1Resistance(r1),
|
||||
BetaCoeff(BCOEFF),
|
||||
UNIT(unit),
|
||||
TEMPNOMINAL(tempNom)
|
||||
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_10kThermistor::~PS_10kThermistor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_10kThermistor::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_10kThermistor::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_10kThermistor::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_10kThermistor::getData()
|
||||
{
|
||||
int NUMSAMPLES = 10;
|
||||
float samples[NUMSAMPLES];
|
||||
for (int i=0; i< NUMSAMPLES; i++)
|
||||
{
|
||||
samples[i] = analogRead(m_nAnalogInputPin);
|
||||
}
|
||||
|
||||
// average all the samples out
|
||||
float average = 0;
|
||||
for (int i=0; i< NUMSAMPLES; i++)
|
||||
{
|
||||
average += samples[i];
|
||||
}
|
||||
average /= NUMSAMPLES;
|
||||
// convert the value to resistance
|
||||
average = 1023 / average - 1;
|
||||
average = r1Resistance / average;
|
||||
|
||||
float reading;
|
||||
float Temp1F;
|
||||
float Temp1C;
|
||||
reading = average / thermResistance; // (R/Ro)
|
||||
reading = log(reading); // ln(R/Ro)
|
||||
reading /= BetaCoeff; // 1/B * ln(R/Ro)
|
||||
reading += 1.0 / (TEMPNOMINAL + 273.15); // + (1/To)
|
||||
reading = 1.0 / reading; // Invert
|
||||
Temp1C = reading -= 273.15; // convert to C
|
||||
Temp1F = (Temp1C * 1.8) + 32; // convert to F
|
||||
|
||||
if(UNIT == 'F'){
|
||||
m_nSensorValue = Temp1F;
|
||||
}
|
||||
else {
|
||||
m_nSensorValue = Temp1C;
|
||||
}
|
||||
|
||||
Everything::sendSmartString(getName() + " " + String(m_nSensorValue));
|
||||
}
|
||||
void PS_10kThermistor::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin = pin;
|
||||
}
|
||||
}
|
||||
76
lib/ST_Anything/PS_10kThermistor.h
Normal file
76
lib/ST_Anything/PS_10kThermistor.h
Normal file
@@ -0,0 +1,76 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_10kThermistor.cpp
|
||||
// Authors: D. Johnson (_M2) based on the work of Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_10kThermistor is a class which implements the Hubitat "Temperature Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value of a simple thermal resistor using another 10k resistor as a voltage divider.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to configure the resistance of the parts.
|
||||
// The first number is the resistance of the thermistor. Second is R1. Third is the thermistor coefficient. Last is your preference of units.
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_10kThermistor sensor1(F("temperature1"), 120, 0, PIN_THERMISTOR, 10000, 10000, 3300, "F");
|
||||
//
|
||||
// st::PS_10kThermistor() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int tl - OPTIONAL - resistance of the thermocouple at the nominal temperature (usually 25C, 77F)
|
||||
// - int r1 - OPTIONAL - actual measured resistance of the voltage divider resistor
|
||||
// - int BCOEFF - OPTIONAL - The beta coefficient of the thermistor (usually 3000-4000). Tweak this number to calibrate.
|
||||
// - int tempNOM - OPTIONAL - The nominal temperature of the thermistor @10k (usually 25C, 77F).
|
||||
// - int unit - OPTIONAL - Use the letter F for Farhenheit, C for Celsius
|
||||
//
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-12-23 D. Johnson Created 10k_Thermistor using PS_Illuminance as example
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_PS_10KTHERMISTOR_H
|
||||
#define ST_PS_10KTHERMISTOR_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_10kThermistor: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin;
|
||||
float m_nSensorValue;
|
||||
int thermResistance;
|
||||
int r1Resistance;
|
||||
int BetaCoeff;
|
||||
int TEMPNOMINAL;
|
||||
char UNIT;
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_10kThermistor(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int t1=10000, int r1=10000, int BCOEFF=3300, int tempNom=25, char unit='F');
|
||||
|
||||
//destructor
|
||||
virtual ~PS_10kThermistor();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
118
lib/ST_Anything/PS_Generic.cpp
Normal file
118
lib/ST_Anything/PS_Generic.cpp
Normal file
@@ -0,0 +1,118 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Generic.h
|
||||
// Authors: Allan (vseven) (Based on original programming by Dan G Ogorchock & Daniel J Ogorchock (Father and Son) )
|
||||
//
|
||||
// Summary: PS_Generic is a class which implements only the SmartThings "Sensor" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version is made to be used as a framework
|
||||
// for more complicated programming
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Generic sensor1(F("generic1"), 120, 0);
|
||||
//
|
||||
// st::PS_Generic() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-20 Allan (vseven) Modified original PS_Illuminance library for use with a generic sensor
|
||||
// 2017-12-28 Dan Ogorchock Fixed bug with improper init() definition
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "PS_Generic.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
//this can be modified to accepting more varialbes into it by modifying the
|
||||
//next line. For example if you wanted to assign a pin or a variable you could add
|
||||
//a ", myVariable" after the offset below and then use that within your program.
|
||||
//you would need to also update the associated line in the header file.
|
||||
PS_Generic::PS_Generic(const __FlashStringHelper *name, unsigned int interval, int offset):
|
||||
PollingSensor(name, interval, offset),m_nSensorValue(0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_Generic::~PS_Generic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Generic::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Generic::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Generic::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PS_Generic::init() {
|
||||
// This is where you would add any initialization for your custom code. For example if you
|
||||
// are using a Adafruit sensor this is where you would setup the sensor.
|
||||
Serial.println("Initiating the generic class.");
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_Generic::getData()
|
||||
{
|
||||
Serial.println("getData routine called");
|
||||
|
||||
// Here is where you would do whatever you need to do to get your data. Some basic
|
||||
// sample data is provided below just to see values come back in SmartThings. We firt
|
||||
// define a integer called someValue then assign it a value of 15.
|
||||
uint16_t someValue;
|
||||
someValue = 15;
|
||||
|
||||
|
||||
// Here is where you would assign the data to the sensor value. m_nSensorValue is a
|
||||
// ST_Anything standard for the value of the sensor, in this case our generic sensor.
|
||||
// In this example I'm converting everything to a String to make it easier to use if
|
||||
// you are trying to send up multiple values. For example you can add the values together
|
||||
// as a tring with a colon seperating them then in the DTH split the values back out.
|
||||
String m_nSensorValue = String(someValue, DEC);
|
||||
|
||||
|
||||
// To make it easier to debug print out our name and sensor value before sending it
|
||||
Serial.println(getName());
|
||||
Serial.println(m_nSensorValue);
|
||||
|
||||
|
||||
// Send the value to our parent which will then update the device handler
|
||||
Everything::sendSmartString(getName() + " " + String(m_nSensorValue));
|
||||
}
|
||||
|
||||
}
|
||||
71
lib/ST_Anything/PS_Generic.h
Normal file
71
lib/ST_Anything/PS_Generic.h
Normal file
@@ -0,0 +1,71 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Generic.h
|
||||
// Authors: Allan (vseven) (Based on original programming by Dan G Ogorchock & Daniel J Ogorchock (Father and Son) )
|
||||
//
|
||||
// Summary: PS_Generic is a class which implements only the SmartThings "Sensor" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version is made to be used as a framework
|
||||
// for more complicated programming
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Generic sensor1(F("generic1"), 120, 0);
|
||||
//
|
||||
// st::PS_Generic() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2017-10-20 Allan (vseven) Modified original PS_Illuminance library for use with a generic sensor
|
||||
// 2017-12-28 Dan Ogorchock Fixed bug with improper init() definition
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Generic: public PollingSensor
|
||||
{
|
||||
private:
|
||||
char m_nSensorValue; //converted to a string so all data can be passed in one call
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
//this can be modified to accepting more varialbes into it by modifying the
|
||||
//line. For example if you wanted to assign a pin or a variable you could add
|
||||
//a ", int myVariable" after the offset below and then use that within your program.
|
||||
//you would need to also update the associated line in the .cpp file.
|
||||
PS_Generic(const __FlashStringHelper *name, unsigned int interval, int offset);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Generic();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//initialization routine
|
||||
virtual void init();
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
105
lib/ST_Anything/PS_Illuminance.cpp
Normal file
105
lib/ST_Anything/PS_Illuminance.cpp
Normal file
@@ -0,0 +1,105 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Illuminance.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Illuminance is a class which implements the SmartThings "Illuminance Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value of a simple photo resistor.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (0 to 1024) to Lux before sending to SmartThings. The
|
||||
// defaults for this sensor are based on the device used during testing.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Illuminance sensor1(F("illuminance1"), 120, 0, PIN_ILLUMINANCE, 0, 1023, 0, 1000);
|
||||
//
|
||||
// st::PS_Illuminance() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2017-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PS_Illuminance.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Illuminance::PS_Illuminance(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int s_l, int s_h, int m_l, int m_h):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nSensorValue(0),
|
||||
SENSOR_LOW(s_l),
|
||||
SENSOR_HIGH(s_h),
|
||||
MAPPED_LOW(m_l),
|
||||
MAPPED_HIGH(m_h)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_Illuminance::~PS_Illuminance()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Illuminance::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Illuminance::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Illuminance::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_Illuminance::getData()
|
||||
{
|
||||
int m_nSensorValue=map(analogRead(m_nAnalogInputPin), SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH);
|
||||
|
||||
Everything::sendSmartString(getName() + " " + String(m_nSensorValue));
|
||||
}
|
||||
|
||||
void PS_Illuminance::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
77
lib/ST_Anything/PS_Illuminance.h
Normal file
77
lib/ST_Anything/PS_Illuminance.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Illuminance.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Illuminance is a class which implements the SmartThings "Illuminance Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value of a simple photo resistor.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (0 to 1024) to Lux before sending to SmartThings. The
|
||||
// defaults for this sensor are based on the device used during testing.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Illuminance sensor1(F("illuminance1"), 120, 0, PIN_ILLUMINANCE, 0, 1023, 0, 1000);
|
||||
//
|
||||
// st::PS_Illuminance() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
// - int m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_PS_ILLUMINANCE_H
|
||||
#define ST_PS_ILLUMINANCE_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Illuminance: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin;
|
||||
int m_nSensorValue;
|
||||
const int SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH;
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Illuminance(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int s_l=0, int s_h=1023, int m_l=1000, int m_h=0);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Illuminance();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
103
lib/ST_Anything/PS_MQ2_Smoke.cpp
Normal file
103
lib/ST_Anything/PS_MQ2_Smoke.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_MQ2_Smoke.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_MQ2_Smoke is a class which implements the SmartThings "Smoke Detector" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value from the MQ2 sensor.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_MQ2_Smoke sensor1("smoke1", 10, 0, PIN_MQ2_SMOKE, 300);
|
||||
//
|
||||
// st::PS_MQ2_Smoke() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name e.g. "smoke1", "smoke2", etc...
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int sensorLimit - REQUIRED - if sensor reads value above this limit, report Smoke Detected (typical range is 0 to 1023 on Arduino Analog Input)
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the Arduino. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2017-07-04 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
|
||||
#include "PS_MQ2_Smoke.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_MQ2_Smoke::PS_MQ2_Smoke(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int sensorLimit):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nSensorValue(0),
|
||||
m_nSensorLimit(sensorLimit)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_MQ2_Smoke::~PS_MQ2_Smoke()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_MQ2_Smoke::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_MQ2_Smoke::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_MQ2_Smoke::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_MQ2_Smoke::getData()
|
||||
{
|
||||
int m_nSensorValue=analogRead(m_nAnalogInputPin);
|
||||
|
||||
Everything::sendSmartString(getName() + (m_nSensorValue < m_nSensorLimit ? F(" clear") : F(" detected")));
|
||||
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_MQ2_Smoke::Analog Pin value is "));
|
||||
Serial.print(m_nSensorValue);
|
||||
Serial.print(F(" vs limit of "));
|
||||
Serial.println(m_nSensorLimit);
|
||||
}
|
||||
}
|
||||
|
||||
void PS_MQ2_Smoke::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
69
lib/ST_Anything/PS_MQ2_Smoke.h
Normal file
69
lib/ST_Anything/PS_MQ2_Smoke.h
Normal file
@@ -0,0 +1,69 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_MQ2_Smoke.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_MQ2_Smoke is a class which implements the SmartThings "Smoke Detector" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// value from the MQ2 sensor.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_MQ2_Smoke sensor1("smoke1", 10, 0, PIN_MQ2_SMOKE, 300);
|
||||
//
|
||||
// st::PS_MQ2_Smoke() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name e.g. "smoke1", "smoke2", etc...
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - int sensorLimit - REQUIRED - if sensor reads value above this limit, report Smoke Detected (typical range is 0 to 1023 on Arduino Analog Input)
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the Arduino. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2017-07-04 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_PS_MQ2_SMOKE_H
|
||||
#define ST_PS_MQ2_SMOKE_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_MQ2_Smoke: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin;
|
||||
int m_nSensorValue;
|
||||
int m_nSensorLimit;
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_MQ2_Smoke(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int sensorLimit);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_MQ2_Smoke();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
138
lib/ST_Anything/PS_Power.cpp
Normal file
138
lib/ST_Anything/PS_Power.cpp
Normal file
@@ -0,0 +1,138 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Power.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Power is a class which implements the SmartThings "Power Meter" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an analog input pin via the EmonLib. This produce the Irms current of the Current Transformer.
|
||||
// The Irms current is then multiplied by the voltage constant passed in to produce Power in Watts.
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Power sensor1(F("power1"), 120, 0, PIN_POWER, 30.0, 1480, 120.0);
|
||||
//
|
||||
// st::PS_Power() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double ICAL - REQUIRED - EmonLib Calibration Constant
|
||||
// - unsigned int numSamples - OPTIONAL - defaults to 1480, number of analog readings to use for calculating the Irms Current
|
||||
// - float voltage - OPTIONAL - defaults to 120, AC voltage of the mains line being monitored
|
||||
// - byte filterConstant - OPTIONAL - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none (default), 5 = maximum
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-02-17 Dan Ogorchock Original Creation
|
||||
// 2019-09-19 Dan Ogorchock Added filtering optional argument to help reduce noisy signals
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "PS_Power.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Power::PS_Power(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double ICAL, unsigned int NumSamples, float voltage, byte filterConstant) :
|
||||
PollingSensor(name, interval, offset),
|
||||
emon1(),
|
||||
m_nAnalogInputPin(analogInputPin),
|
||||
m_fICAL(ICAL),
|
||||
m_fIrms(0.0),
|
||||
m_fApparentPower(0.0),
|
||||
m_nNumSamples(NumSamples),
|
||||
m_fVoltage(voltage)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
|
||||
//check for upper and lower limit and adjust accordingly
|
||||
if ((filterConstant <= 0) || (filterConstant >= 100))
|
||||
{
|
||||
m_fFilterConstant = 1.0;
|
||||
}
|
||||
else if (filterConstant <= 5)
|
||||
{
|
||||
m_fFilterConstant = 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fFilterConstant = float(filterConstant) / 100;
|
||||
}
|
||||
|
||||
emon1.current(m_nAnalogInputPin, m_fICAL); // Current: input pin, calibration.
|
||||
}
|
||||
|
||||
|
||||
//destructor
|
||||
PS_Power::~PS_Power()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PS_Power::init()
|
||||
{
|
||||
//Make sure the EmonLib has some data accumulated before anything is transmitted to ST/Hubitat
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples);
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples);
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples);
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples);
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples);
|
||||
|
||||
m_fApparentPower = m_fIrms * m_fVoltage; //Calcuate Apparent Power
|
||||
|
||||
//Send initial data to ST/Hubitat
|
||||
getData();
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Power::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Power::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Power::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST/Hubitat
|
||||
void PS_Power::getData()
|
||||
{
|
||||
double tempValue = 0;
|
||||
|
||||
m_fIrms = emon1.calcIrms(m_nNumSamples); // Calculate Irms only
|
||||
|
||||
tempValue = m_fIrms * m_fVoltage; //Calcuate Apparent Power
|
||||
|
||||
m_fApparentPower = (m_fFilterConstant * tempValue) + (1 - m_fFilterConstant) * m_fApparentPower;
|
||||
|
||||
Everything::sendSmartString(getName() + " " + String(m_fApparentPower));
|
||||
}
|
||||
|
||||
void PS_Power::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
79
lib/ST_Anything/PS_Power.h
Normal file
79
lib/ST_Anything/PS_Power.h
Normal file
@@ -0,0 +1,79 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Power.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Power is a class which implements the SmartThings "Power Meter" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an analog input pin via the EmonLib. This produce the Irms current of the Current Transformer.
|
||||
// The Irms current is then multiplied by the voltage constant passed in to produce Power in Watts.
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Power sensor1(F("power1"), 120, 0, PIN_POWER, 30.0, 1480, 120.0);
|
||||
//
|
||||
// st::PS_Power() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double ICAL - REQUIRED - EmonLib Calibration Constant
|
||||
// - unsigned int numSamples - OPTIONAL - defaults to 1480, number of analog readings to use for calculating the Irms Current
|
||||
// - float voltage - OPTIONAL - defaults to 120, AC voltage of the mains line being monitored
|
||||
// - byte filterConstant - OPTIONAL - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none (default), 5 = maximum
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-02-17 Dan Ogorchock Original Creation
|
||||
// 2019-09-19 Dan Ogorchock Added filtering optional argument to help reduce noisy signals
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_PS_Power_H
|
||||
#define ST_PS_Power_H
|
||||
|
||||
#include <EmonLib.h>
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Power: public PollingSensor
|
||||
{
|
||||
private:
|
||||
EnergyMonitor emon1;
|
||||
byte m_nAnalogInputPin;
|
||||
double m_fICAL;
|
||||
unsigned int m_nNumSamples;
|
||||
float m_fVoltage;
|
||||
double m_fIrms;
|
||||
double m_fApparentPower;
|
||||
float m_fFilterConstant; //Filter constant % as floating point from 0.00 to 1.00
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Power(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double ICAL, unsigned int NumSamples=1480, float voltage=120.0, byte filterConstant = 100);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Power();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline float getSensorValue() const {return m_fApparentPower;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
151
lib/ST_Anything/PS_PulseCounter.cpp
Normal file
151
lib/ST_Anything/PS_PulseCounter.cpp
Normal file
@@ -0,0 +1,151 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_PulseCounter.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_PulseCounter is a class which implements the SmartThings "Power Meter"-style device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses a digital input to measure the
|
||||
// the number of counts between polling intervals. At the polling interval, the pulse count is converted
|
||||
// to engineering units via a linear conversion (engUnits = slope x counts + offset).
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_PulseCounter sensor3(F("power1"), 60, 5, PIN_PULSE, FALLING, INPUT_PULLUP, 1.0, 0);
|
||||
//
|
||||
// st::PS_PulseCounter() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must be in form of "power1", "power2", etc...
|
||||
// - int interval - REQUIRED - the polling interval in seconds
|
||||
// - int offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the GPIO Pin to be used as an digital input (Hardware Interrupt)
|
||||
// - byte inttype - REQUIRED - which type of Arduino interrupt to trigger the ISR (RISING, FALLING, CHANGE)
|
||||
// - byte inputmode - REQUIRED - Mode of the digital input Pin (INPUT, INPUT_PULLUP)
|
||||
// - float cnvslope - REQUIRED - Conversion to Engineering Units Slope
|
||||
// - float cnvoffset - REQUIRED - Conversion to Engineering Units Offset
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-03-31 Dan Ogorchock Original Creation
|
||||
// 2018-03-03 Dan Ogorchock Improved code to make generic for all boards, not just Arduino MEGA
|
||||
// 2020-01-17 Dan Ogorchock Improved support for ESP8266 using Arduino IDE Board Manager 2.5.1 and newer
|
||||
// 2020-11-15 Dan Ogorchock Prevent Refresh from sending data for this particular device.
|
||||
// 2021-04-12 Dan Ogorchock Corrected data type for interrupt type to correct compiler error for Nano 33 IoT
|
||||
// 2021-06-14 Dan Ogorchock Fixed for SAMD Architectures...again
|
||||
// 2023-01-25 Dan Ogorchock Fixed for MKR 1010 (use PinStatus instead of int for inttype)
|
||||
// 2023-01-26 Dan Ogorchock Fixed for SAMD Architecture boards versus all other boards
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PS_PulseCounter.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
//#include "PinChangeInt.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
//This "Counts" variables must be declared here so they can be used in the Interrupt Service Routines (ISR)
|
||||
volatile unsigned long m_nCounts; //current count of interrupts (pulses)
|
||||
|
||||
//These are the four Interrupt Service Routines (ISR) which must be unique for each interrupt
|
||||
#if defined(ARDUINO_ARCH_ESP8266)
|
||||
void ICACHE_RAM_ATTR isrPulse() {
|
||||
#else
|
||||
void isrPulse() {
|
||||
#endif
|
||||
m_nCounts++;
|
||||
}
|
||||
|
||||
//public
|
||||
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
PS_PulseCounter::PS_PulseCounter(const __FlashStringHelper *name, unsigned int interval, int offset, byte inputpin, PinStatus inttype, byte inputmode, float cnvslope, float cnvoffset) :
|
||||
#else
|
||||
PS_PulseCounter::PS_PulseCounter(const __FlashStringHelper* name, unsigned int interval, int offset, byte inputpin, int inttype, byte inputmode, float cnvslope, float cnvoffset) :
|
||||
#endif
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nInputMode(inputmode),
|
||||
m_nSensorValue(0),
|
||||
m_fCnvSlope(cnvslope),
|
||||
m_fCnvOffset(cnvoffset)
|
||||
{
|
||||
setPin(inputpin);
|
||||
m_nCounts = 0;
|
||||
m_pCounter = &m_nCounts;
|
||||
attachInterrupt(digitalPinToInterrupt(m_nInputPin), isrPulse, inttype);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_PulseCounter::~PS_PulseCounter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_PulseCounter::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_PulseCounter::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_PulseCounter::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PS_PulseCounter::refresh()
|
||||
{
|
||||
//This specific device should not report data except during its scheduled polling interval to preserve data integrity of the pulse counted value
|
||||
//getData();
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_PulseCounter::getData()
|
||||
{
|
||||
if (m_pCounter)
|
||||
{
|
||||
noInterrupts();
|
||||
unsigned long tmpCounts = *m_pCounter;
|
||||
*m_pCounter = 0;
|
||||
interrupts();
|
||||
|
||||
m_nSensorValue = long(m_fCnvSlope * tmpCounts + m_fCnvOffset);
|
||||
|
||||
}
|
||||
else //invalid Pin/Interrupt was requested, therefore we are in an error condition
|
||||
{
|
||||
m_nSensorValue = 0;
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.println(F("PS_PulseCounter::Something went wrong. Need to debug."));
|
||||
}
|
||||
}
|
||||
|
||||
Everything::sendSmartString(getName() + " " + m_nSensorValue);
|
||||
}
|
||||
|
||||
void PS_PulseCounter::setPin(byte pin)
|
||||
{
|
||||
m_nInputPin = pin;
|
||||
pinMode(m_nInputPin, m_nInputMode);
|
||||
}
|
||||
}
|
||||
99
lib/ST_Anything/PS_PulseCounter.h
Normal file
99
lib/ST_Anything/PS_PulseCounter.h
Normal file
@@ -0,0 +1,99 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_PulseCounter.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_PulseCounter is a class which implements the SmartThings "Power Meter"-style device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses a digital input to measure the
|
||||
// the number of counts between polling intervals. At the polling interval, the pulse count is converted
|
||||
// to engineering units via a linear conversion (engUnits = slope x counts + offset).
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_PulseCounter sensor3(F("power1"), 60, 5, PIN_PULSE, FALLING, INPUT_PULLUP, 1.0, 0);
|
||||
//
|
||||
// st::PS_PulseCounter() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must be in form of "power1", "power2", etc...
|
||||
// - int interval - REQUIRED - the polling interval in seconds
|
||||
// - int offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the GPIO Pin to be used as an digital input (Hardware Interrupt)
|
||||
// - byte inttype - REQUIRED - which type of Arduino interrupt to trigger the ISR (RISING, FALLING, CHANGE)
|
||||
// - byte inputmode - REQUIRED - Mode of the digital input Pin (INPUT, INPUT_PULLUP)
|
||||
// - float cnvslope - REQUIRED - Conversion to Engineering Units Slope
|
||||
// - float cnvoffset - REQUIRED - Conversion to Engineering Units Offset
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-03-31 Dan Ogorchock Original Creation
|
||||
// 2018-03-03 Dan Ogorchock Improved code to make generic for all boards, not just Arduino MEGA
|
||||
// 2020-01-17 Dan Ogorchock Improved support for ESP8266 using Arduino IDE Board Manager 2.5.1 and newer
|
||||
// 2020-11-15 Dan Ogorchock Prevent Refresh from sending data for this particular device.
|
||||
// 2021-04-12 Dan Ogorchock Corrected data type for interrupt type to correct compiler error for Nano 33 IoT
|
||||
// 2021-06-14 Dan Ogorchock Fixed for SAMD Architectures...again
|
||||
// 2023-01-25 Dan Ogorchock Fixed for MKR 1010 (use PinStatus instead of int for inttype)
|
||||
// 2023-01-26 Dan Ogorchock Fixed for SAMD Architecture boards versus all other boards
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
|
||||
#ifndef ST_PS_PULSECOUNTER_H
|
||||
#define ST_PS_PULSECOUNTER_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_PulseCounter : public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nInputPin; //input pin connected to the pulse generator
|
||||
byte m_nInputMode; //input mode (INPUT or INPUT_PULLUP)
|
||||
unsigned long m_nSensorValue; //current sensor value (m_nSensorValue = Long(m_fCnvSlope * m_nCounts + m_fCnvOffset))
|
||||
float m_fCnvSlope; //Linear Conversion Slope
|
||||
float m_fCnvOffset; //Linear Conversion Offset
|
||||
volatile unsigned long* m_pCounter; //Point to the correct Counter variable;
|
||||
|
||||
public:
|
||||
|
||||
#if defined(ARDUINO_ARCH_SAMD)
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_PulseCounter(const __FlashStringHelper *name, unsigned int interval, int offset, byte inputpin, PinStatus inttype, byte inputmode, float cnvslope, float cnvoffset);
|
||||
#else
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_PulseCounter(const __FlashStringHelper* name, unsigned int interval, int offset, byte inputpin, int inttype, byte inputmode, float cnvslope, float cnvoffset);
|
||||
#endif
|
||||
//destructor
|
||||
virtual ~PS_PulseCounter();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of each Device subclass object
|
||||
virtual void refresh();
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nInputPin;}
|
||||
inline long getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
|
||||
friend void isrPulse();
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
137
lib/ST_Anything/PS_SoundPressureLevel.cpp
Normal file
137
lib/ST_Anything/PS_SoundPressureLevel.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_SoundPressureLevel.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_SoundPressureLevel is a class which implements the "Sound Pressure Level" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an anlog input pin and then scale it to engineering units.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (e.g. 0 to 1024) to Engineering Units before sending to SmartThings.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::PS_SoundPressureLevel sensor1(F("soundPressureLevel1"), 60, 0, PIN_SPL, 0, 1024, 0.0, 165.0, 50);
|
||||
//
|
||||
// st::PS_SoundPressureLevel() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - long m_nHighSpeedPollingInterval - OPTIONAL - number of milliseconds between high speed analog reads - defaults to 50ms
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-07-08 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "PS_SoundPressureLevel.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
float PS_SoundPressureLevel::map_double(double x, double in_min, double in_max, double out_min, double out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_SoundPressureLevel::PS_SoundPressureLevel(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l, double s_h, double m_l, double m_h, long HighSpeedPollingInterval):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_fSensorValue(-1.0),
|
||||
SENSOR_LOW(s_l),
|
||||
SENSOR_HIGH(s_h),
|
||||
MAPPED_LOW(m_l),
|
||||
MAPPED_HIGH(m_h),
|
||||
m_nHighSpeedPollingInterval(HighSpeedPollingInterval)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_SoundPressureLevel::~PS_SoundPressureLevel()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_SoundPressureLevel::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_SoundPressureLevel::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_SoundPressureLevel::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PS_SoundPressureLevel::update()
|
||||
{
|
||||
|
||||
//read the SPL value if enough time has elapsed
|
||||
if ((millis() - m_nPrevMillis) > m_nHighSpeedPollingInterval) {
|
||||
m_nPrevMillis = millis();
|
||||
|
||||
//read analog input
|
||||
long tempAnalogInput = analogRead(m_nAnalogInputPin);
|
||||
|
||||
//scale raw AI value into Engineering Units
|
||||
float tempValue = map_double(tempAnalogInput, SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH);
|
||||
|
||||
//if new value is greater than previous value, store the new value (i.e. keep the MAX SPL)
|
||||
if (tempValue > m_fSensorValue) {
|
||||
m_fSensorValue = tempValue;
|
||||
}
|
||||
}
|
||||
|
||||
//make sure to call the parent class' update function, since we've overriden update()
|
||||
PollingSensor::update();
|
||||
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to Hub
|
||||
void PS_SoundPressureLevel::getData()
|
||||
{
|
||||
//make sure we have at least one reading before transferring data
|
||||
update();
|
||||
|
||||
//transfer the data to the hub
|
||||
Everything::sendSmartString(getName() + " " + String(m_fSensorValue));
|
||||
|
||||
//reset the max value
|
||||
m_fSensorValue = -1.0;
|
||||
}
|
||||
|
||||
void PS_SoundPressureLevel::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
82
lib/ST_Anything/PS_SoundPressureLevel.h
Normal file
82
lib/ST_Anything/PS_SoundPressureLevel.h
Normal file
@@ -0,0 +1,82 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_SoundPressureLevel.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_SoundPressureLevel is a class which implements the "Sound Pressure Level" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an anlog input pin and then scale it to engineering units.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (e.g. 0 to 1024) to Engineering Units before sending to SmartThings.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::PS_SoundPressureLevel sensor1(F("soundPressureLevel1"), 60, 0, PIN_SPL, 0, 1024, 0.0, 165.0, 50);
|
||||
//
|
||||
// st::PS_SoundPressureLevel() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - long m_nHighSpeedPollingInterval - OPTIONAL - number of milliseconds between high speed analog reads - defaults to 50ms
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2019-07-08 Dan Ogorchock Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_PS_SOUNDPRESSURELEVEL_H
|
||||
#define ST_PS_SOUNDPRESSURELEVEL_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_SoundPressureLevel: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin;
|
||||
float m_fSensorValue;
|
||||
double SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH;
|
||||
long m_nPrevMillis;
|
||||
long m_nHighSpeedPollingInterval;
|
||||
|
||||
float map_double(double x, double in_min, double in_max, double out_min, double out_max);
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_SoundPressureLevel(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l=0, double s_h=1024, double m_l=0.0, double m_h=165.0, long HighSpeedPollingInterval = 50);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_SoundPressureLevel();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//update function
|
||||
virtual void update();
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline float getSensorValue() const {return m_fSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
107
lib/ST_Anything/PS_Ultrasonic.cpp
Normal file
107
lib/ST_Anything/PS_Ultrasonic.cpp
Normal file
@@ -0,0 +1,107 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Ultrasonic.cpp
|
||||
// Authors:
|
||||
//
|
||||
// Summary: PS_Ultrasonic is a class which implements a custom Level device capability.
|
||||
// It inherits from the st::PollingSensor class.
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Ultrasonic sensor1(F("ultrasonic1"), 60, 0, PIN_ULTRASONIC_T, PIN_ULTRASONIC_E);
|
||||
//
|
||||
// st::PS_Ultrasonic() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte digitalTriggerPin - REQUIRED - the Arduino Pin to be used as a digital output to trigger ultrasonic
|
||||
// - byte digitalEchoPin - REQUIRED - the Arduino Pin to be used as a digital input to read the echo
|
||||
//
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
//
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PS_Ultrasonic.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Ultrasonic::PS_Ultrasonic(const __FlashStringHelper *name, unsigned int interval, int offset, byte digitalTriggerPin, byte digitalEchoPin):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nSensorValue(0)
|
||||
{
|
||||
setPin(digitalTriggerPin,digitalEchoPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_Ultrasonic::~PS_Ultrasonic()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Ultrasonic::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
Serial.print("st string ##### ");
|
||||
Serial.println(str);
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Ultrasonic::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Ultrasonic::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_Ultrasonic::getData()
|
||||
{
|
||||
|
||||
//int m_nSensorValue=map(analogRead(m_nAnalogInputPin), SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH);
|
||||
long duration;
|
||||
// Clears the trigPin
|
||||
digitalWrite(m_nDigitalTriggerPin, LOW);
|
||||
delayMicroseconds(2);
|
||||
// Sets the trigPin on HIGH state for 10 micro seconds
|
||||
digitalWrite(m_nDigitalTriggerPin, HIGH);
|
||||
delayMicroseconds(10);
|
||||
digitalWrite(m_nDigitalTriggerPin, LOW);
|
||||
// Reads the echoPin, returns the sound wave travel time in microseconds
|
||||
duration = pulseIn(m_nDigitalEchoPin, HIGH);
|
||||
// Calculating the distance
|
||||
m_nSensorValue = duration*0.034/2;
|
||||
|
||||
// queue the distance to send to smartthings
|
||||
Everything::sendSmartString(getName() + " " + String(m_nSensorValue));
|
||||
}
|
||||
|
||||
void PS_Ultrasonic::setPin(byte &trigPin,byte &echoPin)
|
||||
{
|
||||
m_nDigitalTriggerPin=trigPin;
|
||||
m_nDigitalEchoPin=echoPin;
|
||||
pinMode(m_nDigitalTriggerPin, OUTPUT); // Sets the trigPin as an Output
|
||||
pinMode(m_nDigitalEchoPin, INPUT); // Sets the echoPin as an Input
|
||||
}
|
||||
}
|
||||
64
lib/ST_Anything/PS_Ultrasonic.h
Normal file
64
lib/ST_Anything/PS_Ultrasonic.h
Normal file
@@ -0,0 +1,64 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Ultrasonic.h
|
||||
// Authors:
|
||||
//
|
||||
// Summary: PS_Ultrasonic is a class which implements a custom Level device capability.
|
||||
// It inherits from the st::PollingSensor class.
|
||||
//
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Ultrasonic sensor1(F("ultrasonic1"), 60, 0, PIN_ULTRASONIC_T, PIN_ULTRASONIC_E);
|
||||
//
|
||||
// st::PS_Ultrasonic() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte digitalTriggerPin - REQUIRED - the Arduino Pin to be used as a digital output to trigger ultrasonic
|
||||
// - byte digitalEchoPin - REQUIRED - the Arduino Pin to be used as a digital input to read the echo
|
||||
//
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
//
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_PS_Ultrasonic_H
|
||||
#define ST_PS_Ultrasonic_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Ultrasonic : public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nDigitalTriggerPin;
|
||||
byte m_nDigitalEchoPin;
|
||||
float m_nSensorValue;
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Ultrasonic(const __FlashStringHelper *name, unsigned int interval, int offset, byte digitalTriggerPin, byte digitalEchoPin);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Ultrasonic();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
//inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte &trigPin,byte &echoPin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
239
lib/ST_Anything/PS_Voltage.cpp
Normal file
239
lib/ST_Anything/PS_Voltage.cpp
Normal file
@@ -0,0 +1,239 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Voltage.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Voltage is a class which implements the SmartThings "Voltage Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an anlog input pin and then scale it to engineering units.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (e.g. 0 to 1024) to Engineering Units before sending to SmartThings.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Voltage sensor1(F("voltage1"), 120, 0, PIN_VOLTAGE, 0, 1023, 0.0, 5.0);
|
||||
//
|
||||
// st::PS_Voltage() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - byte numSamples - OPTIONAL - defaults to 1, number of analog readings to average per scheduled reading of the analog input
|
||||
// - byte filterConstant - OPTIONAL - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none (default), 5 = maximum
|
||||
//
|
||||
// Filtering/Averaging
|
||||
//
|
||||
// Filtering the value sent to ST is performed per the following equation
|
||||
//
|
||||
// filteredValue = (filterConstant/100 * currentValue) + ((1 - filterConstant/100) * filteredValue)
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// st::PS_Voltage() has a second constructor which includes a 3rd order polynomial compensation algorithm.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::PS_Voltage sensor5(F("voltage1"), 5, 1, PIN_VOLTAGE_1, -40, 140, 0, 4095, 20, 75, -0.000000025934, 0.0001049656215, 0.9032840665333, 204.642825355678);
|
||||
//
|
||||
// The following arguments all all REQUIRED in order to use the Compensation Algorithm.
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - byte numSamples - REQUIRED - number of analog readings to average per scheduled reading of the analog input
|
||||
// - byte filterConstant - REQUIRED - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none, 5 = maximum
|
||||
// - double Coeff1 - REQUIRED - 3rd order polynomial coefficient #1
|
||||
// - double Coeff2 - REQUIRED - 3rd order polynomial coefficient #2
|
||||
// - double Coeff3 - REQUIRED - 3rd order polynomial coefficient #3
|
||||
// - double Coeff4 - REQUIRED - 3rd order polynomial coefficient #4
|
||||
//
|
||||
// 3rd order Plynomial Compensation Algorithm (useful for correcting non-linear analog to digital converters)
|
||||
//
|
||||
// CompensatedValue = Coeff1 * rawAnalogInput^3 + Coeff2 * rawAnalogInput^2 + Coeff3 * rawAnalogInput + Coeff4
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-04-19 Dan & Daniel Original Creation
|
||||
// 2017-08-18 Dan Ogorchock Modified to return floating point values instead of integer
|
||||
// 2017-08-31 Dan Ogorchock Added oversampling optional argument to help reduce noisy signals
|
||||
// 2017-08-31 Dan Ogorchock Added filtering optional argument to help reduce noisy signals
|
||||
// 2017-09-01 Dan Ogorchock Added 3rd order polynomial nonlinear correction compensation
|
||||
// 2018-06-24 Dan Ogorchock Improved documentation / comments (above)
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#include "PS_Voltage.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
#include <math.h>
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
float map_double(double x, double in_min, double in_max, double out_min, double out_max)
|
||||
{
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Voltage::PS_Voltage(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l, double s_h, double m_l, double m_h, int NumSamples, byte filterConstant):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_fSensorValue(-1.0),
|
||||
SENSOR_LOW(s_l),
|
||||
SENSOR_HIGH(s_h),
|
||||
MAPPED_LOW(m_l),
|
||||
MAPPED_HIGH(m_h),
|
||||
m_nNumSamples(NumSamples),
|
||||
m_bUseCompensation(false)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
|
||||
//check for upper and lower limit and adjust accordingly
|
||||
if ((filterConstant <= 0) || (filterConstant >= 100))
|
||||
{
|
||||
m_fFilterConstant = 1.0;
|
||||
}
|
||||
else if (filterConstant <= 5)
|
||||
{
|
||||
m_fFilterConstant = 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fFilterConstant = float(filterConstant) / 100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Voltage::PS_Voltage(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l, double s_h, double m_l, double m_h, int NumSamples, byte filterConstant, double Coeff1, double Coeff2, double Coeff3, double Coeff4) :
|
||||
PollingSensor(name, interval, offset),
|
||||
m_fSensorValue(-1.0),
|
||||
SENSOR_LOW(s_l),
|
||||
SENSOR_HIGH(s_h),
|
||||
MAPPED_LOW(m_l),
|
||||
MAPPED_HIGH(m_h),
|
||||
m_nNumSamples(NumSamples),
|
||||
m_dCoeff1(Coeff1),
|
||||
m_dCoeff2(Coeff2),
|
||||
m_dCoeff3(Coeff3),
|
||||
m_dCoeff4(Coeff4),
|
||||
m_bUseCompensation(true)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
|
||||
//check for upper and lower limit and adjust accordingly
|
||||
if ((filterConstant <= 0) || (filterConstant >= 100))
|
||||
{
|
||||
m_fFilterConstant = 1.0;
|
||||
}
|
||||
else if (filterConstant <= 5)
|
||||
{
|
||||
m_fFilterConstant = 0.05;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fFilterConstant = float(filterConstant) / 100;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//destructor
|
||||
PS_Voltage::~PS_Voltage()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Voltage::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Voltage::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Voltage::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_Voltage::getData()
|
||||
{
|
||||
int i;
|
||||
double tempValue = 0;
|
||||
long tempAnalogInput = 0;
|
||||
|
||||
//implement oversampling / averaging
|
||||
for (i = 0; i < m_nNumSamples; i++) {
|
||||
|
||||
tempAnalogInput = analogRead(m_nAnalogInputPin);
|
||||
|
||||
if (m_bUseCompensation) {
|
||||
|
||||
//Serial.print(F("PS_Voltage::tempAnalogInput = "));
|
||||
//Serial.print(tempAnalogInput);
|
||||
|
||||
tempAnalogInput = (m_dCoeff1 * pow(tempAnalogInput, 3)) + (m_dCoeff2 * pow(tempAnalogInput, 2)) + (m_dCoeff3 * tempAnalogInput) + m_dCoeff4;
|
||||
|
||||
//Serial.print(F(", PS_Voltage::tempAnalogInput (Compensated) = "));
|
||||
//Serial.print(tempAnalogInput);
|
||||
//Serial.println();
|
||||
|
||||
}
|
||||
|
||||
tempValue += map_double(tempAnalogInput, SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH);
|
||||
|
||||
//if (st::PollingSensor::debug)
|
||||
//{
|
||||
// Serial.print(F("PS_Voltage::tempValue = "));
|
||||
// Serial.print(tempValue);
|
||||
// Serial.println();
|
||||
//}
|
||||
}
|
||||
|
||||
tempValue = tempValue / m_nNumSamples; //calculate the average value over the number of samples
|
||||
|
||||
//implement filtering
|
||||
if (m_fSensorValue == -1.0)
|
||||
{
|
||||
//first time through, no filtering
|
||||
m_fSensorValue = tempValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fSensorValue = (m_fFilterConstant * tempValue) + (1 - m_fFilterConstant) * m_fSensorValue;
|
||||
}
|
||||
|
||||
Everything::sendSmartString(getName() + " " + String(m_fSensorValue));
|
||||
}
|
||||
|
||||
void PS_Voltage::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
120
lib/ST_Anything/PS_Voltage.h
Normal file
120
lib/ST_Anything/PS_Voltage.h
Normal file
@@ -0,0 +1,120 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Voltage.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Voltage is a class which implements the SmartThings "Voltage Measurement" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// voltage on an anlog input pin and then scale it to engineering units.
|
||||
//
|
||||
// The last four arguments of the constructor are used as arguments to an Arduino map() function which
|
||||
// is used to scale the analog input readings (e.g. 0 to 1024) to Engineering Units before sending to SmartThings.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Voltage sensor1(F("voltage1"), 120, 0, PIN_VOLTAGE, 0, 1023, 0.0, 5.0);
|
||||
//
|
||||
// st::PS_Voltage() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - byte numSamples - OPTIONAL - defaults to 1, number of analog readings to average per scheduled reading of the analog input
|
||||
// - byte filterConstant - OPTIONAL - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none (default), 5 = maximum
|
||||
//
|
||||
// Filtering/Averaging
|
||||
//
|
||||
// Filtering the value sent to ST is performed per the following equation
|
||||
//
|
||||
// filteredValue = (filterConstant/100 * currentValue) + ((1 - filterConstant/100) * filteredValue)
|
||||
//
|
||||
//----------------------------------------------------------------------------------------------------------------------------------------------
|
||||
// st::PS_Voltage() has a second constructor which includes a 3rd order polynomial compensation algorithm.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: static st::PS_Voltage sensor5(F("voltage1"), 5, 1, PIN_VOLTAGE_1, -40, 140, 0, 4095, 20, 75, -0.000000025934, 0.0001049656215, 0.9032840665333, 204.642825355678);
|
||||
//
|
||||
// The following arguments all all REQUIRED in order to use the Compensation Algorithm.
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - double s_l - OPTIONAL - first argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - minimum raw AI value
|
||||
// - double s_h - OPTIONAL - second argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - maximum raw AI value
|
||||
// - double m_l - OPTIONAL - third argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Min (or Max if inverting)
|
||||
// - double m_h - OPTIONAL - fourth argument of Arduino map(s_l,s_h,m_l,m_h) function to scale the output - Engineering Unit Max (or Min if inverting)
|
||||
// - byte numSamples - REQUIRED - number of analog readings to average per scheduled reading of the analog input
|
||||
// - byte filterConstant - REQUIRED - Value from 5% to 100% to determine how much filtering/averaging is performed 100 = none, 5 = maximum
|
||||
// - double Coeff1 - REQUIRED - 3rd order polynomial coefficient #1
|
||||
// - double Coeff2 - REQUIRED - 3rd order polynomial coefficient #2
|
||||
// - double Coeff3 - REQUIRED - 3rd order polynomial coefficient #3
|
||||
// - double Coeff4 - REQUIRED - 3rd order polynomial coefficient #4
|
||||
//
|
||||
// 3rd order Plynomial Compensation Algorithm (useful for correcting non-linear analog to digital converters)
|
||||
//
|
||||
// CompensatedValue = Coeff1 * rawAnalogInput^3 + Coeff2 * rawAnalogInput^2 + Coeff3 * rawAnalogInput + Coeff4
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-04-19 Dan & Daniel Original Creation
|
||||
// 2017-08-18 Dan Ogorchock Modified to return floating point values instead of integer
|
||||
// 2017-08-31 Dan Ogorchock Added oversampling optional argument to help reduce noisy signals
|
||||
// 2017-08-31 Dan Ogorchock Added filtering optional argument to help reduce noisy signals
|
||||
// 2017-09-01 Dan Ogorchock Added 3rd order polynomial nonlinear correction compensation
|
||||
// 2018-06-24 Dan Ogorchock Improved documentation / comments (above)
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
#ifndef ST_PS_VOLTAGE_H
|
||||
#define ST_PS_VOLTAGE_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Voltage: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin;
|
||||
float m_fSensorValue;
|
||||
double SENSOR_LOW, SENSOR_HIGH, MAPPED_LOW, MAPPED_HIGH;
|
||||
int m_nNumSamples;
|
||||
float m_fFilterConstant; //Filter constant % as floating point from 0.00 to 1.00
|
||||
double m_dCoeff1, m_dCoeff2, m_dCoeff3, m_dCoeff4; //3rd order polynomial nonlinear correction compensation coefficients
|
||||
bool m_bUseCompensation;
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Voltage(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l=0, double s_h=1023, double m_l=0, double m_h=5000, int NumSamples=1, byte filterConstant = 100);
|
||||
|
||||
//constructor with 3rd order polynomial nonlinear correction compensation coefficients - called in your sketch's global variable declaration section
|
||||
PS_Voltage(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, double s_l, double s_h, double m_l, double m_h, int NumSamples, byte filterConstant, double Coeff1, double Coeff2, double Coeff3, double Coeff4);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Voltage();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline float getSensorValue() const {return m_fSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
};
|
||||
}
|
||||
#endif
|
||||
115
lib/ST_Anything/PS_Water.cpp
Normal file
115
lib/ST_Anything/PS_Water.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Water.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Water is a class which implements both the SmartThings "Water Sensor" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// presence of water using an inexpensive water sensor.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Water sensor3(F("water1"), 60, 6, PIN_WATER, 200, false);
|
||||
//
|
||||
// st::PS_Water() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - int limit - OPTIONAL - the alarm limit to compare analog pin's reading to, above which the sensor reports "wet" instead of "dry", default = 100
|
||||
// - bool invertLogic - OPTIONAL - if set to true, will invert the comparison against target from < to >, default = false
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-08-23 Dan Added optional alarm limit to constructor
|
||||
// 2018-10-17 Dan Added invertLogic parameter to constructor
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
|
||||
#include "PS_Water.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Water::PS_Water(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int limit, bool invertLogic):
|
||||
PollingSensor(name, interval, offset),
|
||||
m_nSensorValue(0),
|
||||
m_nSensorLimit(limit),
|
||||
m_binvertLogic(invertLogic)
|
||||
{
|
||||
setPin(analogInputPin);
|
||||
}
|
||||
|
||||
//destructor
|
||||
PS_Water::~PS_Water()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
void PS_Water::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
|
||||
if (s.toInt() != 0) {
|
||||
st::PollingSensor::setInterval(s.toInt() * 1000);
|
||||
if (st::PollingSensor::debug) {
|
||||
Serial.print(F("PS_Water::beSmart set polling interval to "));
|
||||
Serial.println(s.toInt());
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Water::beSmart cannot convert "));
|
||||
Serial.print(s);
|
||||
Serial.println(F(" to an Integer."));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
void PS_Water::getData()
|
||||
{
|
||||
int m_nSensorValue = analogRead(m_nAnalogInputPin);
|
||||
|
||||
if (st::PollingSensor::debug)
|
||||
{
|
||||
Serial.print(F("PS_Water::Analog Pin value is "));
|
||||
Serial.print(m_nSensorValue);
|
||||
Serial.print(F(" vs limit of "));
|
||||
Serial.println(m_nSensorLimit);
|
||||
}
|
||||
|
||||
//compare the sensor's value is against the limit to determine whether to send "dry" versus "wet".
|
||||
if (m_binvertLogic)
|
||||
{
|
||||
Everything::sendSmartString(getName() + (m_nSensorValue > m_nSensorLimit ? F(" dry") : F(" wet")));
|
||||
}
|
||||
else
|
||||
{
|
||||
Everything::sendSmartString(getName() + (m_nSensorValue < m_nSensorLimit ? F(" dry") : F(" wet")));
|
||||
}
|
||||
}
|
||||
|
||||
void PS_Water::setPin(byte pin)
|
||||
{
|
||||
m_nAnalogInputPin=pin;
|
||||
}
|
||||
}
|
||||
77
lib/ST_Anything/PS_Water.h
Normal file
77
lib/ST_Anything/PS_Water.h
Normal file
@@ -0,0 +1,77 @@
|
||||
//******************************************************************************************
|
||||
// File: PS_Water.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: PS_Water is a class which implements both the SmartThings "Water Sensor" device capability.
|
||||
// It inherits from the st::PollingSensor class. The current version uses an analog input to measure the
|
||||
// presence of water using an inexpensive water sensor.
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::PS_Water sensor3(F("water1"), 60, 6, PIN_WATER, 200, false);
|
||||
//
|
||||
// st::PS_Water() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
// - byte pin - REQUIRED - the Arduino Pin to be used as an analog input
|
||||
// - int limit - OPTIONAL - the alarm limit to compare analog pin's reading to, above which the sensor reports "wet" instead of "dry", default = 100
|
||||
// - bool invertLogic - OPTIONAL - if set to true, will invert the comparison against target from < to >, default = false
|
||||
//
|
||||
// This class supports receiving configuration data from the SmartThings cloud via the ST App. A user preference
|
||||
// can be configured in your phone's ST App, and then the "Configure" tile will send the data for all sensors to
|
||||
// the ST Shield. For PollingSensors, this data is handled in the beSMart() function.
|
||||
//
|
||||
// TODO: Determine a method to persist the ST Cloud's Polling Interval data
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2015-08-23 Dan Added optional alarm limit to constructor
|
||||
// 2018-10-17 Dan Added invertLogic parameter to constructor
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_PS_WATER_H
|
||||
#define ST_PS_WATER_H
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PS_Water: public PollingSensor
|
||||
{
|
||||
private:
|
||||
byte m_nAnalogInputPin; //analog pin connected to the water sensor
|
||||
int m_nSensorValue; //current sensor value
|
||||
int m_nSensorLimit; //alarm limit
|
||||
bool m_binvertLogic; //if false use <, if true use > for comparison of AI value versus limit
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
PS_Water(const __FlashStringHelper *name, unsigned int interval, int offset, byte analogInputPin, int limit = 100, bool invertLogic = false);
|
||||
|
||||
//destructor
|
||||
virtual ~PS_Water();
|
||||
|
||||
//SmartThings Shield data handler (receives configuration data from ST - polling interval, and adjusts on the fly)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
inline byte getPin() const {return m_nAnalogInputPin;}
|
||||
inline byte getSensorValue() const {return m_nSensorValue;}
|
||||
|
||||
//sets
|
||||
void setPin(byte pin);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
113
lib/ST_Anything/PollingSensor.cpp
Normal file
113
lib/ST_Anything/PollingSensor.cpp
Normal file
@@ -0,0 +1,113 @@
|
||||
//******************************************************************************************
|
||||
// File: PollingSensor.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::PollingSensor is a generic class which inherits from st::Sensor. This is the
|
||||
// parent class for the st::PS_Illuminace, st::PS_Water, and PS_TemperatureHumidity classes.
|
||||
//
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// st::PollingSensor() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "PollingSensor.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
bool PollingSensor::checkInterval()
|
||||
{
|
||||
//check for time overflow
|
||||
if(millis()<m_nPreviousTime)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Serial.println(F("PollingSensor: millis() Overflow handled"));
|
||||
}
|
||||
|
||||
m_nPreviousTime = 0;
|
||||
}
|
||||
|
||||
if(m_nPreviousTime==0) //eliminates problem of there being a delay before first update() call
|
||||
{
|
||||
m_nPreviousTime=millis();
|
||||
}
|
||||
|
||||
//calculate new delta time
|
||||
m_nDeltaTime+=(millis()-m_nPreviousTime)-m_nOffset;
|
||||
m_nOffset=0;
|
||||
m_nPreviousTime=millis();
|
||||
|
||||
//determine interval has passed
|
||||
if(m_nDeltaTime>=m_nInterval)
|
||||
{
|
||||
m_nDeltaTime=0;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
PollingSensor::PollingSensor(const __FlashStringHelper *name, long interval, long offset):
|
||||
Sensor(name),
|
||||
m_nPreviousTime(0),
|
||||
m_nDeltaTime(0),
|
||||
m_nInterval(interval*1000),
|
||||
m_nOffset(offset*1000)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
PollingSensor::~PollingSensor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void PollingSensor::init()
|
||||
{
|
||||
getData();
|
||||
}
|
||||
|
||||
void PollingSensor::refresh()
|
||||
{
|
||||
getData();
|
||||
}
|
||||
|
||||
void PollingSensor::update()
|
||||
{
|
||||
if(checkInterval())
|
||||
{
|
||||
getData();
|
||||
}
|
||||
}
|
||||
|
||||
void PollingSensor::getData()
|
||||
{
|
||||
if(debug)
|
||||
{
|
||||
Everything::sendSmartString(getName() + F(" triggered"));
|
||||
}
|
||||
}
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
bool PollingSensor::debug=false;
|
||||
}
|
||||
74
lib/ST_Anything/PollingSensor.h
Normal file
74
lib/ST_Anything/PollingSensor.h
Normal file
@@ -0,0 +1,74 @@
|
||||
//******************************************************************************************
|
||||
// File: PollingSensor.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::PollingSensor is a generic class which inherits from st::Sensor. This is the
|
||||
// parent class for the st::PS_Illuminace, st::PS_Water, and PS_TemperatureHumidity classes.
|
||||
//
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// st::PollingSensor() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - long interval - REQUIRED - the polling interval in seconds
|
||||
// - long offset - REQUIRED - the polling interval offset in seconds - used to prevent all polling sensors from executing at the same time
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_POLLINGSENSOR_H
|
||||
#define ST_POLLINGSENSOR_H
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class PollingSensor: public Sensor
|
||||
{
|
||||
private:
|
||||
unsigned long m_nPreviousTime; //in milliseconds - time of last poll
|
||||
long m_nDeltaTime; //in milliseconds - elapsed time since last poll
|
||||
long m_nInterval; //in milliseconds - polling interval for the sensor
|
||||
long m_nOffset; //in milliseconds - offset to prevent all Polling sensors from running at the same time
|
||||
|
||||
virtual bool checkInterval(); //returns true and resets m_nDeltaTime if m_nInterval has been reached
|
||||
|
||||
public:
|
||||
//constructor
|
||||
PollingSensor(const __FlashStringHelper *name, long interval, long offset=0);
|
||||
|
||||
//destructor
|
||||
virtual ~PollingSensor();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of each Device subclass object
|
||||
virtual void refresh();
|
||||
|
||||
//update function
|
||||
virtual void update();
|
||||
|
||||
//function to get data from sensor and queue results for transfer to ST Cloud
|
||||
virtual void getData();
|
||||
|
||||
//gets
|
||||
virtual void offset(long os) {m_nOffset=os;} //offset the delta time from its current value
|
||||
|
||||
//sets
|
||||
virtual void setInterval(long interval) {m_nInterval=interval;}
|
||||
|
||||
//debug flag to determine if debug print statements are executed (set value in your sketch)
|
||||
static bool debug;
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
206
lib/ST_Anything/S_TimedRelay.cpp
Normal file
206
lib/ST_Anything/S_TimedRelay.cpp
Normal file
@@ -0,0 +1,206 @@
|
||||
//******************************************************************************************
|
||||
// File: S_TimedRelay.cpp
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: S_TimedRelay is a class which implements the SmartThings "Relay" device capability. It features
|
||||
// an automatic-turn-off time delay for a relay to emulate a button press.
|
||||
//
|
||||
// It inherits from the st::Sensor class and clones much from the st::Executor Class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::S_TimedRelay sensor1(F("relaySwitch1"), PIN_RELAY, LOW, true, 1000, 0, 1, 0);
|
||||
//
|
||||
// st::S_TimedRelay() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinOutput - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Ouput should use inverted logic
|
||||
// - long onTime - REQUIRED - the number of milliseconds to keep the output on, DEFAULTS to 1000 milliseconds
|
||||
// - long offTime - OPTIONAL - the number of milliseconds to keep the output off, DEFAULTS to 0
|
||||
// - int numCycles - OPTIONAL - the number of times to repeat the on/off cycle, DEFAULTS to 1
|
||||
// - byte finalState - OPTIONAL - leave in X state after finishing sequence 0 = off, 1 = on , Defaults to 0
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-12-29 Dan Ogorchock Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-06-23 Brian Wilson Added finalState option
|
||||
// 2020-10-20 Dan Ogorchock Fixed minor bug to ensure proper reporting of device state
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "S_TimedRelay.h"
|
||||
|
||||
#include "Constants.h"
|
||||
#include "Everything.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
void S_TimedRelay::writeStateToPin()
|
||||
{
|
||||
digitalWrite(m_nOutputPin, m_bInvertLogic ? !m_bCurrentState : m_bCurrentState);
|
||||
}
|
||||
|
||||
//public
|
||||
//constructor
|
||||
S_TimedRelay::S_TimedRelay(const __FlashStringHelper *name, byte pinOutput, bool startingState, bool invertLogic, unsigned long onTime, unsigned long offTime, unsigned int numCycles, byte finalState) :
|
||||
Sensor(name),
|
||||
m_bCurrentState(startingState),
|
||||
m_bInvertLogic(invertLogic),
|
||||
m_lOnTime(onTime),
|
||||
m_lOffTime(offTime),
|
||||
m_iNumCycles(numCycles),
|
||||
m_iCurrentCount(numCycles),
|
||||
m_nfinalState(finalState),
|
||||
m_lTimeChanged(0),
|
||||
m_bTimerPending(false)
|
||||
{
|
||||
setOutputPin(pinOutput);
|
||||
|
||||
if (numCycles < 1)
|
||||
{
|
||||
m_iNumCycles = 1;
|
||||
m_iCurrentCount = 1;
|
||||
|
||||
Serial.println(F("S_TimedRelay:: INVALID Number of Cycles Requested! Must be at least 1. Setting to 1."));
|
||||
}
|
||||
}
|
||||
|
||||
//destructor
|
||||
S_TimedRelay::~S_TimedRelay()
|
||||
{
|
||||
}
|
||||
|
||||
void S_TimedRelay::init()
|
||||
{
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
//update function
|
||||
void S_TimedRelay::update()
|
||||
{
|
||||
if (m_iCurrentCount < m_iNumCycles)
|
||||
{
|
||||
//Turn off digital output if timer has expired
|
||||
if ((m_bCurrentState == HIGH) && (millis() - m_lTimeChanged >= m_lOnTime))
|
||||
{
|
||||
if (m_nfinalState == 1) { // final state will be on
|
||||
//add one to the current count since we finished an on/off cycle, and turn on output if needed
|
||||
m_iCurrentCount++;
|
||||
if (m_iCurrentCount < m_iNumCycles)
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
writeStateToPin();
|
||||
m_lTimeChanged = millis();
|
||||
}
|
||||
|
||||
} else {
|
||||
m_bCurrentState = LOW;
|
||||
writeStateToPin();
|
||||
m_lTimeChanged = millis();
|
||||
}
|
||||
}
|
||||
else if ((m_bCurrentState == LOW) && (millis() - m_lTimeChanged >= m_lOffTime))
|
||||
{
|
||||
if (m_nfinalState == 0) { // final state will be off
|
||||
//add one to the current count since we finished an on/off cycle, and turn on output if needed
|
||||
m_iCurrentCount++;
|
||||
if (m_iCurrentCount < m_iNumCycles)
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
writeStateToPin();
|
||||
m_lTimeChanged = millis();
|
||||
}
|
||||
} else {
|
||||
m_bCurrentState = HIGH;
|
||||
writeStateToPin();
|
||||
m_lTimeChanged = millis();
|
||||
}
|
||||
}
|
||||
|
||||
//Check to see if we just finished the requested number of cycles
|
||||
if (m_iCurrentCount == m_iNumCycles)
|
||||
{
|
||||
//Decrement number of active timers
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void S_TimedRelay::beSmart(const String &str)
|
||||
{
|
||||
String s = str.substring(str.indexOf(' ') + 1);
|
||||
if (st::Device::debug) {
|
||||
Serial.print(F("S_TimedRelay::beSmart s = "));
|
||||
Serial.println(s);
|
||||
}
|
||||
if ((s == F("on")) && (m_bCurrentState == LOW))
|
||||
{
|
||||
m_bCurrentState = HIGH;
|
||||
|
||||
//Save time turned on
|
||||
m_lTimeChanged = millis();
|
||||
|
||||
//Increment number of active timers
|
||||
if (!m_bTimerPending)
|
||||
{
|
||||
st::Everything::bTimersPending++;
|
||||
m_bTimerPending = true;
|
||||
}
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
|
||||
//Set the initial count to zero
|
||||
m_iCurrentCount = 0;
|
||||
|
||||
//update the digital output
|
||||
writeStateToPin();
|
||||
}
|
||||
else if ((s == F("off")) && (m_bCurrentState == HIGH))
|
||||
{
|
||||
m_bCurrentState = LOW;
|
||||
|
||||
//Decrement number of active timers
|
||||
if (st::Everything::bTimersPending > 0) st::Everything::bTimersPending--;
|
||||
m_bTimerPending = false;
|
||||
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
|
||||
//Reset the count to the number of required cycles to prevent Update() routine from running if someone sends an OFF command
|
||||
m_iCurrentCount = m_iNumCycles;
|
||||
|
||||
//update the digital output
|
||||
writeStateToPin();
|
||||
}
|
||||
else
|
||||
{
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
void S_TimedRelay::refresh()
|
||||
{
|
||||
//Queue the relay status update the ST Cloud
|
||||
Everything::sendSmartString(getName() + " " + (m_bCurrentState == HIGH ? F("on") : F("off")));
|
||||
}
|
||||
|
||||
void S_TimedRelay::setOutputPin(byte pin)
|
||||
{
|
||||
m_nOutputPin = pin;
|
||||
pinMode(m_nOutputPin, OUTPUT);
|
||||
writeStateToPin();
|
||||
}
|
||||
|
||||
}
|
||||
90
lib/ST_Anything/S_TimedRelay.h
Normal file
90
lib/ST_Anything/S_TimedRelay.h
Normal file
@@ -0,0 +1,90 @@
|
||||
//******************************************************************************************
|
||||
// File: S_TimedRelay.h
|
||||
// Authors: Dan G Ogorchock
|
||||
//
|
||||
// Summary: S_TimedRelay is a class which implements the SmartThings "Relay" device capability. It features
|
||||
// an automatic-turn-off time delay for a relay to emulate a button press.
|
||||
//
|
||||
// It inherits from the st::Sensor class and clones much from the st::Executor Class
|
||||
//
|
||||
// Create an instance of this class in your sketch's global variable section
|
||||
// For Example: st::S_TimedRelay sensor1(F("relaySwitch1"), PIN_RELAY, LOW, true, 1000, 0, 1, 0);
|
||||
//
|
||||
// st::S_TimedRelay() constructor requires the following arguments
|
||||
// - String &name - REQUIRED - the name of the object - must match the Groovy ST_Anything DeviceType tile name
|
||||
// - byte pinOutput - REQUIRED - the Arduino Pin to be used as a digital output
|
||||
// - bool startingState - REQUIRED - the value desired for the initial state of the switch. LOW = "off", HIGH = "on"
|
||||
// - bool invertLogic - REQUIRED - determines whether the Arduino Digital Ouput should use inverted logic
|
||||
// - long onTime - REQUIRED - the number of milliseconds to keep the output on, DEFAULTS to 1000 milliseconds
|
||||
// - long offTime - OPTIONAL - the number of milliseconds to keep the output off, DEFAULTS to 0
|
||||
// - int numCycles - OPTIONAL - the number of times to repeat the on/off cycle, DEFAULTS to 1
|
||||
// - byte finalState - OPTIONAL - leave in X state after finishing sequence 0 = off, 1 = on , Defaults to 0
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-12-29 Dan Ogorchock Original Creation
|
||||
// 2018-08-30 Dan Ogorchock Modified comment section above to comply with new Parent/Child Device Handler requirements
|
||||
// 2019-06-23 Brian Wilson Added finalState option
|
||||
// 2019-08-10 Dan Ogorchock Added public getStatus()
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_S_TIMEDRELAY_H
|
||||
#define ST_S_TIMEDRELAY_H
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
class S_TimedRelay : public Sensor //inherits from parent Sensor Class
|
||||
{
|
||||
private:
|
||||
|
||||
//following are for the digital output
|
||||
bool m_bCurrentState; //HIGH or LOW
|
||||
bool m_bInvertLogic; //determines whether the Arduino Digital Output should use inverted logic
|
||||
byte m_nOutputPin; //Arduino Pin used as a Digital Output for the switch - often connected to a relay or an LED
|
||||
unsigned long m_lOnTime; //number of milliseconds to keep digital output HIGH before automatically turning off
|
||||
unsigned long m_lOffTime; //number of milliseconds to keep digital output LOW before automatically turning on
|
||||
unsigned int m_iNumCycles; //number of on/off cycles of the digital output
|
||||
unsigned int m_iCurrentCount; //current number of on/off cycles of the digital output
|
||||
byte m_nfinalState; //desired final state of the output after the cycling has completed (typical value is 0)
|
||||
unsigned long m_lTimeChanged; //time when the digital output was last changed
|
||||
bool m_bTimerPending; //true if waiting on relay timer to expire
|
||||
|
||||
void writeStateToPin(); //function to update the Arduino Digital Output Pin
|
||||
|
||||
public:
|
||||
//constructor - called in your sketch's global variable declaration section
|
||||
S_TimedRelay(const __FlashStringHelper *name, byte pinOutput, bool startingState = LOW, bool invertLogic = false, unsigned long onTime = 1000, unsigned long offTime = 0, unsigned int numCycles = 1, byte finalState = 0);
|
||||
|
||||
//destructor
|
||||
virtual ~S_TimedRelay();
|
||||
|
||||
//initialization function
|
||||
virtual void init();
|
||||
|
||||
//update function
|
||||
void update();
|
||||
|
||||
//SmartThings Shield data handler (receives command to turn "on" or "off" the switch (digital output)
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//called periodically by Everything class to ensure ST Cloud is kept consistent with the state of the contact sensor
|
||||
virtual void refresh();
|
||||
|
||||
//gets
|
||||
virtual byte getPin() const { return m_nOutputPin; }
|
||||
virtual bool getTimerActive() const { return m_bTimerPending; }
|
||||
virtual bool getStatus() const { return m_bCurrentState; }
|
||||
|
||||
//sets
|
||||
virtual void setOutputPin(byte pin);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
46
lib/ST_Anything/Sensor.cpp
Normal file
46
lib/ST_Anything/Sensor.cpp
Normal file
@@ -0,0 +1,46 @@
|
||||
//******************************************************************************************
|
||||
// File: Sensor.cpp
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Sensor is a generic class which inherits from st::Device. This is the
|
||||
// parent class for the st::PollingSensor and st::InterruptSensor classes.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#include "Sensor.h"
|
||||
|
||||
#include "Constants.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//private
|
||||
|
||||
|
||||
//public
|
||||
//constructor
|
||||
Sensor::Sensor(const __FlashStringHelper *name):
|
||||
Device(name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//destructor
|
||||
Sensor::~Sensor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void Sensor::beSmart(const String &str)
|
||||
{
|
||||
//Each derived class should implement this if they are interfacing with SmartThings over the internet.
|
||||
}
|
||||
|
||||
}
|
||||
50
lib/ST_Anything/Sensor.h
Normal file
50
lib/ST_Anything/Sensor.h
Normal file
@@ -0,0 +1,50 @@
|
||||
//******************************************************************************************
|
||||
// File: Sensor.h
|
||||
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
|
||||
//
|
||||
// Summary: st::Sensor is a generic class which inherits from st::Device. This is the
|
||||
// parent class for the st::PollingSensor and st::InterruptSensor classes.
|
||||
// In general, this file should not need to be modified.
|
||||
//
|
||||
// Change History:
|
||||
//
|
||||
// Date Who What
|
||||
// ---- --- ----
|
||||
// 2015-01-03 Dan & Daniel Original Creation
|
||||
// 2019-02-09 Dan Ogorchock Moved update() from Sensor to Device
|
||||
//
|
||||
//
|
||||
//******************************************************************************************
|
||||
|
||||
#ifndef ST_SENSOR_H
|
||||
#define ST_SENSOR_H
|
||||
|
||||
#include "Device.h"
|
||||
|
||||
namespace st
|
||||
{
|
||||
//abstract
|
||||
class Sensor: public Device
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
//constructor
|
||||
Sensor(const __FlashStringHelper *name);
|
||||
|
||||
//destructor
|
||||
virtual ~Sensor();
|
||||
|
||||
//SmartThings Shield data handler
|
||||
virtual void beSmart(const String &str);
|
||||
|
||||
//all derived classes must implement these pure virtual functions
|
||||
virtual void init()=0;
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user