Auto Company Modes for the Fingscan Plugin

Posted on
Fri Oct 14, 2016 9:34 pm
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Auto Company Modes for the Fingscan Plugin

So I am finally breaking down after nearly 50 devices that I consider company. I have all of my "non-company" devices in an outside folder. Any new devices automatically go into the default folder. What I would like to do is have a script running in the background constantly scanning the default folder and determining if any of these devices is up. If they are toggle a variable to on in Indigo and if they are all down, toggle a variable to off in Indigo. It's been a super long time since I've diddled with any scripting and I'm hoping to maybe get some help?

1. How do I set this up where it isn't taxing on my system, but quick enough to detect if a person has triggered company mode prior to even walking into our front door?

2. How do I set this script up to scan a folder?

Any direction to examples or help will be a great assistance!

Posted on
Sat Oct 15, 2016 6:11 am
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

Here's one way you can do it.

I don't think that you can only scan devices in a single folder (in my understanding, folders are attributes of devices rather than objects that contain devices) but I could be wrong about that. This script shouldn't be a heavy lift for Indigo, depending on how often you want to run it.

Code: Select all
company_devices = []
folder_id = 1314917481
variable_id = 1961258112

for dev in indigo.devices.itervalues():

    if dev.folderId == folder_id:
        try:
            company_devices.append(dev.states['onOffState'])
        except:
            pass

# Test the list. Returns True if any item is True
if any(company_devices):
    indigo.variable.updateValue(variable_id, 'on')
else:
    indigo.variable.updateValue(variable_id, 'off')

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Sat Oct 15, 2016 6:55 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Re: Auto Company Modes for the Fingscan Plugin

Thanks Dave!

Code: Select all
 company_devices.append(dev.states['onOffState'])
        except:
            pass

I assume this is checking to see if any devices are up or down?

If we are looking at each individual called out device, why are we specifying a folder?

Sorry for all the questions. Trying to learn as well as getting something to function :)

Posted on
Sat Oct 15, 2016 7:57 am
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

That segment of code is adding the on/off state of each device to a list. If the device doesn't support an on/off state, we skip it (we'll need to be a bit more creative if you want to track devices that don't have an on/off state).

We are looking at all devices because we need to see which folder they're in. It's a little bit counter intuitive, but folders are actually an attribute of devices and not an entity into and among themselves. Think of it this way: if you had a parking lot full of cars, you could have a subset of those cars that are blue; but those cars aren't literally in a subset, so you need to look at each one to see if it's blue. In the same way we need to look at each device to see if it's in the "company folder".

So we look at each device, and if it's in the company folder we record its on/off state. If any of the on/off states are True (or on), we set the value of the company variable to on.

I hope that makes sense. Please feel free to keep asking questions.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Sat Oct 15, 2016 8:37 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Re: Auto Company Modes for the Fingscan Plugin

Thanks! That does make sense... it's not as if we can already see what is in a folder with the way it is structured... as far as we know anyway.

That brings us to these devices. They do not have an on/off state. They have a custom state that is called "status". This status can be one of three states, Up (on the network), Down (off the network) or expired (off the network for a period of time).

So basically I need to look at the list of devices, which I would put the blob of id's into the first list in the code and determine if any of them are "Up". This would trigger my variable to "on". The other part for "off" would be if they all are NOT up, or if they are all expired or off. If I recall, it should be easier to just code for not equal. != if I remember correctly.

So with these being custom states and not being a baked in on/off from a standard indigo device, how would the code change?

Code: Select all
# get the device
dev = indigo.devices[23989834]  # Some custom device
# access the state through the states property, use the key
# that's displayed in the Custom States tile on the main window
# when you have a custom device selected
print dev.states["someDeviceStateKey"]


Would the "key" simply be "status"?

Posted on
Sat Oct 15, 2016 1:24 pm
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

I assume that these other devices are also in the company folder, so we're probably good there. But we can't evaluate them in the same way because "Up", "Down", and "Expired" will all evaluate to True. I think the easiest method is to use a second, separate list for these devices and then we can evaluate them separately.

Code: Select all
company_devices_1 = []
company_devices_2 = []
folder_id = 1314917481
variable_id = 1961258112

for dev in indigo.devices.itervalues():

    if dev.folderId == folder_id:
        try:
            company_devices_1.append(dev.states['onOffState'])
        except:
            pass
       
        try:
            company_devices_2.append(dev.states['status'])
        except:
            pass

# Test the list.
if any(company_devices_1) or any(x=='Up' for x in company_devices_2) :
    indigo.variable.updateValue(variable_id, 'on')
else:
    indigo.variable.updateValue(variable_id, 'off')

This is untested if not inelegant, but should work. It will set the variable to on if any device in the company folder has an onOffState of True or status of Up.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Sat Oct 15, 2016 7:15 pm
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Re: Auto Company Modes for the Fingscan Plugin

I guess I don't quite follow. Why are we doing two lists and how would those lists differ?

Also, why are we checking onoffstate if the device does not contain that?

Posted on
Sat Oct 15, 2016 9:15 pm
kw123 offline
User avatar
Posts: 8333
Joined: May 12, 2013
Location: Dallas, TX

Re: Auto Company Modes for the Fingscan Plugin

Don't know if this is what you want, but anyway

you could loop through ALL devices and see if they are in a specify folder. the check if a certain state is "UP"
Code: Select all
# you need to set this folder id
selectedFolder = 457461663

for dev in indigo.devices: # go through ALL indigo devices
   if dev.folderId !=selectedFolder: continue # wrong folder
   if "status" not in dev.states: continue # device has no status field
   if dev.states["status"].lower() =="up": continue  # it is up, fine, ignore
   # found a device in the folder that is not up
   indigo.server.log("device:"+ dev.name+" is not up")

print to log file:
Code: Select all
   Script                          device:UniFi-amazon-clorox is not up
   Script                          device:UniFi-amazon-glad is not up
   Script                          device:UniFi-amazon-larabar is not up
   Script                          device:UNIFI-amazon-tide is not up
   Script                          device:UniFi-android-1 is not up
   Script                          device:UniFi-awsIOT is not up
   Script                          device:UniFi-cam-7 is not up
   Script                          device:UniFi-chromecast is not up
   Script                          device:UniFi-iPhone-5 is not up
   Script                          device:UniFi-karl-iphone-6 is not up
   Script                          device:UniFi-printer-samsung is not up
   Script                          device:UniFi-raspberry-temperature for leo is not up
   Script                          device:UniFi-raspberry-test2 is not up
   Script                          device:UniFi-rpi-0 is not up
   Script                          device:UniFi-samsung-printer is not up
   Script                          device:UniFi-sonos-1 is not up
   Script                          device:UniFi-sonos-2 is not up
   Script                          device:UniFi-sonos-4 is not up
   Script                          device:UniFi-sonos-5 is not up
   Script                          device:UniFi-sonos-6 is not up



Karl

Posted on
Sun Oct 16, 2016 4:05 am
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

Dewster35 wrote:
I guess I don't quite follow. Why are we doing two lists and how would those lists differ?

In my approach, we maintain two lists because we're tracking two different device states (actually more than two state values) that contain different value types. The first list --company_devices_1 -- will hold the current state of all devices that support the onOffState (True or False). We evaluate that list later to see if any of the states that we've collected are True (the device is on). If yes, we set the variable to on. The second list -- company_devices_2 -- will hold the current state of all devices that support the 'status' state (Up or Down or Expired). We evaluate that list later to see if any of the states that we've collected are Up. If yes, we set the variable to on.

When we evaluate the first list we've created, we search it to see if any of its values are True. When we evaluate the second list we've created, we search it to see if any of its values are Up. We need a separate list because in Python Up/Down/Expired will all evaluate to True if we examine their 'truthiness', so if we added them to the first list, our result would always be True (you would always have company).

Also, why are we checking onoffstate if the device does not contain that?

In my approach, we're first seeing if a device contains the state 'onOffState'. We do this by trying to add the device's onOffState to our list. If the device doesn't contain that state, our attempt will fail and "throw an exception." We ignore the exception and move on to trying to evaluate our next state 'status'. If our device doesn't support either of those two states (fails both tests) we skip it and move on to the next device. If a device somehow supports both the 'onOffState' and 'status' states, it will be evaluated for both. You can think about the try/except bock as meaning "If device x supports the onOffState, then do something". There are other ways that we could do this. For example, instead of the try/except test, we could also do this:

Code: Select all
if 'onOffState' in dev.states:
    # do something

Which is more human-friendly on the face; however, in my opinion, it's less optimal because we have to search every state of every device we evaluate to see if it passes the test. With the try/except block, we cut right to the chase and if the test fails (we've only effectively evaluated one state per device) we move on to the second test.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Mon Oct 17, 2016 5:38 am
johnpolasek offline
Posts: 911
Joined: Aug 05, 2011
Location: Aggieland, Texas

Re: Auto Company Modes for the Fingscan Plugin

DaveL17 wrote:
For example, instead of the try/except test, we could also do this:

Code: Select all
if 'onOffState' in dev.states:
    # do something

Which is more human-friendly on the face; however, in my opinion, it's less optimal because we have to search every state of every device we evaluate to see if it passes the test. With the try/except block, we cut right to the chase and if the test fails (we've only effectively evaluated one state per device) we move on to the second test.


Ummmm, just being techincal here, but actually the "try/catch" methodology just hides the search "under the hood" by passing it off to the system, since the GetState("string") routine invoked by the ".onOffState" has to make the same comparisons in order to decide that the requested state is not in the list, THEN it has to generate a detailed "State Not found" object to hand up to the Try which then has to look through a list of Execpts (in your case 1 item long) to figure out which section gets control. I "try" to avoid Try/Excepts unless there are multiple ways for a block to fail and I want to do DIFFERENT things for each type of failure or if there is no clean "human readable" way to do it.

Posted on
Mon Oct 17, 2016 6:04 am
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

johnpolasek wrote:
Ummmm, just being techincal here, but actually the "try/catch" methodology just hides the search "under the hood" by passing it off to the system, since the GetState("string") routine invoked by the ".onOffState" has to make the same comparisons in order to decide that the requested state is not in the list, THEN it has to generate a detailed "State Not found" object to hand up to the Try which then has to look through a list of Execpts (in your case 1 item long) to figure out which section gets control. I "try" to avoid Try/Excepts unless there are multiple ways for a block to fail and I want to do DIFFERENT things for each type of failure or if there is no clean "human readable" way to do it.

Good to know, thanks. I find it curious, though, that the try/except block in the following example always seems to run faster than the if:
Code: Select all
import datetime as dt

states = {'Foo': 1, 'Bar': 2, 'foo': 3, 'bar': 4}
t_start = dt.datetime.now()

for n in range(1,10000000):
    if 'Foo' in states:
        states['Foo'] = 'a'

print dt.datetime.now() - t_start

t_start = dt.datetime.now()

for n in range(1,10000000):
    try:
        states['Foo'] = 'a'
    except:
        pass
       
print dt.datetime.now() - t_start

Maybe it's not a rational test.

ETA: Okay, I think I see it now. In the if, I need to find if the key is in the dict. If it is, I then set its value and have to search for the key again to do that. With the try, I'm only searching once.

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Mon Oct 17, 2016 6:54 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Re: Auto Company Modes for the Fingscan Plugin

I follow what your saying at a high level. Basically two different methods for searching for devices that have that state. Any help pointing me in the right direction for the syntax and the context of that in the full script?

I'm also curious. If we are putting a list of all those devices together, why do we care what folder it is in or if it has that state? For additional safety?

Posted on
Mon Oct 17, 2016 7:35 am
johnpolasek offline
Posts: 911
Joined: Aug 05, 2011
Location: Aggieland, Texas

Re: Auto Company Modes for the Fingscan Plugin

Dewster35 wrote:
I'm also curious. If we are putting a list of all those devices together, why do we care what folder it is in or if it has that state? For additional safety?


It makes it easy to change which devices are valid; I do the same thing with piBeacons that I use rather than WIFI devices; had too many issues with devices dropping off the list when they went to sleep or batteries died because they DIDN'T go to sleep. I've got a stable of tiles that I keep around to loan to weekend guests; They validate themselves continuously when sitting around in the kitchen drawer, but I want to ignore them until I give them to somebody, when I move the device from the "piBeacons" folder to the "Valid piBeacons" folder. Then when Jason gives it back when he heads out of town (or mails it back if he forgets) I move the device back into the piBeacons folder and the checker ignores them again.

Posted on
Mon Oct 17, 2016 7:58 am
DaveL17 offline
User avatar
Posts: 6741
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Auto Company Modes for the Fingscan Plugin

Dewster35 wrote:
I follow what your saying at a high level. Basically two different methods for searching for devices that have that state. Any help pointing me in the right direction for the syntax and the context of that in the full script?

If I understand your requirements, we're actually searching for two, totally separate things. One is devices that support the 'onOffState' and the other is to search for devices that support the 'status' state.

I believe that the revised script will do that:
Code: Select all
    company_devices_1 = []
    company_devices_2 = []
    folder_id = 1314917481
    variable_id = 1961258112

    for dev in indigo.devices.itervalues():

        if dev.folderId == folder_id:
            try:
                company_devices_1.append(dev.states['onOffState'])
            except:
                pass
           
            try:
                company_devices_2.append(dev.states['status'])
            except:
                pass

    # Test the list.
    if any(company_devices_1) or any(x=='Up' for x in company_devices_2) :
        indigo.variable.updateValue(variable_id, 'on')
    else:
        indigo.variable.updateValue(variable_id, 'off')


I'm also curious. If we are putting a list of all those devices together, why do we care what folder it is in or if it has that state? For additional safety?

We're putting together two lists to check to see if they meet the criteria that you established - an 'onOffState' that's ON (True) or a 'status' state of UP (not DOWN or EXPIRED). The reason that we're searching the company folder is because we want to skip your "non-company" devices as outlined in your original post, which I understood to be, "Give me all the devices in the company folder that are either ON or UP."

Perhaps I somehow misunderstood your requirements?

I came here to drink milk and kick ass....and I've just finished my milk.

[My Plugins] - [My Forums]

Posted on
Mon Oct 17, 2016 10:28 am
Dewster35 offline
Posts: 1030
Joined: Jul 06, 2010
Location: Petoskey, MI

Re: Auto Company Modes for the Fingscan Plugin

No but perhaps I should have been more clear. The only devices in that folder ARE fingscan devices. There are no other commingled devices inside that folder.

Who is online

Users browsing this forum: No registered users and 2 guests