EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Posted on
Tue Dec 03, 2019 3:53 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Using break to bail out of the loop (any type of loop) is a good approach. To do a for loop you would:

Code: Select all
for i in range(6):    # will loop 6 times with values of i set from 0 to 5
  # do something
  if someTerminatingConditional:
    break

Image

Posted on
Tue Dec 03, 2019 3:54 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Nope, that's not right either, I forgot the "for x times" part...

Posted on
Tue Dec 03, 2019 3:56 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

OK, back to my first script, with Matt's mod:

Code: Select all
# turn off all valves and repeats up to 30 times until they are really off
for i in range(30):
   indigo.iodevice.setBinaryOutput(134979129, 0, False) # "EZi08T" output 1 OFF
   indigo.iodevice.setBinaryOutput(134979129, 1, False) # "EZi08T" output 2 OFF
   indigo.iodevice.setBinaryOutput(134979129, 2, False) # "EZi08T" output 3 OFF
   indigo.iodevice.setBinaryOutput(134979129, 3, False) # "EZi08T" output 4 OFF
   indigo.iodevice.setBinaryOutput(134979129, 4, False) # "EZi08T" output 5 OFF
   indigo.iodevice.setBinaryOutput(134979129, 5, False) # "EZi08T" output 6 OFF
   indigo.device.statusRequest(134979129) # "EZi08T"
   time.sleep(1)
   ezio8t.refreshFromServer(waitUntilServerIdle=True)
   binaryOutput1 = ezio8t.states["binaryOutput1"]
   binaryOutput2 = ezio8t.states["binaryOutput2"]
   binaryOutput3 = ezio8t.states["binaryOutput3"]
   binaryOutput4 = ezio8t.states["binaryOutput4"]
   binaryOutput5 = ezio8t.states["binaryOutput5"]
   binaryOutput6 = ezio8t.states["binaryOutput6"]
   if (not binaryOutput1) and (not binaryOutput2) and (not binaryOutput3) and (not binaryOutput4) and (not binaryOutput5) and (not binaryOutput6):
      break

Posted on
Tue Dec 03, 2019 4:01 pm
FlyingDiver offline
User avatar
Posts: 7189
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

I think Matt meant something more like:

Code: Select all
# turn off all valves and repeats up to 30 times until they are really off
for i in range(30):
    for j in range(6):
        indigo.iodevice.setBinaryOutput(134979129, j, False) # "EZi08T" output X OFF
    indigo.device.statusRequest(134979129) # "EZi08T"
   
    time.sleep(1)
    ezio8t.refreshFromServer(waitUntilServerIdle=True)
    binaryOutput1 = ezio8t.states["binaryOutput1"]
    binaryOutput2 = ezio8t.states["binaryOutput2"]
    binaryOutput3 = ezio8t.states["binaryOutput3"]
    binaryOutput4 = ezio8t.states["binaryOutput4"]
    binaryOutput5 = ezio8t.states["binaryOutput5"]
    binaryOutput6 = ezio8t.states["binaryOutput6"]
    if not (binaryOutput1 or binaryOutput2 or binaryOutput3 or binaryOutput4 or binaryOutput5 or binaryOutput6):
        break

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Tue Dec 03, 2019 4:04 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Yes, that's tidier...

I guess I'll take this opportunity to fix that in my code and then move all of it to a set of external scripts, so that I eliminate the errors I'm getting when this internal script is taking longer than 10 seconds...

Thanks for the help, all. Hopefully mgolden50 can make use of some of this effort...

Posted on
Tue Dec 03, 2019 4:05 pm
FlyingDiver offline
User avatar
Posts: 7189
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Or even:

Code: Select all
# turn off all valves and repeats up to 30 times until they are really off
for i in range(30):
    for j in range(6):
        indigo.iodevice.setBinaryOutput(134979129, j, False) # "EZi08T" output X OFF
    indigo.device.statusRequest(134979129) # "EZi08T"
   
    time.sleep(1)
    ezio8t.refreshFromServer(waitUntilServerIdle=True)
   
    stillOn = False
    for state in ["binaryOutput1", "binaryOutput2", "binaryOutput3", "binaryOutput4", "binaryOutput5", "binaryOutput6"]:
        stillOn = stillOn or ezio8t.states[state]
    if not stillOn:
        break

joe (aka FlyingDiver)
my plugins: http://forums.indigodomo.com/viewforum.php?f=177

Posted on
Tue Dec 03, 2019 4:15 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Nice, thanks. But...

While shorter and cleaner, I have to consider my old brain, too!

For example, I knew "for i in range(30):" at some point in time, but needed to have Matt refresh my aging memory. Sometimes I forgo the cleanest code for more lines, so that I can better read and comprehend it in months/years to come, without having to stare too long at it!! :D

In this case, your version will not execute significantly faster or slower than my verbose version, so I'll likely stick with the more dumbed-down version.

As I mentioned somewhere else, I tend to get carried away with this stuff, coming up with all kinds of cool functionality, but I later can't remember the how or why of it. I have to keep myself in check sometimes!

Posted on
Wed Dec 04, 2019 5:31 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

OK, this is what I'm testing today. I moved the EZIO8T output control script to an external file, to eliminate the errors I've been getting (because it sometimes takes longer than 10 seconds to execute).

I run a small external py script file to establish the parameter, from an Action Group, and then that script imports and executes the "master" file. Matt explained that I can't import the "master" file (even though externally located) into an internal py script, because it will then execute "internally," and still bump into the 10 seconds limit. This was the only way I could figure out how to pass parameters to an external py file. I could do it with variables, I suppose, but it "feels" more reliable to do it this way.

So an Action Group executes this linked external script file:
Code: Select all
# calls indigo_irrigation.valveOn('1')
import indigo_irrigation
indigo_irrigation.valveOn('1')


I have six of those: to pass parameters "1" thru "6", and a seventh to pass a parameter of "0", which executes the portion of the script that turns off all the outputs, but doesn't then turn any on. I use the latter a lot: before I turn any valves on, and after all the schedules execute. I also run it once an hour, 24-7, just to make sure my irrigation doesn't run and run and run for days, should an output somehow come on, or stay on after it's supposed to be off (darn EZIO8T reliability).

That small py script file imports and executes the "master" script:
Code: Select all
"""
indigo_irrigation.py
controls EZIO8T outputs, with redundancy to accommodate its unreliability
tests each output (for on or off) and logs any errors, including number of repeat attempts

In this file you can insert any methods and classes that you define.
They will be shared by all Python scripts - you can even import the
IOM (as shown below) but if you do then you'll only be able to import
this script in Python processes started by Indigo. If you don't need
the IOM then skip the import and it'll work in any Python script
no matter where it's run from.
"""

try:
    import indigo
except ImportError:
    print "Attachments can only be used from within Indigo"
    raise ImportError

import time
   
def valveOn(mWhichValve):
   # turns off EZi08T outputs 1-6 and repeats until they are all off
   indigo.server.log("indigo_irrigation.valveOn('"+mWhichValve+"') executing...", type="External Script")
   maxAttempts = 5 # number of times repeat loops will attempt to turn on or off an exio8t output
   repeatCounterOn = 0
   ezio8t = indigo.devices[134979129] # "EZi08T"
   for repeatCounterOff in range(maxAttempts):
      indigo.iodevice.setBinaryOutput(134979129, 0, False) # "EZi08T" output 1 OFF
      indigo.iodevice.setBinaryOutput(134979129, 1, False) # "EZi08T" output 2 OFF
      indigo.iodevice.setBinaryOutput(134979129, 2, False) # "EZi08T" output 3 OFF
      indigo.iodevice.setBinaryOutput(134979129, 3, False) # "EZi08T" output 4 OFF
      indigo.iodevice.setBinaryOutput(134979129, 4, False) # "EZi08T" output 5 OFF
      indigo.iodevice.setBinaryOutput(134979129, 5, False) # "EZi08T" output 6 OFF
      indigo.device.statusRequest(134979129) # "EZi08T"
      time.sleep(1)
      ezio8t.refreshFromServer(waitUntilServerIdle=True)
      binaryOutput1 = ezio8t.states["binaryOutput1"]
      binaryOutput2 = ezio8t.states["binaryOutput2"]
      binaryOutput3 = ezio8t.states["binaryOutput3"]
      binaryOutput4 = ezio8t.states["binaryOutput4"]
      binaryOutput5 = ezio8t.states["binaryOutput5"]
      binaryOutput6 = ezio8t.states["binaryOutput6"]
      if (not binaryOutput1) and (not binaryOutput2) and (not binaryOutput3) and (not binaryOutput4) and (not binaryOutput5) and (not binaryOutput6):
         break
   if mWhichValve in "123456":
      # turn on valve and repeat until it is really on
      if mWhichValve == "1":
         stateName = ("binaryOutput1")
         tTimerDuration = unicode(indigo.variables[128363799].value) # "irrigation_duration_1" value as unicode
      elif mWhichValve == "2":
         stateName = ("binaryOutput2")
         tTimerDuration = unicode(indigo.variables[1092635302].value) # "irrigation_duration_2" value as unicode
      elif mWhichValve == "3":
         stateName = ("binaryOutput3")
         tTimerDuration = unicode(indigo.variables[8186003].value) # "irrigation_duration_2" value as unicode
      elif mWhichValve == "4":
         stateName = ("binaryOutput4")
         tTimerDuration = unicode(indigo.variables[780129921].value) # "irrigation_duration_2" value as unicode
      elif mWhichValve == "5":
         stateName = ("binaryOutput5")
         tTimerDuration = unicode(indigo.variables[50403568].value) # "irrigation_duration_2" value as unicode
      elif mWhichValve == "6":
         stateName = ("binaryOutput6")
         tTimerDuration = unicode(indigo.variables[1214967738].value) # "irrigation_duration_2" value as unicode
      for repeatCounterOn in range(maxAttempts):
         indigo.iodevice.setBinaryOutput(134979129, (int(mWhichValve)-1), True) # "EZi08T" output x ON
         indigo.device.statusRequest(134979129) # "EZi08T"
         time.sleep(1)
         ezio8t.refreshFromServer(waitUntilServerIdle=True)
         binaryOutput = ezio8t.states[stateName]
         if binaryOutput:
            indigo.variable.updateValue(126668483, value=tTimerDuration) # "irrigation_timer"
            break
   if (repeatCounterOff >= (maxAttempts - 1)) or (repeatCounterOn >= (maxAttempts - 1)):
      indigo.server.log("indigo_irrigation.valveOn('"+mWhichValve+"') executed but exceeded maximum attempts limit! Off repeats: "+unicode(repeatCounterOff)+". On repeats: "+unicode(repeatCounterOn), type="External Script", isError=True)
      indigo.actionGroup.execute(848159626) # "Irrigation Valve Error Warning"
   elif (repeatCounterOff > 0) or (repeatCounterOn > 0):
      indigo.server.log("indigo_irrigation.valveOn('"+mWhichValve+"') executed with some repeats. Off repeats: "+unicode(repeatCounterOff)+". On repeats: "+unicode(repeatCounterOn), type="External Script", isError=True)
   else:
      indigo.server.log("indigo_irrigation.valveOn('"+mWhichValve+"') executed. Off repeats: "+unicode(repeatCounterOff)+". On repeats: "+unicode(repeatCounterOn), type="External Script")

"""
mWhichValve (parameter 1) can be:
   "0" (turns off all valves)
   "1" (turns off all valves and turns on valve 1)
   "2" (turns off all valves and turns on valve 2)
   "3" (turns off all valves and turns on valve 3)
   "4" (turns off all valves and turns on valve 4)
   "5" (turns off all valves and turns on valve 5)
   "6" (turns off all valves and turns on valve 6)
"""


The script keeps track if any of the off or on attempts needed to be repeated (based on checking the EZIO8T output status), and reports those in the log. If the attempts to turn outputs on or off exceeds a maximum of 5 attempts, the script calls an Action Group that alerts me with an email, a reminder AND a text. Again, I'm so paranoid about a valve staying on, that I built in a bunch of redundancy and error checking to help ward off a $500 water bill!!

If there's a more elegant way to do any of this, please let me know. Sorry, Joe, your excellent tips about how to use iteration to clean up some of this didn't make it in. As I explained, I'm using a more verbose version to help my ol' brain to understand the code better (now, and days/months/years from now).

Posted on
Thu Dec 05, 2019 2:18 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

For various reasons, I'm off-loading the garage door functions from my EZIO8T to a different device. Which means I can now send a single "all off" command to my EZIO8T, instead of having to send individual commands to each output.

But for the life of me I can't remember the Python for that. And I couldn't find it in the Devices documentation you provide online. I thought you gave that to me once before, but I can't find it... :(

Posted on
Thu Dec 05, 2019 9:18 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

I don't believe there is currently a python API for it, but there is a GUI Action using Type: Device Actions->Input/Output Controls->Turn Off All Outputs. You could create an Action Group that executes that then execute the Action Group via Python if you wanted.

Image

Posted on
Thu Dec 05, 2019 11:17 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Huh, well... that explains why I couldn’t find it! :lol: thanks anyway...

I know I’ve used the GUI version before, but I must have stopped and “invented” the turn-off-and-test loop gizmo instead, probably more EZIO8T reliability issues... This and the IO Link I’m buying are still power-line only, and continue/will continue to give me grief. A dual-band IO device is sorely needed...

Posted on
Thu Dec 05, 2019 11:41 pm
Mark offline
User avatar
Posts: 262
Joined: Apr 21, 2005
Location: California

Re: EZIO8SA, EZIO2X4, EZIO8T support in Indigo

Before I swapped most all devices for newer dual-band devices, which REALLY solved a ton of traffic issues for my entire HA setup, I had done this:

I put two dedicated breakers in my breaker box, one on each leg, and hard-wired them to an Insteon powerline bridge thingie near the breakers. I then ran a single, dedicated line of Romex to a dedicated multi-plug outlet near my HA computer, into which I plugged the Insteon modem and a bunch of dual-band devices, like a giant radio transmitter! Back at the box that houses the bridge, I wired in an outlet, into which I plugged the EZIO8T. That’s about as clean a non-RF setup you can have! STILL can’t get 100% reliability out of that dreaded EZ... :(

I wonder (1) if the new IO Link will be as bad, and (2) if plugging in an RF range extender into one of the outlets that the EZ and the new IO will be sharing would help... Well, I’ll know this weekend...

Who is online

Users browsing this forum: No registered users and 10 guests

cron