SHARE Your Favorite REACTOR Routines [ADVANCED USAGE]

If you have any favorite Reactor setups worth sharing, or Pro Tips, I’d love to see them. Either described (as pseudocode logic), shown (as screenshots), or exported (via Logic Summary), the aim here is to inspire other users of this awesome plug-in.

Suggest that we exclude bug reports and feature requests from this topic!

1 Like

VARIABLE INCREMENT/DECREMENT

I use Reactor and a handheld remote to raise or lower the temperature setting (a/k/a ‘Setpoint’) on my ecobee thermostat – one degree at a time, for optimal comfort during the night – as follows:

  • In a Reactor Sensor module (named ‘Hallway’), I set up multiple subgroups to perform actions on the Thermostat (device #95), leaving the outermost logic group set to NULL. In fact, that’s how most of my RS’s start out.

  • Within that RS, I set up three expressions:

  1. acTemp = getstate( 95, “urn:upnp-org:serviceId:TemperatureSetpoint1”, “CurrentSetpoint” )
  2. acTempUp = acTemp + 1
  3. acTempDn = acTemp - 1
  • In subgroup ‘Increment A/C Temp’, the only Condition is that Button 2 of my MiniMote remote gets pressed.

  • In Activities, for the ‘Increment A/C/ Temp’ IS TRUE panel, the sole Device Action is Thermostat (#95) ► Set Setpoint ► {acTempUp}

Works like a charm, independently of whether the Thermostat mode is Cool or Heat. I could make those variables Global for use in another RS, but haven’t needed to (yet). Obviously, performing a decrement is just as straightforward, using {acTempDn} inside a Condition linked to another button on the remote.

I specifically wanted to employ Expressions to reduce complexity, as before (in Scenes) my old ‘Increment A/C Setpoint’ scene ran the Lua code below:

local deviceUrn = "urn:upnp-org:serviceId:TemperatureSetpoint1"
local deviceId = 95
local currTemp = luup.variable_get(deviceUrn, "CurrentSetpoint", deviceId)
luup.call_action(deviceUrn, "SetCurrentSetpoint", {NewCurrentSetpoint=tonumber(currTemp + 1)}, deviceId)

…and maintaining code is comparatively cumbersome. Variables (with their improved readability and flexibility) for the win!

  • Libra
1 Like

TOGGLE A LIGHT ON/OFF/DIM

There are times you may want a light or other device to toggle between states, such as ON and OFF, in response to a single input.

For example, I want to be able to turn my Hall Light either OFF (if it was ON), and brighten it to 35% (if it was OFF), by pressing the same button on my handheld remote.

This is easy to achieve in Reactor – without using any Luup code – by first defining these Expressions:

statusHallLight  :=  getstate( 139, "urn:upnp-org:serviceId:SwitchPower1", "Status" )

toggleHallLight  :=  if(statusHallLight,"0","35")

I simply create a Condition that goes TRUE when the desired button has been pressed (I’ll leave this as an exercise for the reader), then define its corresponding Activity as:

[Device Action]  [Hall Light (#139)]  [SwitchPower1::SetTarget]  [{toggleHallLight}]

This approach not only makes for compact code – which in turn keeps your Reactor Sensor configuration readable and easy to edit – it also has the potential to double your remote control’s capabilities!

To illustrate this last point, consider that a typical 4-button remote allows you to assign 4, 8 or 12 (sometimes even 16) scenes or actions, depending on its ability to sense buttons being tapped once, twice, held down, or (in rare cases) released after being held.

Now, with toggling, you would effectively have access to 8, 16, 24 (or even 32!!) distinct ON/OFF events using the same remote.

  • Libra
2 Likes

STEP THROUGH BRIGHTNESS LEVELS

One corollary to the ‘Toggling technique’ is that you can set up Reactor to “step thru” a preset series of brightness levels, again using Expressions.

Let’s say you want the Dining Room Light (device #8 in my setup) to go from OFF to 25%, to 45%, to 60%, to 75%, to 90%, finally to 100% brightness, then back OFF in response to seven consecutive presses of the same remote button (or any input you choose).

By defining these three Expression variables…:

lightLvlDining  :=  getstate( 8, "urn:upnp-org:serviceId:Dimming1", "LoadLevelStatus" )

brightLevels  :=  list(0,25,45,60,75,90,100,0)

stepThru  :=  brightLevels[indexof(brightLevels,tonumber(lightLvlDining))+1]

…and creating the following Activity…:

[Device Action]  [Dining Room Light (#8)]  [Set Dimming Level]  [{stepThru}]

…you will cause the light to cycle through the predetermined brightness levels by pushing the same button repeatedly.

Simply edit the numbers in the list() variable to suit your needs. For example, go from OFF to full ON and then progressively dimmer with list(0,100,75,50,30,0); or first brighten then dim the light with list(0,40,80,100,79,39,0). Include as many intermediate step values as you like, but avoid repetitions.

The possibilities are endless!

4 Likes

ON/OFF PATTERN SEQUENCER

Ever wanted a set of Vera-controlled devices to turn themselves ON and OFF according to a preset repeating pattern? With lots of options for customizing the timing and complexity of that pattern?

My criteria for designing this “Pattern Sequencer” were as follows:

  1. It had to use Reactor as its foundation, and be easy to create;
  2. It must ‘start’ and ‘stop’ using a virtual switch (e.g. Switchboard device);
  3. The sequencer must run indefinitely with low processing overhead;
  4. Each step of its pattern must be completely configurable;
  5. Use Expressions wherever possible to simplify setup.

Here’s what I came up with…

STEP 1 - GATHER THE DEVICES

A. Set up a fresh ‘NUL’ Reactor sensor expressly for this project.
B. Also select (or use Switchboard to create) a virtual switch.
(We will refer to this virtual switch as ‘runSw’ in the setup below)
C. Decide which device(s) you will want to be turned on/off.
(We will refer to these 3 devices as ‘dev1’, ‘dev2’ and ‘dev3’ below)

STEP 2 - DECLARE THE REACTOR EXPRESSIONS

devIndex  :=  (no expression / leave blank)
devNext  :=  if(devIndex+1<=len(devSequence),devIndex+1,1)
devSequence  :=  "abcdefg"
devSeq  :=  sub(devSequence,devIndex,devIndex)
dev1Patt  :=  "acdfg"
dev2Patt  :=  "bceg"
dev3Patt  :=  "def"

STEP 3 - CREATE THE CONDITIONS

The Reactor (set to ‘NUL’ mode) requires a minimum of 2 Condition subgroups, but ideally will contain N+1 subgroups (all set to ‘AND’ mode) to control N devices, defined as follows:

Subgroup ‘devCycle’
▼Output Control (for the subgroup, not the Condition inside it)
:= [PULSE] true for [4] seconds [repeat] after [8] seconds
Condition := [Device State] [runSw] [Status] [equals] [1]

Subgroup ‘dev1’
Condition := [Expression Variable] [dev1Patt] [contains] [ {devSeq} ]

Subgroup ‘dev2’
Condition := [Expression Variable] [dev2Patt] [contains] [ {devSeq} ]

Subgroup ‘dev3’
Condition := [Expression Variable] [dev3Patt] [contains] [ {devSeq} ]

(…continue this same pattern adding subgroups ‘dev4’, ‘dev5’, etc. and their corresponding dev4Patt, dev5Patt, etc. Expression variable declarations, as needed for your particular setup.)

STEP 4 - ASSIGN THE ACTIVITIES

When ‘devCycle’ is TRUE
[Set Variable] [devIndex] = [ {devNext} ]

When ‘dev1’ is TRUE
[Device Action] [‘dev1’] [Turn on or off] [1]

When ‘dev1’ is FALSE
[Device Action] [‘dev1’] [Turn on or off] [0]

(Repeat this TRUE/FALSE 1/0 pattern for remaining devices)

SETUP IS COMPLETE!

To run the Pattern Sequencer, simply turn ON the virtual switch you selected in Step 1B, above. Your selected devices will begin alternating ON and OFF according to the match-pattern defined for them in variables ‘dev1Patt’, ‘dev2Patt’, etc. Turning off ‘runSw’ stops it.

HOW IT WORKS

The length of the string declared in the devSequence variable determines how many distinct ‘steps’ your pattern will contain. The characters comprising devSequence – in conjunction with the strings in dev1Patt, dev2Patt, etc. – will directly govern which devices switch ON at each step.

For example, in its initial configuration, devSequence=“abcdefg” gives the Pattern Sequencer 7 discrete steps (with no repeats), for which dev1Patt=“acdfg” will cause device ‘dev1’ to be turned ON, OFF, ON, ON, OFF, ON, ON.
Similarly, dev3Patt=“def” causes device ‘dev3’ to be turned OFF, OFF, OFF, ON, ON, ON during the same cycle. The cycle then restarts from the beginning, and continues cycling until switch ‘runSw’ is turned OFF.

This lexicon enables you to create patterns ranging from very short-and-simple (“ABBA”) to incredibly complex (“abcbWrgb123A”), using character sequences of arbitrary length. The only requirement is that the characters used in the devXPatt strings be some subset (e.g. “aWb2A”) of those in devSequence, since alphabetic matching between these two elements determines when subgroup devX will activate.

NOTE: Order is unimportant here, since with devSequence=“abcbWrgb123A”, both dev1Patt=“aWb2A” and dev1Patt=“Aab2W” mean the same thing to the Pattern Sequencer; namely, “Turn ON device ‘dev1’ during the 1st, 2nd, 4th, 5th, 8th and last steps”.

STEP 5 - FINE TUNING AND CUSTOMIZATION

You may want to adjust such things as the Pattern Sequencer’s speed of execution, or whether it resets the pattern every time it stops running.

OPTION A: Reset pattern to 1st step when sequence stops.

This seemingly simple modification requires yet another subgroup, let’s call it ‘devReset’, with the following:

Condition := [Device State] [runSw] [Whenever the device is turned on or off / Status::SwitchPower1] [equals] [ 0 ]

and

Activity ‘When devReset is TRUE’ := [Set Variable] [devIndex] = [ 1 ]

NOTE: One might be tempted to try placing this action inside ‘When devCycle is FALSE’, but that would cause the sequence to reset itself continually, instead of solely when the cycling has stopped.

OPTION B: Slow down sequencer speed (faster possible, but not recommended!).

In the ‘devCycle’ subgroup under Conditions, click the ▼Output Control drop-down and replace ‘output goes true for [ 4 ] seconds after [ 8 ] seconds’ with any numeric values of the form X | 2X (e.g. 5 | 10, or 120 | 240), although really anything goes.

OPTION C: Return all devices to OFF when sequence stops running.

First perform Option A (above), then make sure each devXPatt string does not contain the first character of the devSequence string. All devices will then turn off when sequencing stops.
To avoid this ‘All OFF’ effect every time the sequence repeats, modify the Expression variable:

devNext  :=  if(devIndex+1<=len(devSequence),devIndex+1,**2**)

This forces the pattern to resume from the 2nd step instead of the 1st.

==========================

Wanna try this with holiday lights, anyone?

Works perfectly with my Zooz power strip!

CONTROLLING IFTTT DEVICES WITH REACTOR ‘NOTIFY’

These steps will allow you to perform (very) basic actions on non-Vera devices and services connected to your IFTTT.com account, using Reactor routines.

STEP ZERO - Create an IFTTT account and install the IFTTT mobile app (use the app for this exercise, not the Web UI).

STEP ONE - Set up Webhooks in IFTTT by adding it as a Service.
(I won’t go into further detail on how to accomplish this)

STEP TWO - Get your Webhooks URL string
(By clicking the gear icon under Webhooks service…


…and then the ‘user_url’ link to your profile…

…and copy your ‘Make a web request’ URL)

STEP THREE - Create a new Webhooks IFTTT Applet
IMPORTANT: You must perform this step for each unique action (e.g. once for ‘Turn light ON’ and again for ‘Turn light OFF’) that you want Reactor to trigger via Webhooks.

Open the IFTTT app and click on ‘GET MORE’ to begin creating a new ‘If THIS then THAT’ connection:


Click on ‘Make your own Applet from scratch [+]’ as shown:

Tap the [+]THIS component in the next screen:

Under ‘Select trigger service’ begin typing ‘Webh…’ and then click on ‘Webhooks’ once it appears beneath ‘Search Results’:

Tap ‘Receive a web request’ (the only choice available) as the ‘This’ trigger:

Enter a meaningful ‘Event Name’ (e.g. add_to_calendar) in the space provided, and click CONTINUE:

In the next step, you will replace the {event} portion of your Webhooks URL with whatever you typed in the ‘Event Name’ field, which must not include spaces or uppercase letters (because good URLs steer clear of those characters).

STEP FOUR - Create a ‘Notify’ activity in Reactor
Add this step to any existing ‘is TRUE’ or ‘is FALSE’ activity group:

[Notify] [User URL] [<optional message text>] [<your Webhooks URL>]

It is here that you must modify your Webhooks URL so that this trigger’s ‘Event Name’ appears in the proper place, as in this example, with your unique IFTTT user key at the end of it:

https://maker.ifttt.com/trigger/add_to_calendar/with/key/cIsQEue9eo5c2Sa

STEP FIVE - Link an action to your IFTTT Applet
Next, click the [+] THAT link on the ensuing screen:


and then choose (from among your connected IFTTT services) the one best suited to this task – here, I’m picking Google Calendar, to create a new calendar event whenever this Reactor routine fires:

For that purpose, I prefer the ‘Quick add event’ option, since even a simple recipe (e.g. “Dinner at 7pm on Tuesday at Antoine’s”) can generate a fully formed calendar event.

We construct that recipe in the very next stop, using ‘Ingredients’:

These ‘Ingredients’ are provided by the trigger itself, but up to three additional ‘Values’ (value1, value2 and value3) can also be passed from the URL in Reactor (see Step Six). Click ‘Insert Ingredient’ to include more of them while building your recipe.

DONE!

IFTTT will now show you a summary of the This-That applet you just created, and offer to send Notifications to your mobile device every time this applet runs. Pro tip: Use ‘Edit title’ if you want to give the applet a better name. Then click FINISH.

STEP SIX - Pass Optional Parameter Values to IFTTT
Assuming you have 1-3 Expression variables (for this example, we’ll call them ‘motion_type’ and ‘zone_name’) already defined for this purpose, you can send their contents to IFTTT for use as ‘Ingredients’ in your applet’s ‘Then’ action.
Simply add these extra value/variable pairs to the end of your Webhooks URL, using the exact value={variable} format illustrated in this example:

https://maker.ifttt.com/trigger/add_to_calendar/with/key/cIsQEue9eo5c2Sa?value1={motion_type}&value2={zone_name}

When Reactor sends the URL, it will dynamically replace each curly-bracketed named variable with its evaluated contents, so that IFTTT receives the correct values, such as:

https://maker.ifttt.com/trigger/add_to_calendar/with/key/cIsQEue9eo5c2Sa?value1=OPENDOOR&value2=FRONT_PORCH

and IFTTT, in turn, will substitute those text strings in place of ‘Value1’, ‘Value2’, etc. in the recipe of your Applet!

WARNING: Until advised otherwise, consider the variable-substitution method illustrated in Step Six to be invalid. I am double-checking with the developer of Reactor to ascertain why the plug-in treats Expression {variables} differently under “User URL” versus the (tested and known working) Notify►"SMTP" messaging method.

1 Like

CONVERTING SCENES TO REACTOR ROUTINES

Among Reactor’s many incredible features is the ability to directly ‘import’ the components of an existing scene into Activities. This is handy when you want to migrate standalone Scenes into the Reactor framework.

Reactor purists might even prefer a Vera devoid of Scenes altogether! But that may leave you wondering:

  1. How will I make the manual routines run?
  2. What added value does Reactor offer?
  3. Is the Scene-to-Reactor conversion easy?
  4. Can I still use Alexa in the same way?

This post aims to demonstrate a “Scene to Routine” conversion process that is easy-to-follow, repeatable, and logical. The steps below walk you through initial setup; copying a Scene into Reactor; creating a virtual switch for manual/spoken execution; deleting the old Scene; and finally, updating Alexa using “Discover Devices”.

FIRST, CREATE A NEW VIRTUAL SWITCH

NOTE: For ‘manually triggered’ scenes only… SKIP THIS STEP if your scene fires based upon a schedule or device event (i.e. things Reactor handles natively).
Using the Switchboard plug-in (or other UI7-compatible virtual switch creation tool) create a new binary virtual switch. I prefer Switchboard because it lets me define custom status text (‘running’/‘stopped’ or ‘active’/‘idle’ or ‘on’/‘off’) as well as an auto-reset timer for each switch.

TIP: Give the new switch the same name and place it in the same room as the Scene you are replicating. (We’ll be deleting the Scene later!) For this example, let’s refer to it as MY_SCENE.

CREATE A NEW REACTOR SENSOR OR SUBGROUP

In a brand new RS, or existing RS (set to ‘NUL’) create a Condition subgroup (set to ‘AND’) – let’s call it RUN_MY_SCENE – into which a single condition will be inserted:

[Device Event]  [MY_SCENE]  [IS TURNED ON]  [STATUS]  [1]

This causes the RUN_MY_SCENE subgroup to go TRUE (i.e. execute its “IS TRUE” activity group) whenever the MY_SCENE switch gets turned on.
NOTE: For routines triggered by a Device State, Interval and/or other event(s), create that Condition here in lieu of the one shown above!

SAVE your work and click on Activities, where we will be copying over the contents of the old Scene.

NEXT, IMPORT THE OLD SCENE INTO REACTOR

Hop over to Activities, where you will insert a single action within the ‘RUN_MY_SCENE IS TRUE’ group:

[Run Scene]  [MY_SCENE]  [Use Reactor to run scene]

and then click the [] button to its immediate right. The “IS TRUE” group will automatically be populated with an exact copy of all of the scene’s contents, including device actions, delays, etc. If you created the virtual switch without assigning it an auto-reset timer, go ahead and add the following two actions to the “IS TRUE” group:

[Delay] for [2]  [from this point]
[Device Action]  [MY_SCENE]  [Turn on or off]  [0/off]

Again, SAVE your work.

DELETE THE OLD SCENE FROM VERA

Hop over to ‘Scenes’ in the Vera UI, and scroll down to MY_SCENE, then click the trashcan icon to its far right. Goodbye, old scene!

DELETE THE OLD SCENE FROM THE ALEXA APP

Alexa users will now want to remove the old Scene from the Alexa app’s SMART HOME > SCENES list. Go there, locate MY_SCENE, and click Forget next to it.
(This helps prevent confusion in the next step, when Alexa discovers the new switch with the same name!)

LOGIN TO VERA'S 'MANAGE ALEXA' PORTAL

In the Vera UI, click LOGOUT and then login to your GetVera account. (Do not click on CONNECT!) Click on your name at the upper right corner of the screen, and select “Manage Alexa”.
Make sure the new MY_SCENE switch is checked under “Lights and Dimmers” (if you had a custom name for the old Scene, enter the same custom name for the new switch) and click FINISH at the bottom of the screen.

INSTRUCT ALEXA TO REDISCOVER DEVICES

Say, “Alexa, discover devices” and wait 1-2 minutes for this process to complete. (Given that we took care to name the new virtual switch the same as the old scene, Alexa may not report finding anything new.)
Finally, again under your name, click “My Controllers” from the drop-down list and this time, click on CONNECT!

MODIFY YOUR NEW REACTOR ROUTINE

It goes without saying that Reactor is more powerful and configurable (not to mention easier to edit!) than any old Scene. This is a great opportunity to review how your scene/routine works, whether it suits your needs as-is, or might benefit from the added functionality that Reactor affords you.

You might also want to define an “IS FALSE” set of actions, which under most circumstances will simply ‘undo’ those under “IS TRUE” (e.g. turn OFF any lights that had been turned ON). This is ideal for setups that use a remote control to toggle the MY_SCENE switch ‘On’ and ‘Off’ (instead of it being reset each time by Reactor, or Switchboard using the timer mentioned above). I leave that as an exercise for the reader.

  • Libra
1 Like

Well I never knew that!

C

1 Like

Here’s one of my new favourite reactor recipes! Allows for zone announcements at night time only.

1 Like

SENDING DEVICE ALERTS VIA REACTOR: A Modular Approach

While it’s very straightforward to trigger “Low Battery” or similar device status notifications in Reactor – by watching a particular variable (e.g. ‘BatteryLevel’) for example, then using ‘Notify’ to generate an SMTP message – I wanted a slightly more advanced setup that would:

  • Be easier to maintain than native Vera notifications;
  • Keep track of multiple devices’ status in one place;
  • Generate a suitable message based on that status;
  • Use Reactor group activities as a chain of modules;
  • Make it easy to include more devices in the future;

HOW IT WORKS IN THEORY

Keep track of a critical parameter, usually a device variable. Set up a Condition to trigger whenever that parameter reaches a critical value. Use Expression variables in a “Mail Merge”-style template to construct message components. Call another Reactor activity group as a ‘module’ (think of it as a ‘function’ or ‘subroutine’) to compose a fully formatted message, and yet another to send it.

THE BASIC SETUP

I created a new Reactor sensor (called ‘Reactor (Alerts)’ in keeping with my naming schema), set it to ‘NUL’, and arranged it as follows:

  • Define the assorted Expression variables needed for the task;
  • For each watched device, create its own Condition subgroup;
  • Create a no-Condition subgroup to compose each type of Alert;
  • Finally, create a no-Condition subgroup to send the Alert email.

THE EXPRESSION VARIABLES

MsgSubj := (no expression)
MsgHead := "Vera says: \n"
MsgBody := (no expression)
MsgFoot := "\n \nSent " + strftime("%c") + "\nfrom VeraPlus S/N #12345678"
LowBatt := 25
MinBatt := 10
DeviceNum := (no expression)
DeviceName := getattribute( DeviceNum ,'name')
DeviceBatt := getstate( DeviceNum, "urn:micasaverde-com:serviceId:HaDevice1", "BatteryLevel" )
LowBattSubj := "Low Battery Warning!"
LowBattBody := "The " + DeviceName + " battery level is currently " + DeviceBatt + "\%"
BattLevSoftRemote := getstate( 216, "urn:micasaverde-com:serviceId:HaDevice1", "BatteryLevel" )
BattLevDeadbolt := getstate( 13, "urn:micasaverde-com:serviceId:HaDevice1", "BatteryLevel" )
AuthSubj := "App Registration Required!"
AuthBody := "The " + DeviceName + " app is currently unregistered."
AuthEcobee := getstate( 219, "urn:ecobee-com:serviceId:Ecobee1", "TSK" )

THE CONDITIONS


NOTE: The ‘OR’ subgroups contain redundant Conditions, either one of which would suffice.

THE ACTIVITIES
First, construct the basic message components, tailored to the specific device for which the Alert is being sent, simply by assigning its Device Number to variable DeviceNum and calling the appropriate composition ‘module’…


NOTE: ‘Force re-evaluation’ is checked so that all Expression variables deriving their values from DeviceNum will be updated at this stage.

Because the last step ‘called’ its .TRUE subgroup using ‘Run Group Activity’, the next ‘module’ gets invoked, which composes the outgoing message…

…and finally, makes a call to the .TRUE activity group of the ‘Send Message Now’ module, so that the fully formatted message gets sent via email:


NOTE: Requires that you have already configured ‘SMTP’ protocol in Reactor!

Note, too, that the Expression variable MsgSubj shown in the 'Subject:" field above currently does NOT get replaced dynamically by Reactor (I have alerted @rigpapa – creator of Reactor – to this anomaly), but I feel confident that is the intended behavior of ‘Notify’ which future revisions will likely implement.

USAGE NOTE: Because certain non-ZWave devices (e.g. such as remote temp/humidity/motion sensors used with ecobee thermostats, whose status gets updated through an API plug-in) do not report BatteryLevel directly to Vera, it will be necessary to create alternative triggers for them. Potentially, this could be accomplished within their own “Notifications” (actually Scenes, though often hidden from Vera’s UI7 interface), but I have not tested this.

Very nice. I do have a question … what triggers the conditions to run?

Have you considered checking for battery levels that have not been updated for some period of time (e.g., a week or so). The situation I experience with some battery powered devices is the battery levels stop being reported, or they seem to go from 30-40% to not working in a very short period of time.

Great question(s), ErnieF, although I hadn’t taken things quite that far (yet).

When the expressions change, the matching Conditions follow suit. One of them, for instance, fired twice while I was typing my last Reply (turns out the ecobee plug-in generates other text – ‘Token refresh success’ – in the ‘TSK’ field, which prompted two “Device Unregistered” alerts to be sent, lol; so I added a second ‘AND’ <> condition to watch for that).

Each of my battery-operated devices also has a variable (‘BatteryDate’) but I have not explored what that does (I think it’s just the current time), and suspect – as you likely do, too – that one should derive the “last reported” timestamp using some other method.

The last thing I’d want to cause is for battery-operated devices to be woken up just to report their battery level, as that would be totally counterproductive. Therefore, I hope and trust that nothing I’ve outlined above makes such a thing happen!

I incorrectly asked what causes the “expressions” to run, and should have asked when “conditions” are evaluated and checked by Reactor.

For example, is the condition “Expression Variable: BatLevSoftRemote <= {LowBatt” checked whenever the expression variable BattLevSoftRemote evaluated (=getstate()) and this happens whenever the BatteryLevel is reported by device 216?

I think this is how Reactor works, but I am unsure. If so, then you could be getting a lot of notifications depending on the device and its wakeup parameter.

When I have implemented similar alert capabilities in other home automation systems, I generally ran these once a week or so and iterated over all battery operated devices. However, your approach deserves further study and consideration.

1 Like

Expressions are run before conditions are evaluated. Expressions are run in the order configured.

The getstate() function will “watch” the subject device, so any device mentioned in either an expression or condition will cause re-evaluation instantly.

I should mention, however, that it’s possible to do tricky things with expressions like getstate( mysensor, "urn:blahblahblah", "Tripped" ) and then change the value of mysensor dynamically… that will not make for consistent performance on device watches and triggered evaluations. Caveat emptor.

1 Like

RESET REACTOR WITH A SCENE

For those times when too much fiddling with Vera (like renaming devices, or moving them to another room) causes Reactor to go into “Lockout” mode, I prepared a special Scene – which I run manually – to reset Reactor to full operation. That way, I don’t have to wait for it to self-reset after its waiting period.

Simply include the following Luup script in the Scene:

luup.variable_set("urn:toggledbits-com:serviceId:Reactor", "rs", 0, NNN)
luup.reload()

where NNN = Reactor master device’s ID number

GET ENERGY READINGS FROM WEB SERVICE BY USING HTTP REQUEST

I have two Efergy energy meters, one that reports the house consumption and one that reports the consumption of the hot tub. Both meters report to the Efergy website.

In the past I have used a Raspberry Pi to run some scripts with curl to fetch the data from the Efergy site, to report it to virtual sensors on the Vera and also to push the data to Thingspeak.

With the addition of HTTP Requests to Reactor I have now moved this function into a Reactor running on OpenLuup.

The first challenge is to parse the raw data reponse in order to get the energy readout (3720 below). The second challenge is then to get the os.execute curl correct for posting the data to Thingspeak. It took some time to get the quotes right…

To keep the thread a bit shorter I have only posted the data for one of the energy meters:

Step 1: Update Reactor to the latest “Stable” release in order to get the HTTP Requests functionality.

Step 2: Create an Expression “House” that will get the raw data readout from the Efergy website

Step 3: Create a HTTP “Get” Request activity that fetches the raw data from the website.

*Request url: http://www.energyhive.com/mobile_proxy/getCurrentValuesSummary?token=<<TOKEN_HERE>>*

Request Headers:
Content-Type: application/json</i>

*Capture response to: House*

Step 4: Create additional Expressions that bring out the energy readout from the raw data string. This could most likely be done in a more elegant way, but it gets the job done.

House
[last “[{"cid":"PWER","data":[{"1586464000000":3720}],"sid":"603049","units":"W","age":20}]”(string)]

HouseCutLeft1 = sub(House,(find(House, “%{” )+1),len(House))
[last “"cid":"PWER","data":[{"1586464000000":3720}],"sid":"603049","units":"W","age":20}]”(string)]

HouseCutLeft2 = sub(HouseCutLeft1,(find(HouseCutLeft1, “%{” )+1),len(HouseCutLeft1))
[last “"1586464000000":3720}],"sid":"603049","units":"W","age":20}]”(string)]

HouseCutLeft3 = sub(HouseCutLeft2,(find(HouseCutLeft2, “%:” )+1),len(HouseCutLeft2))
[last “3720}],"sid":"603049","units":"W","age":20}]”(string)]

HouseCut = sub(HouseCutLeft3,1,(find(HouseCutLeft3, “%}” )-1))
[last “3720”(string)]

Step 5: Create a Generic Virtual Sensor. In post #35 of the Virtual Sensor thread Plugin: Virtual Sensor - #35 by rigpapa - General Plugin Discussion - Ezlo Community there is an instruction on how to update this with a device file to show Watts if this is important for you.

Step 6: Add a device actions to the Reactor so that the energy readout is written to the Virtual Sensor.
Device VSHouseWatt (<<DEVICE_NO>>) action urn:toggledbits-com:serviceId:VirtualSensor1/SetValue( newValue="{HouseCut}" )

Step 7: Add a Run Lua action that writes the energy readout to Thingspeak.

Run Lua:
local result = Reactor.variables.HouseCut
os.execute( "curl -s -i -H 'Accept:application/json' 'https://api.thingspeak.com/update?api_key=<<KEY_HERE>>='" .. result)

Step 8: Set up an interval Condition so that the Reactor is triggered regularly, e.g. 1 minute.

Done!

Hopefully this instruction can be of some use as a simple example of using HTTP “Get” Request in combination with some work to parse through the result string. I recommend looking through the description of LuaXP functions by rigpapa, https://www.toggledbits.com/luaxp/functions.
The instruction can perhaps also serve as an example on how to post device data to Thingspeak.

//ArcherS

2 Likes