1) The primary focus of the plugin is a control page tool to provide a different way of organizing and viewing indigo devices. (updates don't have to be continual or happen with every device or variable, just when actively viewing a control page).
2)The plugin could be used to trigger events (so the user may want more frequent updating)
1+2 = I would like to have multiple ways to update (when the user does something that will change states + ability to change the background update frequency)
Foo is a chunk of code that updates a laundry list of device metadata. The metadata is a map to the source device/variable or text (about 140 lines or so). It will be called when a device is created, updated, and when a few different actions are called.... So I'll need to use that 140+/- lines about 11 times. I could just copy-paste the lines in for every place I need it, but that would add an extra 1400 lines to the overall script.
The plugin doesn't have to update in the background to function if the plugin is used primarily as a control page tool. If the plugin is used to trigger other things from, then more frequent updates would be important. So, the update function is presently in the runConcurrentThread. The "self.sleep" interval can be manipulated from the plugin config dialog.
Right now, the update function updates 16 states. Once I figure out where everything should go, that will be expanded to the full 60 device states. I won't know the server impact until I fully build out 60 device states for 10 or so plugin devices. Right now, sleep=5, 3 devices @ 16 states = 0.2% of my cpu. (when looking at the plugin PID).
So, at a minimum, it's important to update the states whenever they are charged by the user (4 different actions) or whenever the control page actions are run (5 different actions) Plus 1 (update all now action)... 10 actions + 1 runConcurrent = 11 places where I would use an updateAll function
- Code: Select all
def updateAllFromMetadata():
for dev in indigo.devices.iter(filter="com.whmoorejr.my-rooms"):
###### Identifier States
subRoomName = self.substitute(dev.pluginProps.get("meta_roomName","unknown"))
subRoomState = self.substitute(dev.pluginProps.get("meta_roomState","Other"))
subFloorLevel = self.substitute(dev.pluginProps.get("meta_floorLevel","unknown"))
subBuilding = self.substitute(dev.pluginProps.get("meta_building","unknown"))
###### Occupancy States
subIsOccupied = self.substitute(dev.pluginProps.get("meta_isOccupied","unknown"))
subLastOccupied = self.substitute(dev.pluginProps.get("meta_lastOccupied","unknown"))
subLastVacant = self.substitute(dev.pluginProps.get("meta_lastVacant","unknown"))
subOccupiedBy1 = self.substitute(dev.pluginProps.get("meta_occupiedBy1","unknown"))
subOccupiedBy2 = self.substitute(dev.pluginProps.get("meta_occupiedBy2","unknown"))
###### Lighting Device States
subMainLight = self.substitute(dev.pluginProps.get("meta_mainLight","unknown"))
subAccentLight = self.substitute(dev.pluginProps.get("meta_accentLight","unknown"))
subLuminescence = self.substitute(dev.pluginProps.get("meta_luminescence","unknown"))
subWindowShades = self.substitute(dev.pluginProps.get("meta_windowShades","unknown"))
###### Climate Device States
subTemperature = self.substitute(dev.pluginProps.get("meta_temperature","unknown"))
subHumidity = self.substitute(dev.pluginProps.get("meta_humidity","unknown"))
subCeilingFan = self.substitute(dev.pluginProps.get("meta_ceilingFan","unknown"))
###### Outlet Device States <- need to populate this
###### Audio/Vidoe Device States <- need to populate this
###### Security Device States <- need to populate this
###### Auxiliary Device States <- need to populate this
#indigo.server.log("Sleep Test") # <-- for testing
updatedStates = [
{'key' : u'roomName', 'value' : subRoomName},
{'key' : u'roomState', 'value' : subRoomState},
{'key' : u'floorLevel', 'value' : subFloorLevel},
{'key' : u'building', 'value' : subBuilding},
{'key' : u'isOccupied', 'value' : subIsOccupied},
{'key' : u'lastOccupied', 'value' : subLastOccupied},
{'key' : u'lastVacant', 'value' : subLastVacant},
{'key' : u'occupiedBy1', 'value' : subOccupiedBy1},
{'key' : u'occupiedBy2', 'value' : subOccupiedBy2},
{'key' : u'mainLight', 'value' : subMainLight},
{'key' : u'accentLight', 'value' : subAccentLight},
{'key' : u'luminescence', 'value' : subLuminescence},
{'key' : u'windowShades', 'value' : subWindowShades},
{'key' : u'temperature', 'value' : subTemperature},
{'key' : u'humidity', 'value' : subHumidity},
{'key' : u'ceilingFan', 'value' : subCeilingFan}
]
dev.updateStatesOnServer(updatedStates)
if subRoomState == "On":
dev.updateStateImageOnServer(indigo.kStateImageSel.SensorOn)
elif subRoomState == "Off":
dev.updateStateImageOnServer(indigo.kStateImageSel.SensorOff)
else:
dev.updateStateImageOnServer(indigo.kStateImageSel.SensorTripped)
I considered the subscribeToChanges route, but since the plugin can utilize any state from any device or any variable... the plugin would have to look at every device change and every variable change across all of indigo and if the user is only using the plugin as a control page tool, that would be a lot of unnecessary server load if their plugin devices are associated with a ton of other devices/variables.
Example, a light switch with a motion detector in a kids room will be updating/changing almost consistently... Do I need a control page I'm not looking at updating consistently? Or is it okay if the state only updates when I run the action to view the page or press a button on the page to "update now" or wait 5, 10, 30, 60 seconds etc, for the runConcurrent to do it's thing?
A lot of guessing on my part as I'm learning as I go.... I just learned how to write a runConcurrentThread yesterday. (Thank you Karl for helping baby-step me through that process)