Piston Return Value?


#1

From Piston A, how can I synchronously get a return value from Piston B?

My use case is a piston that detects all the national holidays and others where school is closed. Most are easy, but some are based on the lunar cycle.

So I have a piston that figures out the phase of the moon for a particular day. I pass in the date, but I don’t know how to return the moon phase to the calling piston.

PS. I plan on posting all the pistons involved when I am done.


Feature Request: Piston $return variable
#2

When I want data that is not built in to SmartThings, my second choice is to use an API call.
(if I can find a good data source)

For those hard to find APIs, I might use PHP to scrape data from various websites.
Once the data is in webCoRE, there are a thousand things that can be done with it.


#3

If you already have the external data, then you can simply pass the data between pistons by having one piston write to a “global variable”. That data will be available and seen in other pistons.

There are many fancy ways to do this, but one easy example is if you were tracking something boolean, like MoonUp… It either is, or it isn’t. (true or false) The piston that is tracking the moon, can write ‘true’ when the moon rises, and ‘false’ when it sets. Other pistons can react differently depending on the state of that global variable.


#4

I calculate all the data I need on my own in this case. The problem is WebCore says writing to global variable won’t be available until the next run of the piston. I need it right away in the calling piston.

So, to calculate Passover, I need to search for the day the New Moon occurred in late September. So I want to loop over each day and call a piston to ask if what the moon phase is that day. In other words, I need the equivalent of a function call.


#5

Just to clarify, if Piston-A writes the global, then Piston-A won’t see the change until the next run… but Piston-B will see the change a split second after Piston-A completes execution.


#6

Use a local variable for this… They are instantly seen by the same piston on the very next line of code. I would only write to the global once you find the data you want to pass. At that point, it will be seen by the other piston immediately.


#7

So I ended using a callback function-like solution, where Piston A calls Piston B for a calculation, and then Piston B calls back Piston A so it can finish its work. This is all because I didn’t want to duplicate the complex algorithm in Piston B in multiple pistons.

So all of this was to calculate Holidays (Piston A) that are based on the moon phase (Piston B). It turns out I found other algorithms that don’t use the moon phase so the callback function feature of my piston is currently unused.

I will post the results in another thread soon with a more appropriate title and link it here. The various pistons I will post figure out if today is a U. S. holiday (actual or observed) and the other piston figures out today’s moon phase or the moon phase of a date passed in as an argument.


#8

I posted my pistons here:

Moon Phases:

U.S. Holidays:


#9

I think these both deserve some kind of award for the “Pistons with the most global variables”, LOL

My hats off to you, good sir.


Personally, the only global I would use in the “Moon Phase” piston is @MoonPhaseToday.

May I ask why you have so many “Friendly Named” globals?
IE: @HolidayHalloween = Halloween

Do other pistons actually refer to those?


#10

Yes. You can compare @HolidayToday to @HolidayHalloween and turn your lights orange.


#11

I love where you are going with this… but why not reduce 90% of those globals into a single global?
IE: {currentHoliday}
Then any piston can check that one global to see if today is X


Oh wait, you already have a @HolidayToday… Now I am confused


#12

@HolidayToday is the current holiday name. But for string compares, I didn’t want to duplicate the name of every holiday in multiple pistons. For example, I wanted the string “Halloween” in only one place.


#13

Oh, for queries like, how many days between Halloween and Thanksgiving?


#14

No, it doesn’t support that. I was planning to write another piston like this…

If @HolidayToday == @HolidayHalloween then
Set lights to orange
Else If @HolidayToday == @HolidayStPatricks
Set lights to green


#15

But I also have @HolidayNext and @HolidayNextDaysAway, so you could say “if Halloween is less than 10 days away” do something.


#16

I still see this done with only one global.

Something like:

If @HolidayToday contains "Halloween" then
     Set lights to orange
If @HolidayToday contains "Patrick" then
     Set lights to green

etc etc.


The “contains” is a nice bonus because there may occasionally be two holidays that fall on the same day


#17

Yeah, I guess I went code-reuse crazy. I didn’t want one piston to know the other piston had the string “Halloween”. This way, the string is defined in one place.

Good point about multiple holidays. This won’t handle that case.