Custom Device Type Stuck on Sensor Image and address UI

Posted on
Wed Dec 16, 2020 11:39 am
whmoorejr offline
User avatar
Posts: 522
Joined: Jan 15, 2013
Location: Houston, TX

Custom Device Type Stuck on Sensor Image and address UI

I'm now on beta version 118 (I really stink at writing code), and I'm stuck on two things.. Updating a sensor image and updating the address uiValue

1) kStateImageSel.Sensor....
    My device id="homeState" with list options "Home" "Away" and "Unsure"
    My Actions has a plugin action that sets with either "Home", "Away" or "Unsure"
    My plugin.py is correctly updating "homeState", but the image isn't cooperating. "Away" = grey dot (good), "Unsure" = red dot (good), "Home" = red dot (bad)
Code: Select all
   def setHomeState(self, pluginAction, dev):
      self.debugLog(u"setHomestate Action called:\n" + str(pluginAction))
      dev.updateStateOnServer(key="homeState", value=str(pluginAction.props.get(u"homeStateField")))
      HomeStateValue = str(pluginAction.props.get(u"homeStateField"))
      if HomeStateValue == "Home":
         dev.updateStateImageOnServer(indigo.kStateImageSel.SensorOn)
            
      if HomeStateValue == "Away":
         dev.updateStateImageOnServer(indigo.kStateImageSel.SensorOff)
            
      else:
         dev.updateStateImageOnServer(indigo.kStateImageSel.SensorTripped)
Edit [#1 Solved]: if elif else :oops:

2) Address UI
    I use two states for address which are mirrored, email1address and address.
    The plugin action correctly updates both states with the entered text string
    The uiValue remains at " - none - "
Code: Select all
   def setEmail1Address(self, pluginAction, dev):
      self.debugLog(u"setEmail1Address Action called:\n" + str(pluginAction))
      addressVar = str(pluginAction.props.get(u"email1AddressField"))
      dev.updateStateOnServer(key="email1Address", value=addressVar)
#      dev.updateStateOnServer(key="address", value=addressVar)
      dev.updateStateOnServer("address",addressVar, uiValue=addressVar)
#      dev.updateStateOnServer("address","A Thing", uiValue="Another Thing")


Any pointers would be appreciated. (This is my first plugin attempt and it's been brutal).
Attachments
Screen Shot 2020-12-16 at 10.08.05 AM.png
Screen Shot 2020-12-16 at 10.08.05 AM.png (15.06 KiB) Viewed 598 times
Screen Shot 2020-12-16 at 9.51.07 AM.png
Screen Shot 2020-12-16 at 9.51.07 AM.png (8.33 KiB) Viewed 598 times

Bill
My Plugin: My People

Posted on
Wed Dec 16, 2020 12:12 pm
autolog offline
Posts: 3506
Joined: Sep 10, 2013
Location: West Sussex, UK [GMT aka UTC]

Re: Custom Device Type Stuck on Sensor Image and address UI

Change "if HomeStateValue == "Away":" to "elif HomeStateValue == "Away":"

Your logic at the moment checks for Home and sets the image state.

You then check it for "Away and if so set the state image else if it isn't "Away" (which is what Home is) you set it to a red dot. :)

EDIT: Beat me to it! :D

Posted on
Wed Dec 16, 2020 12:22 pm
FlyingDiver offline
User avatar
Posts: 5335
Joined: Jun 07, 2014
Location: Southwest Florida, USA

Re: Custom Device Type Stuck on Sensor Image and address UI

Code: Select all
   def setEmail1Address(self, pluginAction, dev):
      self.debugLog(u"setEmail1Address Action called:\n" + str(pluginAction))
      addressVar = str(pluginAction.props.get(u"email1AddressField"))
      dev.updateStateOnServer(key="email1Address", value=addressVar, uiValue= addressVar)
      dev.updateStateOnServer(key="address", value=addressVar, uiValue= addressVar)


I'm not sure you can actually set a uiValue for "address", as it's a property of the device, not a custom state.

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

Posted on
Wed Dec 16, 2020 12:27 pm
autolog offline
Posts: 3506
Joined: Sep 10, 2013
Location: West Sussex, UK [GMT aka UTC]

Re: Custom Device Type Stuck on Sensor Image and address UI


Posted on
Wed Dec 16, 2020 3:10 pm
whmoorejr offline
User avatar
Posts: 522
Joined: Jan 15, 2013
Location: Houston, TX

Re: Custom Device Type Stuck on Sensor Image and address UI

FlyingDiver wrote:
I'm not sure you can actually set a uiValue for "address", as it's a property of the device, not a custom state.
. Not sure.... I was following this snippet from Matt.... but I got tangled up somehow. https://forums.indigodomo.com/viewtopic.php?f=108&t=18184#p174184
Code: Select all
dev.updateStateOnServer("address", "192.168.0.10:1", uiValue="IP:switch -- 192.168.0.10")


autolog wrote:
See this thread:

Ok, I think I know where I got confused.... I though anything with an id="address" would automatically populate the indigo main screen with that information. I guess it's when a Field id="address" in the devices.xml has a value.... that value is plopped onto the screen.

I rearranged some stuff and added a button to the devices.xml ConfigUI that does a setAddEmail callback to take the email address from the Field id="address" and save it as the state id="email1Address".

but now I'm getting this:
My People Error Error in plugin execution UiAction:

Traceback (most recent call last):
TypeError: setAddEmail() takes exactly 3 arguments (4 given)

when using this:
Code: Select all
   def setAddEmail(self, pluginAction, dev):
      emailVar = dev.address
      self.debugLog(u"setAddEmail Action called:\n" + str(pluginAction))
      dev.updateStateOnServer(key="email1Address", value=emailVar)
and it looks like:
Screen Shot 2020-12-16 at 2.57.40 PM.png
Screen Shot 2020-12-16 at 2.57.40 PM.png (26.28 KiB) Viewed 545 times
I'd like to have it on the main indigo page, well, because it's pretty. I'd like it as a state so it's easier to script, put on control pages, trigger with it, etc.

Bill
My Plugin: My People

Posted on
Wed Dec 16, 2020 6:22 pm
matt (support) offline
Site Admin
User avatar
Posts: 20568
Joined: Jan 27, 2003
Location: Texas

Re: Custom Device Type Stuck on Sensor Image and address UI

If setAddEmail is a device dialog callback you specified in the devices.xml file, then the argument signature should be:

Code: Select all
   def setAddEmail(self, valuesDict, typeId, devId):

But if you just want to propagate dev.address into a state, then I'd suggest doing it in the deviceStartComm callback then you don't need the button at all. Untested, but something like:

Code: Select all
   def deviceStartComm(self, dev):
      if dev.pluginId == self.pluginId:
         dev.updateStateOnServer(key="email1Address", value=dev.address)

Image

Posted on
Wed Dec 16, 2020 6:50 pm
whmoorejr offline
User avatar
Posts: 522
Joined: Jan 15, 2013
Location: Houston, TX

Re: Custom Device Type Stuck on Sensor Image and address UI

matt (support) wrote:
Code: Select all
   def deviceStartComm(self, dev):
      if dev.pluginId == self.pluginId:
         dev.updateStateOnServer(key="email1Address", value=dev.address)
That worked flawlessly. Will that same method work with other items that are created in Devices.xml ConfigUI?

if I have <Field id="favoriteColor" type="textfield">

I have a <State id="favoriteColor"

can I...
Code: Select all
   def deviceStartComm(self, dev):      #<-- Right Place for this thing?
            if dev.pluginId == self.pluginId:
             dev.updateStateOnServer(key="email1Address", value=dev.address)
             dev.updateStateOnServer(key="favorteColor", value=dev.favoriteColor)
? Or is there another way to grab the field id text?

Bill
My Plugin: My People

Posted on
Fri Dec 18, 2020 3:31 pm
matt (support) offline
Site Admin
User avatar
Posts: 20568
Joined: Jan 27, 2003
Location: Texas

Re: Custom Device Type Stuck on Sensor Image and address UI

'address' is a special attribute exposed on the device instance, so for something like favoriteColor you need to use the pluginProps dict instead to retrieve the value:

Code: Select all
   def deviceStartComm(self, dev):
      if dev.pluginId == self.pluginId:
         dev.updateStateOnServer(key="favoriteColor", value=dev.pluginProps["favoriteColor"])

Image

Posted on
Sat Dec 19, 2020 11:22 am
whmoorejr offline
User avatar
Posts: 522
Joined: Jan 15, 2013
Location: Houston, TX

Re: Custom Device Type Stuck on Sensor Image and address UI

I think I'm getting my head wrapped around this.....

State id = key
field id = value=dev.pluginProps["fieldIDName"]

Is that just the property for a field id from the Device.XML?

In other word, If I have field id = "favorieColor" in the Device.XML for the configuration thing....Then in the Actions.XML I have a filed id ="favoriteColor", are those two different properties or are they writing over each other and mirroring each other?

Basically, I am looking for an easy way to set a bunch of states for a custom device with two different methods.
One state at a time via plugin action (working now, current method)
Bulk state update (either via a separate bulk update action or via the device configuration)

Where I'm getting stuck is....
Action Bulk update -> would need to pre-populate all states with current state information... so if the user doesn't want to update one of the states, it won't be overwritten with a blank " " when the action is run.

Device Configuration -> Can fill out every device state here (got that figured out). Can make all those fields update device states (Got that figured out now), but if a plugin action (Set Favorite Color) is run to update a device state, how do I update the pluginProps["favoriteColor"], or do I need to since field id="favoriteColor" (from Device.xml) is the same as field id="favoriteColor" (from Action.xml)? Will that "Action" automatically update the device configuration page?

Bill
My Plugin: My People

Posted on
Sat Dec 19, 2020 4:43 pm
jay (support) offline
Site Admin
User avatar
Posts: 16815
Joined: Mar 19, 2008
Location: Austin, Texas

Re: Custom Device Type Stuck on Sensor Image and address UI

There are 2 basic places to store data in any device: state (dev.states["stateKey"]), and device properties. Both are specified in the Devices.xml file (though can be managed outside of that). Device properties are actually one big dictionary (dev.globalProps), with the key being what plugin put the props there. So, if the ID of your plugin is com.jay.pluginId, then the props that your plugin stores in the device instance is dev.globalProps["com.jay.pluginId"]. There is also a shortcut that indigo adds as a Python Property (dev.ownerProps) that points to the properties that belong to the device's owner (and from within your plugin you can access via dev.pluginProps). Any plugin can add props to any device, and that plugin's props will be in the globalProps dictionary using the key from that plugin. This is how the Global Properties plugin adds arbitrary properties to a device in ways useful to other plugins.

<Field> elements in the <ConfigUI> element of your <Device> element are what are stored in the various props dictionaries. <State> elements in the <States> element of your <Device> element are what's shown in the custom states section of the UI and is accessible via dev.states dictionary. The key's for each dictionary are the id attributes to the <State> or <Field> element.

Properties for a device's config are completely separate from any other properties (in Actions, Events, etc).

To write/save the state values to a file, you'd want to iterate through the device.states dictionary and write the values out in whatever format you like. JSON would be much easier to read/write IMO, but you can do it in any format you like. Reading in values would be the process in reverse. You could set all states at the same time using dev.updateStatesOnServer (notice the plural States) passing it a dictionary of things to update.

I didn't want to give too much away, since this is a learning experience, but that should get you started... ;)

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Sat Dec 19, 2020 6:07 pm
DaveL17 offline
User avatar
Posts: 5909
Joined: Aug 20, 2013
Location: Chicago, IL, USA

Re: Custom Device Type Stuck on Sensor Image and address UI

A word of caution that took me a while to wrap my head around (and one that still trips me up from time to time). You programmatically update props like this:

Code: Select all
newProps = dev.pluginProps
newProps['propName'] = value
dev.replacePluginPropsOnServer(newProps)
Here's the important bit. If you then check to see that the operation has been successful by doing something like:

Code: Select all
indigo.server.log(str(dev.ownerProps))
Your new prop 'propName' will not show up. This is because in the first bit, newProps is taken from a copy of the device and not the device itself. You need to refresh your copy of the device from the Indigo server. So, all together:

Code: Select all
dev = indigo.devices[12345678]  # Gets a *copy* of the device.
newProps = dev.pluginProps
newProps['propName'] = value
dev.replacePluginPropsOnServer  # Puts the new prop on the *real* device

new_dev = indigo.devices[12345678]  # Gets a copy of the updated device
indigo.server.log(str(new_dev.ownerProps))  # this is where your new prop will show up.

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

[My Plugins] - [My Forums]

Posted on
Sun Dec 20, 2020 1:18 pm
matt (support) offline
Site Admin
User avatar
Posts: 20568
Joined: Jan 27, 2003
Location: Texas

Re: Custom Device Type Stuck on Sensor Image and address UI

This is a good point. I know in some cases Indigo automatically updates the local instance on which the API call is made (as well as telling the server to update its device), but that might just be for state updates and not pluginProps. Note there is a slightly more efficient way to refresh the device instance though compared to requesting an entire new copy from the server:

Code: Select all
dev.refreshFromServer()

Image

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 1 guest