[Release] HubDuino v1.1.7 - Hubitat to Arduino / ESP8266 / ESP32 / ThingShield Integration (ST_Anything)



I like the hidden TV idea. Although, the projector screen I would classify under the Shade capability since they are very, VERY similar. But these other uses...what capability would you put them under inside HE?

Ahem....you're lookin at one mister!! I'd never touched an ESP8266 before stumbling on your post in the ST forum. But I also did a TON of reading and self-teaching in addition to asking questions. Gotta learn some things on your own. :stuck_out_tongue:


I agree. Kudo's are well warranted. I have found Hubduino to be the best way to create some of the sensors I need that are definitely cheaper and more inline with what I really want instead of having to "make do" with what I can find in a Zigbee or Z-Wave sensor. I'm not a programmer by any means and have never had a class in any language besides English and ladder logic for AB PLC's ! :smile: , but I can look through code, figure out what's happening, Google things if needed and figure out how to change it to what I need. Sometimes takes a while this way, but I get there eventually. I'm not an "I don't know how" person, I'm an "I don't know how yet" person. You and your son's work has simplified things for me vastly and it's much appreciated.


I was simply listing a few ideas where a stepper would be needed in place of a servo. While I cant anticipate what potential use someone might conciece of. Artificially limiting values and variables because "I" cant think of a use is shortsighted. I personally spent many hours updating hardware and software to minimize effects of the y2k bug 20 years ago because of shortsighted thinking.



I was just asking how you imagine implementing it in HE. I didn't say it shouldn't be done or it was a bad idea. Just asking for more detail. Nothing says you have to have the answer, i was really asking out of curiosity and not trying to "challenge" your response.


I am currently using a Mega with 5100 shield and have everything up and running but it's like the connection goes to sleep after a while. I have a basic setup of a contact sensor that triggers a relay. That works fine except after a few hours the contact sensor will fail to report change until I manually change a relay (through the dashboard) then the contact sensor will start reporting again. Is there something I need to do to keep it active?


If understand you correctly, attached to the Arduino MEGA + 5100 shield combination, you have a simple magnetic contact sensor attached to one GPIO pin and a relay attached to a second GPIO pin. Is that correct?

There is nothing in the Arduino code that would permit the Arduino MEGA to ever go to sleep. In fact, there is actually some code to send the status updates of all attached devices (whether they have changed or not) every 5 minutes (by default) to the Hubitat hub.

If you look at the Contact Sensor and Switch child devices in Hubitat, and then click on the list of events for either of them, you should see their "lastUpdated" attribute has been updated every 5 minutes as shown below. This is from my primary HubDuino board, which is an Arduino MEGA + 5500 Ethernet Shield.

If you're not seeing these updates every 5 minutes, then you may have a hardware issue with your Arduino/5100 combination. I know a lot of the 5100 Ethernet shield sold are clones, often with reliability issues. Perhaps that could be the problem? Also, is your power supply adequate for the Arduino board? I use a 9v regulated power supply to ensure enough power is always available. Prior to using this power supply, I sometimes had stability problems.


Thanks for the reply. Your understanding is correct. There is definitely a gap in the events.

At 7:38 this morning is when I turned on the relay and 7:39 is when the contact sensor reported.

I have tried with powering with usb and an external 9v supply. I have another mega and 5100 shield combo (different models) that is in use but I’ll try that one to see if I have better results.


Or on second thought I’ll just use it as an excuse to buy a genuine mega and Ethernet shield. Should be here next week. Is this the shield you use?



Yes, that is the exact same shield I have been using without any issues for about 2 years. I am using SainSmart Arduino MEGA 2560.


I have a BME280 sensor connected up for a few months. It appears that the humidity is wonky. Most of the time it reports 80, the temp and pressure appear to be correct or pretty close. Any ideas what I could look for?


I am by no means an expert on HE and the types of data it uses to communicate with devices or am I in any position to suggest to HE owners what types of data makes sense. I was just commenting that in general terms its shortsighted to limit data types to only those you can think of today.

As I originally suggested since HE and Hubduino already communicate variables such as on/off, luminence or lux, perhaps its not to much of a stretch to add a general purpose 32bit number for other uses such as driving a stepper motor. This number would be used by Hubduino to represent the number of pulses and the direction of rotation. The actual number would be something the enduser would need work out. No different then me determining that 51% illumination was the ideal for opening for my blinds however I actually needed 140 degrees but HE and by extension Hubduino doesnt offer degrees.



See, I wouldn't want to have to pass the number of steps to take from HE. That should be contained within the sketch in Hubduino. You should only pass either preset points or percentage from HE. That way it could be controlled via one of the tiles currently available in dashboards.


But absolute values are already being passed between devices and the hub in other instances. Temp, humid, lux, etc

And through the device settings in the servo child device I can set the value (in percentage) that I want to use for on/off for my particular needs and its controlled from my dashboard tile too.

However what you or I need or want may not be what someone else needs/wants. Saying that you should only pass certain variables limits flexibility. And that was the basis of Dan's original request for ideas. Maybe mine wasn't feasible but he knows his code best and maybe my idea would put him on a path he hadn't thought of.

Again I am not an expert in HE. But I have seen the affects of artificial limitations



But you are limited to the interface that Hubitat provides. How would you pass a value of 13545 to the board without going into the edit device page and entering that value in a custom command? You have to think practically about what would be able to be implemented within the existing architecture. For it to be useful, it has to work. This is not an artificial limitation. It's called designing a total solution instead of just throwing something together.


Again as I stated, I don't know all the inner workings of hubitat and it's limitations. If hubitat doesn't offer a large enough variable then the point moot. And I never suggested throwing something together. I was offering a suggestion to a request. If it doesn't work then so be it.

I'm done



Rule Machine can call an arbitrary command with an arbitrary parameter. So can any app, though you'd likely need a custom one. The running of either can, of course, be triggered by anything you choose--device page totally unnecessary.

But certainly if you want to pass a range of values from the Dashboard, something that is part of a device capability would be the most generally useful. Otherwise, you'll probably want to have buttons or switches for each value, and that could get out of hand with too many...

Or I guess you could let an app "translate" between the two, customizable for each device and its range. A lot of options here. :slight_smile:


Yes, a million and one things are possible. But what's most practical?


Hubduino noob question. Which sketch will help create the voltage sensor child? I'm still working out the documents but a quick example sketch will be useful.

Basically similar to some messages above, I would like to trigger Hubitat I'm rules machine if voltage goes below certain values or is in a range. I already got the voltage sensor sketch working on NodeMCU ESP8266 so just need to get that info to Hubitat to trigger and do actions when it goes from 12V to 9V, or when it goes 12V to 6V do another action.



I have modified the ST_Anything_Multiples_ESP8266WiFi.ino sketch below to simply create one PS_Voltage device. I have commented out all of the other devices. To configure the settings of the PS_Voltage device, please take a look at the comments section at the top of the PS_Voltage.cpp file. You can adjust the scaling for your application as you see fit. In the example below, I chose to scale the A0's input range of 0-1024 counts to 0.0-12.0 volts based on your comments above. You can choose any range you desire.

//  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
// 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 <PS_Voltage.h>      //Implements a Polling Sensor (PS) to measure voltage
#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_WATER_1               A0  //NodeMCU ESP8266 only has one Analog Input Pin 'A0'
#define PIN_VOLTAGE_1               A0  //NodeMCU ESP8266 only has one Analog Input Pin 'A0'

//#define PIN_ALARM_1               D0  //SmartThings Capabilty "Alarm"
//#define PIN_SWITCH_1              D1  //SmartThings Capability "Switch"
//#define PIN_CONTACT_1             D2  //SmartThings Capabilty "Contact Sensor"
//#define PIN_BUTTON_1              D3  //SmartThings Capabilty Button / Holdable Button (Normally Open!)
//#define PIN_BUTTON_2              D4  //SmartThings Capabilty Button / Holdable Button (Normally Open!)
//#define PIN_MOTION_1              D5  //SmartThings Capabilty "Motion Sensor" (HC-SR501 PIR Sensor)
//#define PIN_SMOKE_1               D6  //SmartThings Capabilty "Smoke Detector"
//#define PIN_TEMPERATURE_1         D7  //SmartThings Capabilty "Temperature Measurement" (Dallas Semiconductor DS18B20)
//#define PIN_TIMEDRELAY_1          D8  //SmartThings Capability "Relay Switch"

//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
// Hubitat Hub Information
IPAddress hubIp(192, 168, 1, 145);    // hubitat hub ip         //  <---You must edit this line!
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
//  static st::PS_Water               sensor1(F("water1"), 60, 20, PIN_WATER_1, 200);
//  static st::PS_DS18B20_Temperature sensor2(F("temperature1"), 15, 0, PIN_TEMPERATURE_1, false, 10, 1); 
    static st::PS_Voltage sensor1(F("voltage1"), 10, 0, PIN_VOLTAGE_1, 0, 1024, 0.0, 12.0, 3);  
  //Interrupt Sensors 
//  static st::IS_Contact             sensor3(F("contact1"), PIN_CONTACT_1, LOW, true);
//  static st::IS_Button              sensor4(F("button1"), PIN_BUTTON_1, 1000, LOW, true, 500);
//  static st::IS_Button              sensor5(F("button2"), PIN_BUTTON_2, 1000, LOW, true, 500);
//  static st::IS_Motion              sensor6(F("motion1"), PIN_MOTION_1, HIGH, false);
//  static st::IS_Smoke               sensor7(F("smoke1"), PIN_SMOKE_1, HIGH, true, 500);

  //Special sensors/executors (uses portions of both polling and executor classes)
//  static st::S_TimedRelay           sensor8(F("relaySwitch1"), PIN_TIMEDRELAY_1, LOW, false, 3000, 0, 1);
//  static st::EX_Alarm executor1(F("alarm1"), PIN_ALARM_1, LOW, true);
//  static st::EX_Switch executor2(F("switch1"), PIN_SWITCH_1, LOW, true);  //Inverted logic for "Active Low" Relay Board
  //  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, "OfficeESP");
    //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
//  st::Everything::addSensor(&sensor2);
//  st::Everything::addSensor(&sensor3);
//  st::Everything::addSensor(&sensor4); 
//  st::Everything::addSensor(&sensor5); 
//  st::Everything::addSensor(&sensor6); 
//  st::Everything::addSensor(&sensor7);  
//  st::Everything::addSensor(&sensor8);  
  //Add each executor to the "Everything" Class
//  st::Everything::addExecutor(&executor1);
//  st::Everything::addExecutor(&executor2);
  //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"


Worked like a charm. was heading this direction (albeit bumbling around) and you saved me quite some time and clarity :slight_smile:

Thanks @ogiewon