[RELEASE] ST_Anything - Arduino/ESP8266/ESP32

Yes, you’re making sense, however it doesn’t really fit well into any of the existing, implemented, standard ST Capabilities. There is no 'Distance Measurement" Capability currently. The closest thing to it would probably the “Voltage Measurement” capability. That provides a raw floating point value, but when you look at the device in your ST App, you will see a voltage display, not a “Present” or “Away” status. Most people want to look at the device and know more than just a raw numeric value with no context as to what it means. We could expose both, the “Presence Sensor” and “Voltage Measurement” capabilities to a new Child Ultrasonic DH. In the Device Settings, you would configure the threshold for “Away” vs “Present”. I still think it would be much simpler to build a webCoRE rule off of the “Presence Sensor” capability vs the raw value. You always have to go into the webCoRE rule to change the threshold instead of just tweaking the device’s settings.

I’ve got a bit of a busy schedule for the next few days, so no promises on how quickly I can get to this.

I really don’t know what to tell you at this point. Have you tried using a Windows PC to run the Arduino IDE on? Perhaps the Linux OS’s case sensitive file naming is causing an issue? Just a guess. If so, let me know if any of the code needs to have any of the #include<> statements modified to account for a case-sensitive operating system.

My first setup was on a windows 10 pc and my second was on my Linux laptop. Both gave same error, very strange. I completely removed all Arduino from Linux laptop.
Oh well I’ll keep plugging away. Thanks for your help. Big fan of your work too.

1 Like

Beggers can’t be choosers! I’ve said it many times, but I seriously appreciate your assistance. Without that, I would have been nowhere.

So I was able to get the sensor working. Seems the LUX is very low especially if compared to another LUX sensor. I am showing readings of 0 and 5. When I shine a 800 lumen flashlight directly at the sensor it shoots up to 550. Curious if there is anything else I need to modify to get better readings. Suggestions?

Hi Dan, hope you are doing well.
I have now the lights of my entire house been controlled by 4 arduinos mega, with about 16 relay and 20 buttons for each arduino. (All wired up)
Everything works well most of the time… But time to time (probably every 10 to 30 minutes or so) the arduino stuck for a few seconds and than comes back again. So it becomes irresponsive during this time… And some times I have to reset the arduino to get it back.
I believe this may have something to do with the communication with the hub, or maybe with the Internet. It seams the loop is interrupt for some reason.
Do you have any idea how could I find the problem? Or have some suggestions?
Keep in mind you are talking to a “cave man” in therms of programming. so I don’t have any idea how most of your code works… Lol

Thank you very much Dan!

Every 5 mins, by default, ST_Anything refreshes all of the device statuses to ST. If you look in Constants.h (found in the ST_Anything library) you’ll find a couple of lines of code specifying how frequently this update is performed, and whether or not you want theses regular updates.

Try disabling this feature, as this keeps the Arduino busy for a while if you have a large number of devices defined. During this time, the system will be slow to respond.

The reason for this periodic refresh is to make sure ST always is kept up to date. It is not required, but you may end up with situations where ST and the Arduino could be out of sync.

Hi, I’m fairly new to smartthings but have had a little bit experience with raspberry pi arduino and esp8266. I have managed (reading and reading again) to get my nodemcu 12e flashed and working with the multiple flash. As I understand github doesn’t integrate in the UK so I copied the raw code in for child devices. I would like to use 4 DS18B20 temp sensors which are currently on a raspberry pi via speakthings mqtt. I take it I need to edit the sketch. On raspi I can bring all the data form 4 sensors into 1 pin. Do I need to use 4 pins and what about the 4k7 resistor do i use 4?. I would also like to use a couple of door contacts, do I set them to go high or low. If there is any documentation around about this I would love to read it. I would like to thank Daniel for the hours of work put into this project.
Regards Ray

I don’t currently have mine plugged in but I probably could test this weekend. I do remember indoor lighting being pretty low and when the Sun came out it shot up like it did with your flashlight. But 0 - 5 for ambient light seems really low.

I thought I put some debug lines into the code so if you are using serial monitor you’ll see the raw values being passed from the sensor. I’m not doing any kind of conversions or anything else on the data, literally making a call for the raw data and passing it to your hub. So if what shows up in serial monitor is what is showing in the device Handler then that is the data being passed from that sensor. Whether the sensor is correct or not I can’t tell you.


The DS18B20 support allows for multiple sensors on a single pin. The last argument in the constructor is the number of sensors that the software should expect to find. If this value is greater than 1, the first argument should be “temperature” as the numeric suffix will be added automatically by the software. If the last argument is equal to 1, the first argument should be “temperature1”. Wiring should be the same as for the raspberry pi, similar to the image below (ignore the 5V Vdd, as your ESP8266 will be 3.3V. do not connect the DS18B20 to a 5v supply if using a 3.3v board like the ESP8266!)


As for contact sensors (magnetic reed switches), those are easy. Just connect one wire to GND on the ESP8266, and the other to the corresponding PIN defined in the sketch for each sensor. In the example below, the internal pull-up resistor feature is enabled, which will supply 3.3v on each pin.

Here is a sketch that should meet your needs - I have not compiled or tested it, but it should be fine.

//  File: ST_Anything_Multiples_ESP8266WiFi.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_Multiples implements the following ST Capabilities as a demo of what is possible with a single NodeMCU ESP8266
//              - 1 x Alarm device (using a simple digital output)
//              - 1 x Contact Sensor devices (used to monitor magnetic door sensors)
//              - 1 x Switch devices (used to turn on a digital output (e.g. LED, relay, etc...)
//              - 1 x Motion devices (used to detect motion)
//              - 1 x Smoke Detector devices (using simple digital input)
//              - 1 x Temperature Measurement devices (Temperature from Dallas Semi 1-Wire DS18B20 device)
//              - 1 x Relay Switch devices (used to turn on a digital output for a set number of cycles And On/Off times (e.g.relay, etc...))
//              - 2 x Button devices (sends "pushed" if held for less than 1 second, else sends "held"
//              - 1 x Water Sensor devices (using the 1 analog input pin to measure voltage from a water detector board)
//  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
//    2018-02-09  Dan Ogorchock  Added support for Hubitat Elevation Hub
// 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_CONTACT_1             D1  //SmartThings Capabilty "Contact Sensor"
#define PIN_CONTACT_2             D2  //SmartThings Capabilty "Contact Sensor"
#define PIN_CONTACT_3             D5  //SmartThings Capabilty "Contact Sensor"
#define PIN_CONTACT_4             D6  //SmartThings Capabilty "Contact Sensor"
#define PIN_TEMPERATURE_1         D7  //SmartThings Capabilty "Temperature Measurement" (Dallas Semiconductor DS18B20)

//ESP8266 WiFi Information
String str_ssid     = "yourSSIDhere";                           //  <---You must edit this line!
String str_password = "yourWiFiPasswordhere";                   //  <---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 / Hubitat Hub TCP/IP Address
IPAddress hubIp(192, 168, 1, 149);    // smartthings/hubitat hub ip //  <---You must edit this line!

// SmartThings / Hubitat Hub TCP/IP Address: UNCOMMENT line that corresponds to your hub, COMMENT the other
const unsigned int hubPort = 39500;   // smartthings hub port
//const unsigned int hubPort = 39501;   // hubitat 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
//			  st::PS_DS18B20_Temperature() constructor requires the following arguments
//				- String &name - REQUIRED - the name of the object - if only 1 sensor, use "temperature1", if multiple use "temperature" as the number will be added automatically
//				- 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 for the One-Wire DS18B20 sensor conenction
//				- bool In_C - OPTIONAL - true = Report Celsius, false = Report Farenheit (Farentheit is the default)
//				- byte resolution - OPTIONAL - DS18B20 sensor resolution in bits.  9, 10, 11, or 12.  Defaults to 10 for decent accuracy and performance
//				- byte num_sensors - OPTIONAL - number of OneWire DS18B20 sensors attached to OneWire bus - Defaults to 1

  static st::PS_DS18B20_Temperature sensor1(F("temperature"), 15, 0, PIN_TEMPERATURE_1, false, 10, 4); 
  //Interrupt Sensors 
//			  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)
  static st::IS_Contact             sensor2(F("contact1"), PIN_CONTACT_1, LOW, true);
  static st::IS_Contact             sensor3(F("contact2"), PIN_CONTACT_2, LOW, true);
  static st::IS_Contact             sensor4(F("contact3"), PIN_CONTACT_3, LOW, true);
  static st::IS_Contact             sensor5(F("contact4"), PIN_CONTACT_4, LOW, true);

  //Special sensors/executors (uses portions of both polling and executor classes)
  //  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

  //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
  //Add each sensor to the "Everything" Class
  //Add each executor to the "Everything" Class

  //Initialize each of the devices which were added to the Everything Class

//Arduino Loop() routine
void loop()
  //Execute the Everything run method which takes care of "Everything"

Hi Dan
Thanks for the very prompt and detailed reply, I will try this asap. Within smartthings do i need to delete the existing parent and reset everything or can I just delete the children?
Regards Ray

Have you thought about using a sensor like this:

Depending on the layout of your garage and how comfortable you are with wiring this could be a lot more practical and dependable than a presence sensor. You might also look into a pressure pad that could go under your tire.

1 Like


Yes, if you’re using the exact same ESP8266, it is best to simply delete the parent device using the ST App on your phone. Doing so will delete the child devices. Then simply recreate the parent. It’s annoying, I know. Something changed on the ST Cloud Backend that has resulted in problems if you just delete a child. I tried for days to fix the issue, but no luck.


Hi Dan
Fantastic, all 4 contacts work and all 4 temps work off the same pins. I deleted the parent after the flash and they all came up. However I got an extra duplicate of temp 4 showing 0 degrees, so I deleted it, and as you wrote it broke the parent. (i’m getting quick at putting the parent back now!). Things are working very sweet just tried the simple logger smart app and it recording values to google sheets, neat! Question: I cant find any way to automate the temps, to say turn a switch on when a certain temperature is reached. Is this possible?
Thanks for all your time and support.
Regards Ray

I would recommend you look into webCoRE, as it is a very powerful Rules Engine for SmartThings. If it can be automated, webCoRE can do it.

1 Like

My intention is to install the ultrasonic sensor overhead. Don’t think that would work with the IR sensor. Installing it on the side next to the vehicles is also not an option because of the layout of the garages (vehicles stopped next to each other without any walls between them, in other words, a single enclosure with multiple garage doors.)

Hi dan
Many thanks for all your help,will give webCoRe a look.
Regards Ray

I have been planning to do the same exact thing for along time. Perhaps we should work together.

I have my garage open/close and a temp sensor out there right now but it is all on a particle photon. I am going to move it over to an ESP8266.

I want to add two sonic sensors to detect the presence of two cars next.

Dan helped me to get a water level sensor going. He is going to adapt the DTH of that setup when he has some spare time, so that it can be used as a Car-In-Garage sensor. Or perhaps you have the programming skills to assist with the changes to which have to be made to the DTH ?
If you want to get the hardware setup so long, you can look at this post.

Dan wrote the sketch for the ESP01 module (because that is what I started out with, but once I had it all set up, I realised that the ESP01 won’t boot with the sensor connected (with the sensor connected, it goes into flashing mode)). I’m now using the NodeMCU instead of the ESP01. I now nothing about programming, but was able to use the same sketch with the NodeMCU. All I had to do, was to change the pin setup in the sketch. (Let me know if I can help you with that).

The sensor I’m using is same as referred to in this post.

By the way, I had a hard time getting the water level set up to work, because I know nothing about programming. The fact that many of the NodeMCU’s I purchased were bad, complicated things a lot for me. It was only after many hours that I realised that it was not a case of me doing the flashing incorrectly, but because the units were bad. I purchased 5, of which 2 would not connect to the wifi network and the third drops the network continuously, even though my test bench is located less than 6 meters from the wifi access point. Once I had one working correctly, the rest was fairly easy. The water level sensor works fantastic and appears to be extremely accurate.

Hi Dan

here is solution that seems to work. My friend and neighbor Dan came up with this temporary fix. hope this helps


  //Polling Sensors

  // Dan's Fix
const __FlashStringHelper* test1 = (const __FlashStringHelper*) "temphumid1";

  st::PS_TemperatureHumidity sensor2(test1, 120, 7, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT11, "temperature1", "humidity1", false);

  //Interrupt Sensors 

I’m having trouble getting the PS_TemperatureHumidy function to compile in the sample ST_Anything_AlarmPanel_ESP8266_TEST.ino.
no matching function for call to ‘st::PS_TemperatureHumidity::PS_TemperatureHumidity(const char [11], int, int, int, st::PS_TemperatureHumidity::DHT_SENSOR, const char [13], const char [10], bool)’

something about “candidate expects 1 argument, 8 provided”

Is this where I should supply my full code and errors?