Announcing the "ST_Anything" Arduino/ThingShield Project

Dan,
Thanks. It was the Parent Ethernet DTH which did not get published. It appears in ST now. I’ll do more testing with the flow sensor now. I’ll let you know how it goes.

thanks,
chin

1 Like

Dan,
It is working. The power registers some value when pulses are detected. A few seconds later it goes to 0.
How can I get two measures out of it. One is total cumulative pulse which can be reset (much like kWh in power meters) and another which measure pulse/minute (much like watts). Each one will need a scaling factor to adjust the value to (gallons) and second to gallons/hr. It much also be nice to have a days since reset for first measure.

thanks,

Chin

Chin,

You’re going to have to probably modify the Child DTH to add that additional functionality yourself. I’d rather leave the Arduino code as simple as possible. You should be able to modify the existing ‘Child Power Meter’ to create an accumulator and reset capability, along with scaling factors/algorithms.

For an example, take a look at my ‘Child Temperature Sensor’ as it allows for a user select F/C conversion, as well as a temperature offset. You’ll see these as User Preferences near the top, and then later where these values are used to adjust the raw incoming data before the final value is updated.

To get pulses/minute, simple change the 120 to 60 in the device declaration in your setup() routine.

static st::PS_PulseCounter sensor4(F(“power1”), 60, 5, PIN_PULSE, FALLING, INPUT_PULLUP, 1.0, 0);

Thanks. Ill give it a whirl.

Dan,
Do you have a groovy example of how I can accumulate the pulses?

thanks,

chin

You’ll want to use ‘state’ to create a variable inside the DTH to act as an accumulator.

state.totalGallons = state.totalGallons + value

But, you cannot accumulate forever. You’ll need to reset the value periodically (daily, weekly, monthly) to avoid overflow.

state.totalGallons = 0

Of course, you have to first scale the raw ‘value’ into the correct units (.e.g gallons) by performing some type of linear conversion.

Dan,
Am I on the right track here?

metadata {
definition (name: “Child Power Meter”, namespace: “ogiewon”, author: “Daniel Ogorchock”) {
capability “Energy Meter”
capability “Power Meter”
capability “Sensor”
command “reset”

	attribute "lastUpdated", "String"

	command "generateEvent", ["string", "string", "string"]
}

simulator {
}    
preferences {
		section("Prefs") {
		input "pulseFactor", "number", title: "pulse to Gallons factor", description: "Multipler to convert pulse to Gallons", range: "*..*", displayDuringSetup: false
	}
}

tiles(scale: 2) {
	multiAttributeTile(name: "power", type: "generic", width: 6, height: 4, canChangeIcon: true) {
		tileAttribute("device.power", key: "PRIMARY_CONTROL") {
			attributeState("default", label: '${currentValue}', unit:"Gallons/min", defaultState: true)
		}
		tileAttribute("device.lastUpdated", key: "SECONDARY_CONTROL") {
				attributeState("default", label:'    Last updated ${currentValue}',icon: "st.Health & Wellness.health9")        
        }
	}
    valueTile("state.totalGallons", "state.totalGallons", decoration: "flat") {
		state "default", label:'Consumed Gallons'
	}

}    

}

def generateEvent(String name, String name2, String value) {
log.debug(“Passed values to routine generateEvent in device named $device: Name - $name - Value - $value”)
def offsetValue = Math.round((Float.parseFloat(value))*100.0)/100.0d
offsetValue = offsetValue / pulseFactor
state.totalGallons = state.totalGallons + offsetValue

// Update device
sendEvent(name: name, value: (String)offsetValue)
sendEvent(name: name2, value: (String)state.totalGallons)

// Update lastUpdated date and time
def nowDay = new Date().format("MMM dd", location.timeZone)
def nowTime = new Date().format("h:mm a", location.timeZone)
sendEvent(name: "lastUpdated", value: nowDay + " at " + nowTime, displayed: false)

}

def installed() {
}

When copying and pasting code into the forum, please be sure to finish by highlighting all of your code, then click the Preformatted Text menu button that looks like ‘</>’. This will make your code readable and allow others to successfully copy and paste it.

As for your code, it is a decent start, but it has some issues:

There is no need to change the number of arguments being passed into ‘generateEvent()’. Doing so will actually totally break the code. That function is called by the Parent Device to pass in new data. You will be accumulating your water flow into a variable that is persisted within the Child Device only.

I do not see where you’ve added another Tile to display the accumulated ‘energy’ value. You’re going to want to use the ‘energy’ attribute to hold your accumulated value. To do that, you’d want to change your sendEvent() lines to be something like:

// Update device
sendEvent(name: name, value: offsetValue)
sendEvent(name: "energy", value: state.totalGallons)

Dan,
Thanks. I’m noob here. Learning the groovy with this project.

thanks.

Chin

Dan,
It seems to be working. I added another multiAttributeTile to show the total Gallons. I also added a reset tile to reset the totalGallons. However, I want to display when the reset happened. So instead of showing the last updated, I want to show days/hrs since it was reset. Do you know how it can be done?

	tiles {       
        multiAttributeTile(name: "power", type: "generic", width: 6, height: 4, canChangeIcon: true) {
			tileAttribute("device.power", key: "PRIMARY_CONTROL") {
				attributeState("default", label: '${currentValue}', unit:"Gallons/min", defaultState: true)
			}
 			tileAttribute("device.lastUpdated", key: "SECONDARY_CONTROL") {
    				attributeState("default", label:'    Last updated ${currentValue}',icon: "st.Health & Wellness.health9")        
            }
		}
        multiAttributeTile(name: "energy", type: "generic", width: 6, height: 4, canChangeIcon: true) {
			tileAttribute("device.energy", key: "PRIMARY_CONTROL") {
				attributeState("default", label: '${currentValue}', unit:"Gallons", defaultState: true)
			}
 			tileAttribute("device.lastUpdated", key: "SECONDARY_CONTROL") {
    				attributeState("default", label:'    Last updated ${currentValue}',icon: "st.Health & Wellness.health9")        
            }
		}

		standardTile("reset", "device.energy", inactiveLabel: false, decoration: "flat") {
			state "default", label:'reset Gallons', action:"reset"
		}
		standardTile("refresh", "device.power", inactiveLabel: false, decoration: "flat") {
			state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
		}
.
.
.
def reset() {
	return [
		state.totalGallons = 0
	]
}

Dan,
I figured out how to show the lastReset. Ignore that request.

thanks,

Chin

1 Like

Begging pardon if this has been addressed (also consider that I am quite noobish and stumbling in the dark a fair bit here on ALL things related). To be fair, I did research the thread quite a bit, but it’s quite massive and I did a fair amount of outside Googling and whatnot.

Fried my only Mega the other day. (Like I said, noobish and stumbling). Don’t ask. Complete rookie mistake. OK, fine. I set the thing down on something metal while it was powered up. In my defense, I didn’t think it was metal.

Anyway…I’ve continued fiddling with an UNO on this, more or less just to keep fiddling. The more fiddling, the more learning.

Anyway, I got to the point of attempting to test compile and send a sketch. Using the Mega/8266 wifi combo sketch.
It failed. ‘Serial’ not detected in this scope.
If I’m following all this right…
It looks like that’s because pins 18 and 19 on the Mega act as an additional high speed UART TX/RX.
I resaved the original skech with a new name (following instructions to maintain a ‘pure’ sketch) and did a simple search and replace on Serial1.begin with Serial.begin.

Failed on size. Commented out a bunch of devices and it appears compile.

Basically, other than the PITA of making sure nothing’s connected to the TX/RX pins on the Uno when uploading sketches and such, I should be able to use those 0/1 (RX/TX) respectively, right? Instead of 18 and 19? And there’s no comparable “Serial.1” on the UNO. Just “Serial” at 0/1…but they do essentially the same thing.

I have no problem with picking up another Mega. Easier for my fat fingers. Just wondering if my understanding here is correct. I’m not trying to do much with this. All I’m looking to do is be able to read a switch position and fire a relay. Just using the Arduino to do that heavy lifting and using the 8266 to do the wi-fi’ing.

Oh…and much respect and praise for what you’ve done with all this!

1 Like

Make you life super easy and just buy a NodeMCU ESP8266 board. No need for an Arduino UNO or MEGA at all. It has all of the IO you’ll need for a simple project.

If you’re going to use WiFi, the ESP8266 is by far the most stable WiFi platform that I have used. Just be sure to use the v2.3 ESP8266 Board support package as the new v2.4/2.4.1 version has a big memory leak in it. This is not in the ST_Anything code.

Trying to get an UNO or MEGA to work with the ESP01 is not a good noob project. The UNO only has 2KB of RAM, so it is difficult to get the code small enough. Also, you really need the MEGA’s extra HW UARTs to communicate to the ESP01 due to speed requirements. Again - DON"T DO IT! The ESP01 as a WiFi dongle has NEVER worked very well in my testing.

BTW - this thread is pretty old so you may want to keep an eye on the newer thread at

How does one get debug info? I’m assuming after flashing to my wemos d1 mini I should see some output on the com?

Yes, in the Arduino IDE Serial Monitor window, you will see debug. Make sure you set the Serial Monitor window baud-rate to 115200.

Ok let me try re-uploading my code again and seeing if I get any output this time

Hey All,

Has anyone been able to use the water sensor on a digital pin? I’ve got an esp-01 that I’m tryina use as a combo water/temp sensor. I’ll assign the water sensor D0 in the IDE, it’ll show up as a child device when setup in smart things, but when watching the serial console the esp ignores the pin if it goes high or low. This happens on the nodemcu as well (if I wanted to make two water sensors for example). I dont need the analog, its connected to a water sensing board with digital output and ajustable threshold.

The Water Sensor ST_Anything class only supports Analog inputs currently. It wouldn’t be too hard to modify a copy of the IS_Contact sensor class to do what you’re wanting.

1 Like

I have a couple of questions, but first I’d like to say THANK YOU! to Dan and Daniel for all their hard work on this project! awesome stuff!

I am playing around with ST_Anything on an ESP8266 nodeMCU board. I currently have 4 DS18B20 temperature sensors and a capacitive water sensor to keep an eye on my boat when it is stored outdoors over the winter. I basically have a few battery heat blankets (made for the purpose, NEVER use a household heating pad or bed style blanket for this! you WILL burn your boat down!) to monitor some key spots that I don’t want to freeze and to make sure water / snow melt isn’t leaking in. The water sensor gives an analog out, and I added a line of code to the water sensor .cpp file that posts the ADC value to the “recently” tab while preserving the “wet. dry” indication. I wanted to see an actual number so I could get a feel for how the water level on the sensor changes the value if I need to make any adjustments and dragging a laptop outside is a pain. I simple added another line that sends the raw m_nSensorValue as a string rather than doing the if/then on it.

Usually you would have all the DS18B20’s sharing a single pin as they all should have unique addresses from the factory. I see that you have the capability for multiple sensors on the same bus by reading the header file but I have them all on their own pins because I couldn’t figure out how to modify the code in the sketch to implement this. Not to beat on you, because I can’t claim to be the comment king of coding and you’re giving your time and energy for free, but commenting your code helps so much for the rest of us! So I guess is there some example code I missed on how this is done or could you please post some?

Also can someone point me to a post on how to run multiple ESP8266’s with ST_Anything, I’ve seen it mentioned that it is possible, but I can’t find the post explaining how to do it. I guess the fact you add a MAC address in the parent device setup tab for one device is throwing me. Do you add more device handlers or a comma in there between MACs or what? I would really like to make my own garage door controller that I can trust not to open on its own when I’m away without better layers of authentication than the commercial products already out there. I think I can leverage this project to do that since it allows for some “outside of smartthings” processing. I’ve had outdoor lights come on during the day and false sensor trips too many times to trust smarththings with something like the garage door…

And finally - Smartthings is being changed. I honestly haven’t been keeping up very closely, but I did notice somewhere that this project will only work with “classic” - Is this still the case and are there any plans to update ST_Anything to stay alive should be all be suddenly forced to move to the new app?

-Ryan

Please see this project I documented a few years ago where I have 2 temp sensors on the same pin. You have to first get the sensor serial number of each probe as documented in this post:

Specifically:

Then in your sketch you will address them:
DeviceAddress freezerProbe = { 0x28, 0xFF, 0x17, 0x99, 0x01, 0x15, 0x02, 0x13 };
DeviceAddress fridgeProbe = { 0x28, 0xFF, 0xD3, 0x6D, 0x01, 0x15, 0x02, 0x51 };