[DEPRECATED] ST_Anything - Arduino/ESP8266/ESP32

It might be fairly straightforward… :wink:

In the ST_Anything_Relays_Buttons_ESP8266WiFi.ino sketch, try changing the following three sections of code as shown below. This is where I’d start… You may need to debug things a bit. All of the manual button logic is all self contained within the sketch. It was done as an example for users, as are all of the sketches. Have fun!

From

  //EX_Switch arguments(name, pin, starting state,  invert logic) change last 2 args as needed for your application 
  static st::EX_Switch executor1(F("switch1"), PIN_RELAY_1, LOW, true);
  static st::EX_Switch executor2(F("switch2"), PIN_RELAY_2, LOW, true);
  static st::EX_Switch executor3(F("switch3"), PIN_RELAY_3, LOW, true);

To

  //Special sensors/executors (uses portions of both polling and executor classes)
  static st::S_TimedRelay sensor1(F("relaySwitch1"), PIN_RELAY_1, LOW, true, 3000, 0, 1);
  static st::S_TimedRelay sensor2(F("relaySwitch2"), PIN_RELAY_2, LOW, true, 3000, 0, 1);
  static st::S_TimedRelay sensor3(F("relaySwitch3"), PIN_RELAY_3, LOW, true, 3000, 0, 1);

AND

From

  st::Everything::addExecutor(&executor1);
  st::Everything::addExecutor(&executor2);
  st::Everything::addExecutor(&executor3);

To

  st::Everything::addSensor(&sensor1);
  st::Everything::addSensor(&sensor2);
  st::Everything::addSensor(&sensor3); 

AND

From

  //---Begin Push Button initialization section---
  swArray[0]=&executor1;
  swArray[1]=&executor2;
  swArray[2]=&executor3;  

To

  //---Begin Push Button initialization section---
  swArray[0]=&sensor1;
  swArray[1]=&sensor2;
  swArray[2]=&sensor3;  

Thank you for the reply. I tried that after I posted the question, I realized the static st::S_TimedRelay sensor1(F(“relaySwitch1”), PIN_RELAY_1, LOW, true, 3000, 0, 1); is for the hub and app and I could use the same switch logic to change the state of the relay pins. I was not sure how the besmart fuction worked. When I setup the code as you suggested I was getting a error ‘class st::S_TimedRelay’ has no member named ‘getStatus’. I tried to modify the TimedRelay.cpp file to add the function but it didn’t work.

Thank you,

Chris

Chris

Chris,

Here is a version of the sketch that successfully compiles. You will need the new version of S_TimedRelay.h that I just uploaded to my GitHub repository. I have not tested this sketch, but at least it compiles without error. Please let me know if it works.

//******************************************************************************************
// File: ST_Anything_TimedRelays_Butttons_ESP8266.ino
// Authors: Dan G Ogorchock & Daniel J Ogorchock (Father and Son)
//
// Summary: This Arduino Sketch, along with the ST_Anything library and the revised SmartThings
//          library, demonstrates the ability of one NodeMCU ESP8266 to
//          implement a multi input/output custom device for integration into SmartThings.
//
//          The ST_Anything library takes care of all of the work to schedule device updates
//          as well as all communications with the NodeMCU ESP8266’s WiFi.
//
//          ST_Anything_Relays_Buttons_ESP8266 implements the following ST Capabilities as a demo 
//          of what is possible with a single NodeMCU ESP8266
//            - 3 x TimedRelay devices
//
//
// Change History:
//
//    Date        Who            What
//    ----        ---            ----
//    2015-01-03  Dan & Daniel   Original Creation
//    2017-02-12  Dan Ogorchock  Revised to use the new SMartThings v2.0 library
//    2017-04-17  Dan Ogorchock  New example showing use of Multiple device of same ST Capability
//                               used with new Parent/Child Device Handlers (i.e. Composite DH)
//    2017-05-25  Dan Ogorchock  Revised example sketch, taking into account limitations of NodeMCU GPIO pins
//    2017-11-29  Dan Ogorchock  New example to showcase local control using momentary buttons
//    2019-08-10  Dan Ogorchock  New example using TimedRelays instead of Switches
//
//******************************************************************************************
//******************************************************************************************
// SmartThings Library for ESP8266WiFi
//******************************************************************************************
#include <SmartThingsESP8266WiFi.h>

//******************************************************************************************
// ST_Anything Library
//******************************************************************************************
#include <Constants.h> //Constants.h is designed to be modified by the end user to adjust behavior of the ST_Anything library
#include <Device.h> //Generic Device Class, inherited by Sensor and Executor classes
#include <Sensor.h> //Generic Sensor Class, typically provides data to ST Cloud (e.g. Temperature, Motion, etc…)
#include <Executor.h> //Generic Executor Class, typically receives data from ST Cloud (e.g. Switch)
#include <InterruptSensor.h> //Generic Interrupt "Sensor" Class, waits for change of state on digital input
#include <PollingSensor.h> //Generic Polling "Sensor" Class, polls Arduino pins periodically
#include <Everything.h> //Master Brain of ST_Anything library that ties everything together and performs ST Shield communications

#include <PS_Illuminance.h> //Implements a Polling Sensor (PS) to measure light levels via a photo resistor

#include <PS_TemperatureHumidity.h> //Implements a Polling Sensor (PS) to measure Temperature and Humidity via DHT library
#include <PS_DS18B20_Temperature.h> //Implements a Polling Sesnor (PS) to measure Temperature via DS18B20 libraries
#include <PS_Water.h> //Implements a Polling Sensor (PS) to measure presence of water (i.e. leak detector)
#include <IS_Motion.h> //Implements an Interrupt Sensor (IS) to detect motion via a PIR sensor
#include <IS_Contact.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <IS_Smoke.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin
#include <IS_DoorControl.h> //Implements an Interrupt Sensor (IS) and Executor to monitor the status of a digital input pin and control a digital output pin
#include <IS_Button.h> //Implements an Interrupt Sensor (IS) to monitor the status of a digital input pin for button presses
#include <EX_Switch.h> //Implements an Executor (EX) via a digital output to a relay
#include <EX_Alarm.h> //Implements Executor (EX)as an Alarm Siren capability via a digital output to a relay
#include <S_TimedRelay.h> //Implements a Sensor to control a digital output pin with timing capabilities

//*************************************************************************************************
//NodeMCU v1.0 ESP8266-12e Pin Definitions (makes it much easier as these match the board markings)
//*************************************************************************************************
//#define LED_BUILTIN 16
//#define BUILTIN_LED 16
//
//#define D0 16  //no internal pullup resistor
//#define D1  5
//#define D2  4
//#define D3  0  //must not be pulled low during power on/reset, toggles value during boot
//#define D4  2  //must not be pulled low during power on/reset, toggles value during boot
//#define D5 14
//#define D6 12
//#define D7 13
//#define D8 15  //must not be pulled high during power on/reset

//******************************************************************************************
//Define which Arduino Pins will be used for each device
//******************************************************************************************

#define PIN_RELAY_1 D5 //SmartThings Capability "Relay Switch"
#define PIN_RELAY_2 D6 //SmartThings Capability "Relay Switch"
#define PIN_RELAY_3 D7 //SmartThings Capability "Relay Switch"

//---Begin Push Button declarations---
#define MAX_PUSHBUTTONS 3
#define MIN_DEBOUNCE_TIME 50 //push-buttons must be held for 50ms to prevent chattering input

#define PIN_BUTTON1   D1
#define PIN_BUTTON2   D2
#define PIN_BUTTON3   D3

byte nBtnIndex;      //Index Variable
bool nCurrentVal;     //temp variable
String strCommand; 
byte nBtnVals[MAX_PUSHBUTTONS][2];   //Array of current[0] and last[1] values of the pushbuttons
byte nBtnPins[MAX_PUSHBUTTONS] = {PIN_BUTTON1, PIN_BUTTON2, PIN_BUTTON3};
unsigned long lngBtnLastMillis[MAX_PUSHBUTTONS]; //needed to properly debounce the pushbutton inputs
st::S_TimedRelay* swArray[MAX_PUSHBUTTONS]; //need an array of the executors so we can togle the correct one
//---End Push Button declarations--- 


//******************************************************************************************
//ESP8266 WiFi Information
//******************************************************************************************
String str_ssid     = "yourSSIDhere";                            //  <---You must edit this line!
String str_password = "yourPASSWORDhere";                          //  <---You must edit this line!
IPAddress ip(192, 168, 1, 227);       //Device IP Address       //  <---You must edit this line!
IPAddress gateway(192, 168, 1, 1);    //Router gateway          //  <---You must edit this line!
IPAddress subnet(255, 255, 255, 0);   //LAN subnet mask         //  <---You must edit this line!
IPAddress dnsserver(192, 168, 1, 1);  //DNS server              //  <---You must edit this line!
const unsigned int serverPort = 8090; // port to run the http server on

// Smartthings Hub Information
IPAddress hubIp(192, 168, 1, 149);    // smartthings hub ip     //  <---You must edit this line!
const unsigned int hubPort = 39500;   // smartthings hub port

//******************************************************************************************
//st::Everything::callOnMsgSend() optional callback routine.  This is a sniffer to monitor 
//    data being sent to ST.  This allows a user to act on data changes locally within the 
//    Arduino sktech.
//******************************************************************************************
void callback(const String &msg)
{
//  Serial.print(F("ST_Anything Callback: Sniffed data = "));
//  Serial.println(msg);
  
  //TODO:  Add local logic here to take action when a device's value/state is changed
  
  //Masquerade as the ThingShield to send data to the Arduino, as if from the ST Cloud (uncomment and edit following line)
  //st::receiveSmartString("Put your command here!");  //use same strings that the Device Handler would send
}

//******************************************************************************************
//Arduino Setup() routine
//******************************************************************************************
void setup()
{
  //******************************************************************************************
  //Declare each Device that is attached to the Arduino
  //  Notes: - For each device, there is typically a corresponding "tile" defined in your 
  //           SmartThings Device Hanlder Groovy code, except when using new COMPOSITE Device Handler
  //         - For details on each device's constructor arguments below, please refer to the 
  //           corresponding header (.h) and program (.cpp) files.
  //         - The name assigned to each device (1st argument below) must match the Groovy
  //           Device Handler names.  (Note: "temphumid" below is the exception to this rule
  //           as the DHT sensors produce both "temperature" and "humidity".  Data from that
  //           particular sensor is sent to the ST Hub in two separate updates, one for 
  //           "temperature" and one for "humidity")
  //         - The new Composite Device Handler is comprised of a Parent DH and various Child
  //           DH's.  The names used below MUST not be changed for the Automatic Creation of
  //           child devices to work properly.  Simply increment the number by +1 for each duplicate
  //           device (e.g. contact1, contact2, contact3, etc...)  You can rename the Child Devices
  //           to match your specific use case in the ST Phone Application.
  //******************************************************************************************
  //Polling Sensors
  
  //Special sensors/executors (uses portions of both polling and executor classes)
  static st::S_TimedRelay sensor1(F("relaySwitch1"), PIN_RELAY_1, LOW, true, 3000, 0, 1);
  static st::S_TimedRelay sensor2(F("relaySwitch2"), PIN_RELAY_2, LOW, true, 3000, 0, 1);
  static st::S_TimedRelay sensor3(F("relaySwitch3"), PIN_RELAY_3, LOW, true, 3000, 0, 1);

  //EX_Switch arguments(name, pin, starting state,  invert logic) change last 2 args as needed for your application 
//  static st::EX_Switch executor1(F("switch1"), PIN_RELAY_1, LOW, true);
//  static st::EX_Switch executor2(F("switch2"), PIN_RELAY_2, LOW, true);
//  static st::EX_Switch executor3(F("switch3"), PIN_RELAY_3, LOW, true);


  //*****************************************************************************
  //  Configure debug print output from each main class 
  //  -Note: Set these to "false" if using Hardware Serial on pins 0 & 1
  //         to prevent communication conflicts with the ST Shield communications
  //*****************************************************************************
  st::Everything::debug=true;
  st::Executor::debug=true;
  st::Device::debug=true;
  st::PollingSensor::debug=true;
  st::InterruptSensor::debug=true;

  //*****************************************************************************
  //Initialize the "Everything" Class
  //*****************************************************************************

  //Initialize the optional local callback routine (safe to comment out if not desired)
  st::Everything::callOnMsgSend = callback;
  
  //Create the SmartThings ESP8266WiFi Communications Object
    //STATIC IP Assignment - Recommended
    st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, ip, gateway, subnet, dnsserver, serverPort, hubIp, hubPort, st::receiveSmartString);
 
    //DHCP IP Assigment - Must set your router's DHCP server to provice a static IP address for this device's MAC address
    //st::Everything::SmartThing = new st::SmartThingsESP8266WiFi(str_ssid, str_password, serverPort, hubIp, hubPort, st::receiveSmartString);

  //Run the Everything class' init() routine which establishes WiFi communications with SmartThings Hub
  st::Everything::init();
  
  //*****************************************************************************
  //Add each sensor to the "Everything" Class
  //*****************************************************************************
  st::Everything::addSensor(&sensor1);
  st::Everything::addSensor(&sensor2);
  st::Everything::addSensor(&sensor3); 
      
  //*****************************************************************************
  //Add each executor to the "Everything" Class
  //*****************************************************************************
//  st::Everything::addExecutor(&executor1);
//  st::Everything::addExecutor(&executor2);
//  st::Everything::addExecutor(&executor3);
      
  //*****************************************************************************
  //Initialize each of the devices which were added to the Everything Class
  //*****************************************************************************
  st::Everything::initDevices();

  //*****************************************************************************
  //Add User Customized Setup Code Here (instead of modifying standard library files)
  //*****************************************************************************
  //---Begin Push Button initialization section---
//  swArray[0]=&executor1;
//  swArray[1]=&executor2;
//  swArray[2]=&executor3;  
  swArray[0]=&sensor1;
  swArray[1]=&sensor2;
  swArray[2]=&sensor3;  

  //Allocate strCommand buffer one time to prevent Heap Fragmentation.
  strCommand.reserve(20);

  //Configure input pins for hardwired pusbuttons AND read initial values
  for (nBtnIndex=0; nBtnIndex < MAX_PUSHBUTTONS; nBtnIndex++) {
    pinMode(nBtnPins[nBtnIndex], INPUT_PULLUP);
    nBtnVals[nBtnIndex][0] = digitalRead(nBtnPins[nBtnIndex]);   // read the input pin
    nBtnVals[nBtnIndex][1] = nBtnVals[nBtnIndex][0];
    lngBtnLastMillis[nBtnIndex] = 0;  //initialize times to zero
  }
 //---End Push Button initialization section---
}

//******************************************************************************************
//Arduino Loop() routine
//******************************************************************************************
void loop()
{
  //*****************************************************************************
  //Execute the Everything run method which takes care of "Everything"
  //*****************************************************************************
  st::Everything::run();

  //*****************************************************************************
  //Add User Customized Loop Code Here (instead of modifying standard library files)
  //*****************************************************************************
  
  //---Begin Push Button execution section---
  //Loop through the pushbutton array
  for (nBtnIndex=0; nBtnIndex < MAX_PUSHBUTTONS; nBtnIndex++) 
  {
    nCurrentVal = digitalRead(nBtnPins[nBtnIndex]); // read the input pin   
    if (nCurrentVal != nBtnVals[nBtnIndex][1])      // only act if the button changed state
    {
      lngBtnLastMillis[nBtnIndex] = millis();  //keep track of when the button changed state
    }
    if ((millis() - lngBtnLastMillis[nBtnIndex] >= MIN_DEBOUNCE_TIME) && (nBtnVals[nBtnIndex][0] != nCurrentVal))
    {
      nBtnVals[nBtnIndex][0] = nCurrentVal; //keep current value for proper debounce logic
      if (nCurrentVal == LOW)    //only care if the button is pressed (change LOW to HIGH if logic reversed)
      {
        strCommand = swArray[nBtnIndex]->getName() + " " + (swArray[nBtnIndex]->getStatus()== HIGH?"off":"on");
        Serial.print(F("Pushbutton: "));
        Serial.println(strCommand);
        swArray[nBtnIndex]->beSmart(strCommand);  //Call the beSmart function of the proper executor object to either turn on or off the relay
        strCommand.remove(0); //clear the strCommand buffer
      }
    }
    nBtnVals[nBtnIndex][1] = nCurrentVal;  //keep last value for proper debounce logic
  }  
 //---End Push Button execution section---
}

Dan,

I tried the code but I received the following error Error compiling for board NodeMCU 1.0 (ESP-12E Module). The other sketches worked fine I am not sure what the issue is with this one. I wonder if it is something lost in copying it to a new sketch.

Chris

What was the error?

The error message is very long. Here is the first part. Can I attach a file in this forum?

Arduino: 1.8.9 (Windows 10), Board: “NodeMCU 1.0 (ESP-12E Module), 80 MHz, Flash, Disabled, All SSL ciphers (most compatible), 4M (3M SPIFFS), v2 Lower Memory, Disabled, None, Only Sketch, 921600”

WARNING: Category ‘’ in library OneWire is not valid. Setting to ‘Uncategorized’
In file included from C:\Users\Hum\Documents\Arduino\Relay_Button_aug09c\Relay_Button_aug09c.ino:58:0:

C:\Users\Hum\Documents\Arduino\libraries\ST_Anything/S_TimedRelay.h:31:3: error: stray ‘\302’ in program

ST_Anything/S_TimedRelay.h at master · DanielOgorchock/ST_Anything

^

C:\Users\Hum\Documents\Arduino\libraries\ST_Anything/S_TimedRelay.h:31:3: error: stray ‘\267’ in program
^

Multiple libraries were found for “Servo.h”
Used: C:\Users\Hum\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.5.2\libraries\Servo
Not used: C:\Program Files (x86)\Arduino\libraries\Servo
Multiple libraries were found for “OneWire.h”
Used: C:\Users\Hum\Documents\Arduino\libraries\OneWire
Not used: C:\Users\Hum\Documents\Arduino\libraries\arduino_95215
Multiple libraries were found for “DallasTemperature.h”
Used: C:\Users\Hum\Documents\Arduino\libraries\DallasTemperature
Not used: C:\Users\Hum\Documents\Arduino\libraries\Arduino-Temperature-Control-Library-master
exit status 1
Error compiling for board NodeMCU 1.0 (ESP-12E Module).

Chris

Are you sure you downloaded the latest full ST_Anything GitHub zip file? And then extracted the updated S_TimedRelay.h file and placed it into the ST_Anything library folder?

I saved the file from github and replaced the S_TimedRelay.h file. I did not download the full ST_Anything GitHub zip file. I will try that now.

Chris

I downloaded the full zip file and replaced the entire library. The problem still occurs. I tried the original relay sketch and had the same issue.

Chris

Dan,

Nevermind. I must have had a glitch the first time. I followed the instructions on GitHub to install the libraries and tried compiling. The code compiled and works well. Thank you.

Chris

1 Like

Is there a way to have ST report if it has lost connection to the parent and/or child devices?

Every child device has a “last updated” custom attribute you can use to determine whether or not the microcontroller has sent an update recently. Perhaps you could use something like WebCoRE to check to see how long it has been since the last update and then send you a notification?

Hi Dan,

I’ve just started tackling my next ST challenge - grabbing data from a wifi SD card. I’m planning to use a windows server to sit in the middle - I was starting to write a device handler to post the data to the ST Hub, when I realised I was basically trying to re-write ST_Anything (feels stupid).
So, I’m embarking on setting up for Windows, and I’ve hit my first snag - http://www.omnithing.net/ is saying “refused to connect” - is it down for a while?

Thanks,

James

So… ST_Anything and OmniThing are two different integrations, although they have similar roots. My son and I originally wrote ST_Anything, which only runs on Arduino IDE compatible micro-controllers. Later, my son, @leinax, wrote OmniThing as a successor to ST_Anything, which runs on a variety of platforms.

You’ll probably have more luck posting questions about OmniThing in its thread.

Hi Dan,

Apols - makes sense. Will do.

James

1 Like

Okay so I have managed to create smart blinds using a stepper motor and the code for a switch. Basically when the switch turns on the stepper moves x number of steps when i turns of it move back x number of steps. it working perfectly. I recently hit a bit of a hurdle. I would like to change the label associated with the with switch to be open, opening, closed, closing rather the on, turning on, off, turning off. I was looking that the groovy code located here https://github.com/DanielOgorchock/ST_Anything/blob/master/devicetypes/ogiewon/child-switch.src/child-switch.groovy
Line 42 - 45, Im not sure what I can change here that will produce the desired result without breaking the code. Any help is appreciated.

Hi Dan,
I’m having real issues getting Omnithing running on my Windows PC - all down to my lack of skills and familiarity with Visual Studio I think.
I’m beginning to think that Omnithing may be overkill for what I want to achieve…
I have a wifi SD card in my solar thermal & heating controller.
The controller logs data to it every minute - 12 temperatures (deg c), 2 flow rates (int, 0 to 1000), 2 pump rates (0 to 100%).
I want to get these in to ST so I can respond to them.
I have the SD card as a mapped drive on my windows server.
I figure that a small program (written in python for e.g.) could pull the latest values and send them by curl to ST.
I’m thinking that if I were to format the data correctly, I could just use another ST_Anything device as the receiver for this - would I be right?
It looks to me like you’re sending the name, followed by an ordinal, then white space, then the value (I’ve already got curl working from the PC to ST following this post:How can I receive LAN messages on the ST hub (when the messages can come at any point)?)

Best,

James

Yes, you’ve got the basic idea…however… I would not do it this way, knowing what I know now.

These days, I would format the data as json. OmniThing actually does this, thereby allowing an entire data structure to be transmitted at once.

Can you use st anything to control a sonoff th device

Possibly. You’d have to flash the Sonoff with an ESP8266 ST_Anything sketch, and know exactly which GPIO pins can be used.

There are many other integrations already available for Sonoff Devices… why not simply use one of those?