Announcing the "ST_Anything" Arduino/ThingShield Project

Todd (@Todd_Whitehead),

I have made the changes to PS_TemperatureHumidity.h and PS_TemperatureHumidity.cpp to allow you to optionally pick the names you want sent to the ST Cloud. Simply modify your sketch as follows:

Original:
st::PS_TemperatureHumidity sensor2(“temphumid”, 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT22);

Additional DHT sensor:
st::PS_TemperatureHumidity sensor2(“temphumid2”, 120, 10, PIN_TEMPERATUREHUMIDITY, st::PS_TemperatureHumidity::DHT11, “temperature2”, “humidity2”);

The last two string arguments are new and are optional if you only have one Temp/Humidity sensor. The first argument must be unique as well…as requires some minor tweaks to the Device Type Groovy code if you want the Polling Rate for the additional Temp/Humid sensor to show up in “Preferences” and be sent to the Arduino in the “Configure()” routine.

If you need to Alarm off of the secondary Temp/Humid sensor, you’ll have to add support in a Multiplexer SmartApp and add a Virtual Temp/Humidity Device (you should be able to simply use a Virtual Contact Sensor Device Type as a prototype, and use the Tile definitions from the ST_Anything Device Type groovy code. Of course, you have to modify the capabilities section as well to replace “Contact Sensor” with “Temperature Sensor” and add “Humidity Sensor”…

New code is available on GitHub at https://github.com/DanielOgorchock/ST_Anything

Sounds like you’re having fun! Let me know if you have any questions.

Dan

1 Like

Dan (@ogiewon),
I’m having a blast! Thank you.

I think I added the extra sensors correctly, but the display output only shows the first one.

I have these lines for the temp humid sensors:

#define PIN_TEMPERATUREHUMIDITY1 16
#define PIN_TEMPERATUREHUMIDITY2 17
#define PIN_TEMPERATUREHUMIDITY3 18

st::PS_TemperatureHumidity sensor16("Pin16", 120, 10, PIN_TEMPERATUREHUMIDITY1, st::PS_TemperatureHumidity::DHT11, "Pin16t", "Pin16h");
st::PS_TemperatureHumidity sensor17("Pin17", 120, 10, PIN_TEMPERATUREHUMIDITY2, st::PS_TemperatureHumidity::DHT11, "Pin17t", "Pin17h");
st::PS_TemperatureHumidity sensor18("Pin18", 120, 10, PIN_TEMPERATUREHUMIDITY3, st::PS_TemperatureHumidity::DHT11, "Pin18t", "Pin18h");
  st::Everything::addSensor(&sensor16); 
  st::Everything::addSensor(&sensor17); 
  st::Everything::addSensor(&sensor18); 

But the serial output only shows the first set:

Everything: Sending: PinA8 dry
Everything: Sending: Pin16t 68
Everything: Sending: Pin16h 39
Everything: initDevices ended
Everything: Free RAM = 6133

The first set is populating in the ST “Thing”, but the other 2 sets are not showing values.

Did I miss something in customizing the labels?

THANKS!
@Todd_Whitehead

Todd (@Todd_Whitehead),

Not sure how many sensors you have now. You may need to increase the MAX number of sensors in Constants.h. The initial debug statements will display an error if you exceed the default maximum.

Dan

That did it!

Thanks!

Wow. Are all DHT11 sensors so crappy? I have the three sensors plugged into the same breadboard and the temperatures they report back are not very close to each other. There is a seven degree spread…

Everything: Sending: Pin16t 66
Everything: Sending: Pin16h 38
Everything: Sending: Pin17t 71
Everything: Sending: Pin17h 38
Everything: Sending: Pin18t 73
Everything: Sending: Pin18h 37

After the refresh, they got closer…

Everything: Sending: Pin17t 64
Everything: Sending: Pin17h 40
Everything: Sending: Pin18t 64
Everything: Sending: Pin18h 38
Everything: Sending: Pin16t 66
Everything: Sending: Pin16h 39

Glad to hear that solved it!

This is almost exactly what I was looking for. I want to add a lot of sensors to the platform, but I don’t need wireless and the costs that come with it. What is the best way to add say 15 DHT22, 15 TEMT6000, and say 30 relays?

I’m just looking for the glue that will sit between all the wired sensors and relays, and expose them all as devices to the ST network.

@Miles,

Start with the ST_Anything Arduino code. Install the libraries and then open the sketch.

Remove the sensors you don’t want and make copies of the sensors you want multiples of. So, if you just want 3 DH22’s, then set up your pins:

#define PIN_TEMPERATUREHUMIDITY5  5
#define PIN_TEMPERATUREHUMIDITY7  7
#define PIN_TEMPERATUREHUMIDITY8 8

Then define the sensors:

st::PS_TemperatureHumidity sensor5("temphumid", 120, 10, PIN_TEMPERATUREHUMIDITY5, st::PS_TemperatureHumidity::DHT22, "pin5t", "pin5h");
st::PS_TemperatureHumidity sensor7("temphumid", 120, 10, PIN_TEMPERATUREHUMIDITY7, st::PS_TemperatureHumidity::DHT22, "pin7t", "pin7h");
st::PS_TemperatureHumidity sensor8("temphumid", 120, 10, PIN_TEMPERATUREHUMIDITY8, st::PS_TemperatureHumidity::DHT22, "pin8t", "pin8h");

and add them to the class:

  st::Everything::addSensor(&sensor5); 
  st::Everything::addSensor(&sensor7); 
  st::Everything::addSensor(&sensor8); 

Two things to note here.

  1. The temperature humidity sensors are unique since one sensor returns
    two things on one pin. Because of that, the call for that one is
    different than the other sensors. On the other sensors, the name
    that will be used in the ST cloud is the first parameter that is
    passed. For the temp humid sensors, the names are optional
    parameters at the end. (“pin5t”, “pin5h” for example)
  2. Based on the number of sensors you are talking about having, you
    will need to increase the MAX number of sensors in Constants.h.

That should be enough to get them to start showing in the serial display when you run the Arduino code.

Then, create a device type in the smart things IDE (Following the instructions above) and do a similar modification, removing what you don’t want and duplicating what you do. So, remove all of the non temp and non humidity sensors and duplicate the existing ones changing the names to match what you called them when you defined them. Also remove any capabilities you will not be using.

So, your tile definitions for the three sensor example above would look something like this:

	// Tile Definitions
	tiles {

        valueTile("pin5t", "device.pin5t", width: 1, height: 1) {
			state("pin5t", label:'${currentValue}∞', 
				backgroundColors:[
					[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("pin7t", "device.pin7t", width: 1, height: 1) {
			state("pin7t", label:'${currentValue}∞', 
				backgroundColors:[
					[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("pin8t", "device.pin8t", width: 1, height: 1) {
			state("pin8t", label:'${currentValue}∞', 
				backgroundColors:[
					[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("pin5h", "device.pin5h", inactiveLabel: false) {
			state "pin5h", label:'${currentValue}% humidity', unit:""
		}

        valueTile("pin7h", "device.pin7h", inactiveLabel: false) {
			state "pin7h", label:'${currentValue}% humidity', unit:""
		}

        valueTile("pin8h", "device.pin8h", inactiveLabel: false) {
			state "pin8h", label:'${currentValue}% humidity', unit:""
		}

        main(["pin5t","pin7t","pin8t","pin5h","pin7h","pin8h"])
        details(["pin5t","pin7t","pin8t","pin5h","pin7h","pin8h"])
	}
}

You’ll send up with something that looks like this:

Now, the only issue with this, is the Arduino can only trigger events off of the first of each type of thing. So, if you want to have something happen when the temp gets to a certain point, you can only do that for one sensor.

@ogiewon solved that for contact sensors and switches using virtual device types and a smart app to multiplex to the virtual devices.

This is as far as I have gotten on my temp humidity sensors. I am trying to figure out how to multiplex the temp and humid values to virtual device types, but I have not been successful yet.

If you just want to be able to see what the values are everywhere, this will work asis, however.

Good luck!
@Todd_Whitehead

@Todd_Whitehead, @Miles

I have update the code in my GitHub account ( https://github.com/DanielOgorchock/ST_Anything ) to include a new Virtual Temperature/Humidity Device Type. I also modified the ST_Anything_Doors_Multiplexer SmartApp to show an example of mapping the Arduino’s “temperature” and “humidity” events to the new virtual device.

When you add a 2nd, 3rd, 4th, … DHT device to the Arduino… You will need to add custom attributes (e.g. “temperature2”, “humidity2”) and tiles to the ST_Anything DeviceType groovy code. Then modify the multiplexer to subscribe to the “temperature2” and “humidity2” events…

This follows the same pattern as Virtual Contact Sensors…

Still trying to figure out how to build a generic Multiplexer SmartApp… Not a trivial task, especially for me since I am not much of a Groovy programmer.

Enjoy!

Dan

Hi All,

Not sure if anyone has seen this project:

Essentially, it’s using wireless transceivers to connect between Arduino sensor nodes and communicating to the Internet through a Raspberry PI using OpenHAB.

I was thinking of attempting to connect through ST_Anything instead, but sadly I’ve realized that my woeful coding skills won’t enable me to.

I was thinking there might be people out there looking for just such a challenge!

Regards,
David

1 Like

Hi @ogiewon

First off this is a very impressive project that I have been following intently. Congratulations. I have been reading all of the library files before I start a project I have in mind and need to pick your brain on how interrupts are set up. Am I correct that ST_Anything uses pin change interrupts? I see in InterruptSensor.cpp is where a lot of the details are concerning pin and state, but I can’t find how the interrupts are currently configured or how to configure them on a per sensor basis.

Thanks!

@techbutler

You’re not really missing anything… We chose to not use “real interrupts” as not every pin is capable of generating a hardware interrupt. Instead, the “InterruptSensor” parent class, and everything derived from it, is designed to poll a digital input pin as fast a possible, looking for a change of state. If a change of state is detected, a notification is sent to the SmartThings hub via the ST ThingShield. (Note: These sensors are also set up to send their state to the ST Hub upon startup of the Arduino, and periodically (user configurable in Constants.h) to make sure the state within the ST Cloud is always current.

Sorry if the name “Interrupt” created any confusion.

A “PollingSensor” derived class is primarily designed for an analog input type of sensor, with a much slower interval which is passed into the object’s constructor. Since analog inputs are often constantly changing from one read to another, it is important to not flood the ThingShield with too many updates as it would never keep up.

Hope that helps!

Dan

2 Likes

Aha, I guess I was getting caught up in the name.

Thanks for the clarification!

I have been working with another ST Community member, @keithcroshaw, on adding the ability to use the ST_Anything Arduino library with RCSwitch devices. For more information on what an RCSwitch is, and to download the required Arduino RCSwicth library, please visit http://code.google.com/p/rc-switch/.

To add support for the RCswitch, I have created a new EX_RCSwitch.cpp and EX_RCSwitch.h set of files which implements the generic send() command from the RCSwitch library. The ST_Anything EX_RCSwitch device’s constructor allows you to pass in the “on” and “off” parameters that will be used when calling the RCSwitch’s send() method. To see what this looks like, I have created a new Arduino Sketch called ST_Anything_RCSwitch.ino which implements three RCSwitch’s.

I have also created a custom Device Type to be used alongside the Arduino sketch called ST_Anything_RCSwitch.device.groovy. Hopefully some others may find this useful to integrate RF based devices with SmartThings. All of the code is now available on my GitHub repository at https://github.com/DanielOgorchock/ST_Anything

Disclaimer:
Please note that I do not have any RCSwitch devices, and thus can only tell you that the Arduino and Groovy code compiles and behaves properly. Communications to/from ST via the ThingShield works as expected. I just cannot test the actual Radio Frequency communications implemented via the RCSwitch library.

2 Likes

What I’m confused about is can’t all the information be contained in the gateway device? When a manufacture makes zigbee lightbulb, door lock, or receptacle, do they really need to have something custom for each and every zigbee controller? Seems like one should be able to attach a temperature sensor to arduino, and it should be able to describe it’s basic function to any controller out there and just work.

Miles,

@Miles - I am a little confused by your question, but I’ll try to explain what I know about the subject…

For the SmartThings ThingShield, the Device Type is intentionally configured to be non-specific. ST loads some special firmware on the ThingShield to identify it as a generic “ThingShield” when it is joined to the hub. At this point, there is no way for ST to know what sensors you have connected to your Arduino. It is actually your custom groovy Device Type software that enables the Arduino ThingShield to take on the ST Device Capabilities (like Switch, Contact Sensor, Temperature Sensor, etc…) This actually true of all Zigbee and Zwave devices.

Vendor produced Zigbee and Zwave devices actually have a unique “Fingerprint” associated with each device they make. For example, an Aeon Multisensor might have a fingerprint of “AMS1” while a SmartThings Multisensor could have a fingerprint of “STMS1” (Note: I made up those fingerprints purely as an example. Real fingerprints are much longer and more complicated.) These fingerprints are what tells SmartThings which Device Type (i.e. driver) to use when they are added to your hub.

For an Aeon Multisensor to be used with different Home Automation systems, I believe that a device specific driver would have to be built for each platform to expose the capabilities of that device. This what makes SmartThings so special. With ST, we the users are able to write our own Device Type software to allow the integration of devices which are not officially supported by ST yet.

In the case of the Arduino ThingShield, this is an absolute necessity as everyone uses it differently. My hope with the ST_Anything library, which my son and I created, is to help streamline the process by showing users what is possible, and by industrializing/standardizing the process. This also greatly reduces development time to integrate new sensors. For example, adding the RCSwitch was simply a matter of taking my generic Arduino “EX_Switch” class, making a copy called “EX_RCSwitch”, and swapping a little bit of logic to use different calls to talk to the real world (via the RCSwitch library.)

Hopefully this helps to answer your question. If not, feel free to clarify and I’ll do my best to explain.

Dan

I spent some time looking over the zigbee developer documentation today, and what I’m seeing isn’t a specific “driver” per say. Using the zigbee stack you have the Application Layer, which is where you can define what the device does in a standard way which can be then used to interface within an zigbee network or controller, smartthings or other.

You basically define that the device is a light switch, and it appears as a light switch in the network without having to continually update the controller as well. Or you define that it is a temperature sensor. There are a number of standard profiles, and with smartthings the profile we are concerned about is Home Automation. Within home automation we have a number of standard “devices” which have a common interface.:

ftp://ftp1.digi.com/support/documentation/html/manuals/ZigBee/Introduction/zigbee.htm

http://zigbee.org/zigbee-for-developers/applicationstandards/zigbeehomeautomation/

While implementing the full stack is beyond what I’m capable of doing, it seems to be a good way to go unless we are implementing something that isn’t already defined as a device. You basically have a write it once and it will then work anywhere in any network, and nothing needs to be developed or maintained on the controller. The up side as well is it is inherently designed for multiple sensors / controls.

I now get what you have developed and that makes sense for the specific use case where the device type isn’t already defined in the zigbee standard. My initial question came more from a place of ignorance than anything else. I’ve been searching high and low for and example of that framework fully implemented in Arduino, but with no such luck yet. I can’t imagine I’m the first person down this road though.

I am so interested in this. Can you please support pulse counting? I want to create a water meter using a flow sensor.

@email_cslee

I am sure it is possible to add a flow meter to the Arduino. However, I am curious which SmartThings Device Capability this would align with, if any? See https://graph.api.smartthings.com/ide/doc/capabilities for a list if pre-defined device capabilities.

By using one of these pre-defined capabilities, it would allow your flow meter to integrate with other existing SmartApps, if that is desired. If you create a completely custom device capability, for example “Flow Measurement”, you will need to write your own SmartApps to use the data.

So, we need to answer a few questions before we can start.

  • What physical device are you trying to integrate with the Arduino? You mention pulse counting, but it would be helpful to know what physical product you are considering.
  • What would be the range of flows you want to measure? Or is it enough just to know that something is flowing (i.e. “On”) or is not flowing (i.e. “Off”) ?
  • And finally, how do you plan to use the data in SmartThings? Just to be able to view it on your phone/tablet? Or to make decisions of some sort?

The beauty of the ST_Anything library is that your imagination is the only thing that limits what is possible. The open nature of the SmartThings IDE for Device Types and Smart Apps allows you to build whatever you want. These two things together is what sold me on SmartThings.

Dan

Dan,
Thank you for responding. I dont see a matching capbility. The closest is a power meter. We can retarget it to mean gallons/min instead of KW.

Answers to your questions:
(1) What physical device are you trying to integrate with the Arduino?
I want to integrate a flow sensor which is a hall effect device. When water flows, it generate a pulse for a certain volume. By counting these pulses, one can calculate gallons/min and also total gallons
(2) What would be the range of flows you want to measure? Or is it enough just to know that something is flowing (i.e. “On”) or is not flowing (i.e. “Off”) ?
All the above will be useful. Having an “ON”, “OFF”, one can write IFTTT to alert that there’s water leakage somewhere. And the rate you can use to alert is there’s excessive usage, perhaps a broken irrigation valve, or toilet valve stuck, faucet left on.
(3) And finally, how do you plan to use the data in SmartThings? Just to be able to view it on your phone/tablet? Or to make decisions of some sort?
I plan to be able to view the usage on the phone/tablet. Then later set up alerts probably using IFTTT.

Thank you for your great contribution to the group. Hope it answers all your questions.

Chin