Announcing the "ST_Anything" Arduino/ThingShield Project

Thanks. I’ll reread the DH guide…

My devices in the ST_Anything_ESP8266.ino sketch are named the same as the tiles in the DH. They work fine but I have the temp as the main tile showing on the Things view and the rest show on the device details screen. I am trying to get the relay switch to show in the Things view like I did with the multiplexer and virtual device on my Uno setup. I’m not seeing how to do that in the DH.

That’s very easy to change! Back in the v1.x ST Phone App, you could select any tile as the main tile for the device. ST broke this functionality when they released v2.x of the Phone Apps.

Simply change the following lines of code in the Device Handler to adjust the order of the tiles.


For example, to have the Contact Sensor show up as the main tile for the device, change the first line as follows:


I have that. I’m trying to get both the temperature and the switch to show on the Things view.
I have a virtual thermostat smartapp that uses 2 separate devices. A NodeMCU ESP8266 to sense the temp and then a second ‘off the shelf’ outlet control to activate a fan. I’m trying to use the relay and temp on a single NodeMCU ESP8266 with the virtual thermostat smartapp and to do that (unless I nave something wrong) I need to have both the temp and switch show on the Things view…

Looking for some ideas. I have the below in place and can see each individual motion sensor triggering when activated. The issue is that I can’t view the motion sensors outside of the Arduino/ST_Anything. I’m thinking this is done with multiplexing and virtual sensors but I’m not certain where to start. I have looked but don’t quite understand how it’s done.

// File: ST_Anything_WiFiEsp.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 Arduino + ESP-01 board 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 ESP-01 board.
// This example requires the use of an Arduino MEGA2560 since the ESP-01 WiFi board
// needs a high-speed UART for communications. This example assumes the ESP-01 is
// connected to the MEGA’s “Serial1” UART on pins 18 & 19.
// 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-02-20 Dan Ogorchock Revised to use the ESP-01 board
// SmartThings Library for Arduino + ESP-01 board combination.
#include <SmartThingsWiFiEsp.h> //Library to provide API to the SmartThings ESP-01 WiFi board

// 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_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_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

//Define which Arduino Pins will be used for each device
// Notes: Arduino communicates with the ESP-01 using the “Serial1” Hardware Serial UART.
// This is on digital pins 18 & 19 on the Mega.
//“RESERVED” pins for ESP-01 - best to avoid
#define PIN_18_RESERVED 18 //reserved ESP-01 on MEGA
#define PIN_19_RESERVED 19 //reserved ESP-01 on MEGA

#define PIN_WATER A4
#define PIN_MOTION0 6
#define PIN_MOTION1 2
#define PIN_MOTION2 3
#define PIN_MOTION3 4
#define PIN_CONTACT 7
#define PIN_SWITCH 8
#define PIN_ALARM 9
#define PIN_BUTTON1 10
#define PIN_BUTTON2 11

//WiFiEsp Information
String str_ssid = // <—You must edit this line!
String str_password = "; // <—You must edit this line!
IPAddress ip(; // Device IP Address // <—You must edit this line!
const unsigned int serverPort = 8090; // port to run the http server on

// Smartthings hub information
IPAddress hubIp( // 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 = "));

//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 DeviceType Groovy code
// - 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
// DeviceType Tile name. (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”)
//Polling Sensors
static st::PS_Illuminance sensor1(F(“illuminance”), 120, 0, PIN_ILLUMINANCE, 0, 1024, 0, 1000);
static st::PS_TemperatureHumidity sensor2(F(“temphumid”), 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT22);
static st::PS_Water sensor3(F(“water”), 60, 20, PIN_WATER, 200);

//Interrupt Sensors
static st::IS_Motion sensor4(F(“motion0”), PIN_MOTION0, HIGH, false);
static st::IS_Motion sensor8(F(“motion1”), PIN_MOTION1, HIGH, false);
static st::IS_Motion sensor9(F(“motion2”), PIN_MOTION2, HIGH, false);
static st::IS_Motion sensor10(F(“motion3”), PIN_MOTION3, HIGH, false);

static st::IS_Contact sensor5(F(“contact”), PIN_CONTACT, LOW, true);
static st::IS_Button sensor6(F(“button:1”), PIN_BUTTON1);
static st::IS_Button sensor7(F(“button:2”), PIN_BUTTON2);

static st::EX_Switch executor1(F(“switch”), PIN_SWITCH, LOW, true);
static st::EX_Alarm executor2(F(“alarm”), PIN_ALARM, LOW, true);

// Configure debug print output from each main class

//Initialize the “Everything” Class

//Initialize the optional local callback routine (safe to comment out if not desired)
st::Everything::callOnMsgSend = callback;

//Create the SmartThings WiFiEsp (ESP-01) Communications Object
st::Everything::SmartThing = new st::SmartThingsWiFiEsp(&Serial1, str_ssid, str_password, ip, serverPort, hubIp, hubPort, st::receiveSmartString);

//Initialize the Serial1 baudrate to match your ESP-01’s baud rate (e.g. 9600, 57600, 115200)

//Run the Everything class’ init() routine which establishes Ethernet communications with the 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”

Device Handler

  • ST_Anything_Ethernet.device.groovy
  • Copyright 2017 Dan G Ogorchock
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except
  • in compliance with the License. You may obtain a copy of the License at:
  • Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
  • on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
  • for the specific language governing permissions and limitations under the License.
  • Change History:
  • Date Who What

  • 2017-02-08 Dan Ogorchock Original Creation
  • 2017-02-12 Dan Ogorchock Modified to work with Ethernet based devices instead of ThingShield


metadata {
definition (name: “ST_Anything_Ethernet”, namespace: “ogiewon”, author: “Dan Ogorchock”) {
capability "Configuration"
capability "Illuminance Measurement"
capability "Temperature Measurement"
capability "Relative Humidity Measurement"
capability "Water Sensor"
capability "Motion Sensor"
capability "Switch"
capability "Sensor"
capability "Alarm"
capability "Contact Sensor"
capability "Polling"
capability "Button"
capability “Holdable Button”

	command "test"
	command "alarmoff"

simulator {


// Preferences
preferences {
	input "ip", "text", title: "Arduino IP Address", description: "ip", required: true, displayDuringSetup: true
	input "port", "text", title: "Arduino Port", description: "port", required: true, displayDuringSetup: true
	input "mac", "text", title: "Arduino MAC Addr", description: "mac", required: true, displayDuringSetup: true
	input "illuminanceSampleRate", "number", title: "Light Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "temphumidSampleRate", "number", title: "Temperature/Humidity Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "waterSampleRate", "number", title: "Water Sensor Inputs", description: "Sampling Interval (seconds)", defaultValue: 30, required: true, displayDuringSetup: true
	input "numButtons", "number", title: "Number of Buttons", description: "Number of Buttons to be implemented", defaultValue: 0, required: true, displayDuringSetup: true


// Tile Definitions
tiles {
	valueTile("illuminance", "device.illuminance", width: 1, height: 1) {
		state("illuminance", label:'${currentValue} ${unit}', unit:"lux",
				[value: 9, color: "#767676"],
				[value: 315, color: "#ffa81e"],
				[value: 1000, color: "#fbd41b"]
    valueTile("temperature", "device.temperature", width: 1, height: 1) {
		state("temperature", label:'${currentValue}�', 
				[value: 31, color: "#153591"],
				[value: 44, color: "#1e9cbb"],
				[value: 59, color: "#90d2a7"],
				[value: 74, color: "#44b621"],
				[value: 84, color: "#f1d801"],
				[value: 95, color: "#d04e00"],
				[value: 96, color: "#bc2323"]
    valueTile("humidity", "device.humidity", inactiveLabel: false) {
		state "humidity", label:'${currentValue}% humidity', unit:""

    standardTile("water", "device.water", width: 1, height: 1) {
		state "dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
		state "wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"

	standardTile("motion0", "device.motion0", width: 1, height: 1) {
		state("active", label:'Kitchen', icon:"", backgroundColor:"#53a7c0")
		state("inactive", label:'Kitchen', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
    standardTile("motion1", "device.motion1", width: 1, height: 1) {
		state("active", label:'Droom', icon:"", backgroundColor:"#53a7c0")
		state("inactive", label:'Droom', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
    standardTile("motion2", "device.motion2", width: 1, height: 1) {
		state("active", label:'DStairs', icon:"", backgroundColor:"#53a7c0")
		state("inactive", label:'DStairs', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
    standardTile("motion3", "device.motion3", width: 1, height: 1) {
		state("active", label:'BroomUp', icon:"", backgroundColor:"#53a7c0")
		state("inactive", label:'BroomUp', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff")
    standardTile("switch", "device.switch", width: 1, height: 1, canChangeIcon: true) {
		state "off", label: '${name}', action: "switch.on", icon: "", backgroundColor: "#ffffff"
		state "on", label: '${name}', action: "", icon: "st.switches.switch.on", backgroundColor: "#79b821"

	standardTile("configure", "device.configure", inactiveLabel: false, decoration: "flat") {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"

	standardTile("contact", "", width: 1, height: 1) {
		state("open", label:'${name}', icon:"", backgroundColor:"#ffa81e")
		state("closed", label:'${name}', icon:"", backgroundColor:"#79b821")

	standardTile("alarm", "device.alarm", width: 1, height: 1) {
		state "off", label:'off', action:'alarm.siren', icon:"st.alarm.alarm.alarm", backgroundColor:"#ffffff"
        state "strobe", label:'', action:'alarmoff', icon:"st.secondary.strobe", backgroundColor:"#cccccc"
        state "siren", label:'siren!', action:'alarmoff', icon:"st.alarm.beep.beep", backgroundColor:"#e86d13"
		state "both", label:'alarm!', action:'alarmoff', icon:"st.alarm.alarm.alarm", backgroundColor:"#e86d13"

	standardTile("test", "device.alarm", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"test", icon:"st.secondary.test"
	standardTile("off", "device.alarm", , width: 1, height: 1) {
		state "default", label:'Alarm', action:"alarmoff", icon:""
	//standardTile("off", "device.alarm", inactiveLabel: false, decoration: "flat") {
	//	state "default", label:'', action:"alarmoff", icon:""



// parse events into attributes
def parse(String description) {
//log.debug "Parsing ‘${description}’"
def msg = parseLanMessage(description)
def headerString = msg.header

if (!headerString) {
	//log.debug "headerstring was null for some reason :("

def bodyString = msg.body

if (bodyString) {
    log.debug "BodyString: $bodyString"
	def parts = bodyString.split(" ")
	def name  = parts.length>0?parts[0].trim():null
	def value = parts.length>1?parts[1].trim():null
	def results = []
	if (name.startsWith("button")) {
    	def pieces = name.split(":")
        def btnName = pieces.length>0?pieces[0].trim():null
        def btnNum = pieces.length>1?pieces[1].trim():null
		//log.debug "In parse:  name = ${name}, value = ${value}, btnName = ${btnName}, btnNum = ${btnNum}"
    	results = createEvent([name: btnName, value: value, data: [buttonNumber: btnNum], descriptionText: "${btnName} ${btnNum} was ${value} ", isStateChange: true, displayed: true])
    else {
		results = createEvent(name: name, value: value)

	log.debug results
    return results



private getHostAddress() {
def ip = settings.ip
def port = settings.port

log.debug "Using ip: ${ip} and port: ${port} for device: ${}"
return ip + ":" + port


def sendEthernet(message) {
log.debug "Executing ‘sendEthernet’ ${message}"
new physicalgraph.device.HubAction(
method: “POST”,
path: “/${message}?”,
headers: [ HOST: “${getHostAddress()}” ]

// handle commands

def on() {
log.debug "Executing ‘switch on’"
sendEthernet(“switch on”)

def off() {
log.debug "Executing ‘switch off’"
sendEthernet(“switch off”)

def alarmoff() {
log.debug "Executing ‘alarm off’"
sendEthernet(“alarm off”)

def strobe() {
log.debug "Executing ‘alarm strobe’"
sendEthernet(“alarm strobe”)

def siren() {
log.debug "Executing ‘alarm siren’"
sendEthernet(“alarm siren”)

def both() {
log.debug "Executing ‘alarm both’"
sendEthernet(“alarm both”)

def test() {
log.debug “Executing ‘alarm test’”
sendEthernet(“alarm both”),
“delay 3000”,
sendEthernet(“alarm off”)

def poll() {
//temporarily implement poll() to issue a configure() command to send the polling interval settings to the arduino

def configure() {
log.debug "Executing ‘configure’"
sendEvent(name: “numberOfButtons”, value: numButtons)
//log.debug "illuminance " + illuminanceSampleRate + "|temphumid " + temphumidSampleRate + "|water " + waterSampleRate
log.debug "water " + waterSampleRate
log.debug "illuminance " + illuminanceSampleRate
log.debug "temphumid " + temphumidSampleRate
sendEthernet("water " + waterSampleRate),
“delay 1000”,
sendEthernet("illuminance " + illuminanceSampleRate),
“delay 1000”,
sendEthernet("temphumid " + temphumidSampleRate)


def updateDeviceNetworkID() {
log.debug "Executing ‘updateDeviceNetworkID’"
if(device.deviceNetworkId!=mac) {
log.debug “setting deviceNetworkID = ${mac}“

def updated() {
if (!state.updatedLastRanAt || now() >= state.updatedLastRanAt + 5000) {
state.updatedLastRanAt = now()
log.debug "Executing ‘updated’"
runIn(3, updateDeviceNetworkID)
sendEvent(name: “numberOfButtons”, value: numButtons)
else {
log.trace “updated(): Ran within last 5 seconds so aborting.”

def initialize() {
sendEvent(name: “numberOfButtons”, value: numButtons)


So…What we have here is effectively a “Multi Sensor” which means a device with more than one SmartThings Capability. For each device, only 1 of the capabilties can be exposed as the “main” capability.

Edit: Just re-read your reply above - A SmartApp does not need to “see” anything in the Things View. That is purely for display only. A SmartApp uses the Device Handler’s “Capabilities” list to determine what each device is capable of. As long as your tiles use the standard naming convention, which my base ST_Anything example sketches do, then any SmartApp can see these values from a multi-sensor device. If you’re still having issues, please post your Device Handler code so I can help you debug the issue.

Why is it so important to you to have both show up on the “Things View” in the Phone App? You could use something like SmartTiles/ActionTiles to create a custom display that will show you everything you want, from each of your devices, on a very nice-looking web-based display.

You could write a custom SmartApp to keep a separate virtual device up to date. While this works, it is not always 100% reliable. I use this technique for my “Multiplexer” SmartApps when I define more than one device of the same ST capability in an Arduino Sketch/ST Device Handler (for example, multiple Contact Sensors.) This is required because ST does not support having more than one of a given capability in a device handler. If I only have one of each capability, the normal behavior is exactly what my “ST_Anything” example code demonstrates. Simpler is always better, IMHO.

If you’re having trouble with writing a custom Multiplexer SmartApp, be careful to verify that the names of each device match exactly with the names in all of your code. The names are CaSe SeNsItIvE. :slight_smile:

There are some other options available as well like Simple Device Viewer which you might find helpful.


Pro Tip: When posting code in the forums, please use the “Preformatted Text” feature in the menu bar (paste your text, highlight it, then click the “’< / >’” button in the menu bar.) This makes your code readable and prevents the forum software from stripping out certain characters.

One thing that stands out is you are missing the custom “Attribute” statements in the Device Handler necessary for your “motion0, 1, 2, 3” tiles. You also listed “motion1” twice in the “details()” section.

To get these 4 motion detectors to be exposed independently, you will need a “Multiplexer” SmartApp and 4 virtual motion detector devices. You need to make sure you pay VERY CLOSE ATTENTION to using the exact same names (case sEnSiTiVe) throughout the Arduino sketch, Device Handler, and Multiplexer SmartApp. The virtual motion detectors will be generic.

I have been working on an example where I create multiples of each device type in one Arduino Sketch, along with the corresponding Device Handler, Multiplexer SmartApp, and associated virtual devices. Hopefully I’ll have some free time to finish this example up as I believe it would help users.

1 Like

Dan, your response of the smartapp not having to ‘see’ things in the Things view was the answer.
I had not tried using the smartapp because I made this mistaken assumption. A quick test of the smartapp pointing to the temp and switch on the same device worked…just the way it is supposed to…
The DH and .ino are pretty much vanilla your code with the exception of adding the DS18B20 reference instead of the DHT.
This is going to be controlling the valve that feeds water to my solar panels and heats my pool in case anyone is wondering what i’m doing…
Thanks to all those that indulged me on this one…

That’s a great use case for a custom “thermostat” style device! Glad it is working for you!

Finally, I’m ready to try to get this pulse counting implemented since I have now the ESP8266 and your ST_anything_ESP and thus dont need the Thingshield and Arduino Mega. Does the .ino and .groovy need to be modified for ST_ESP and arduino - non-thing-shield.

Edit : I was referring to this post:




I just looked through my PS_PulseCounter class that I wrote back in 2015. This class is specific to the Arduino 2560 due to the need to implement Hardware Interrupts to properly count the pulses accurately.

Therefore, I really doubt it will work on the ESP8266 platform in its current configuration. When I have some time, I’ll see whether or not this code can be ported to run on the ESP8266 platform.

I still support the Arduino Mega with either the ThingShield (Zigbee) or an ESP-01 (Wifi) for network connectivity. However, I have not yet ported the old PulseCounter sketch and Device Handler example files to work with the newer Ethernet connectivity.


I would gladly donate an ESP07 module to the cause.

I already added support for using an ESP-01 module as a “WiFi shield” for the Arduino Mega. Check out my ST_Anything_WiFiESP.ino example sketch.

If you want to use any ESP8266 module as a standalone controller, try the ST_Anything_ESP8266WiFi.ino example sketch. I have run a stripped down version of this sketch on a ESP-01. I had to strip it down due to only having 2 GPIO pins.

Let me know if this meets your requirements.

For those of you who are only following this old thread, I am working on some new enhancements to the ST_Anything project. Still a work in process, but feel free to check it out if you’re so inclined…

1 Like

Hi all,

with all of the work that Dans has done … WOW …
does any one want to part with a couple of the original Smar Thing Arduino Shields?

I built a custom motherboard to hold the ThingShield, and now the MB’s and my project is useless.

I will pay top dollar, $60.00 each plus shipping for at least 2 units

Any assistance is appreciated


1 Like

Hey @BenB2016,
I may actually have two shields. I definitely have one never used spare Shield, and may have one that I used (very little) for prototyping/testing new device types. I will check tonight and send you a private message.

BTW: Giving up my precious Shields would not have been possible without all of Dan’s great work!

1 Like

Hi Garnet

Thank you


grateful for your work I am from Colombia and I have smartthings in my house and I am a DIY enthusiast, I have saved some Xbee WIFI S6B, I would like to know if these can be connected to smartthings

I have never used an Xbee module, but others have. Search the forums and you’ll find some examples, although they are pretty scarce. The old ST ThingShield (Zigbee) and Ethernet based connectivity are much more popular. These are the connectivity options I support in ST_Anything.

Dude… you rock!!! I just now noticed the whole cancellation deal with ThingShield and then read all the angry posts about it. Your solution is not only faster and more elegant, it is cheaper and more standard. If the ST folks were really on the ball they would have thought of this themselves. Anyway, thank you. You have made so many important contributions to the community. I ordered a few W150’s and a few ESP8266’s to try it out and I can’t wait. Now I just have to think of a fun project… maybe controlling my hot tub…

1 Like