Troubleshooting Plugin Code

Posted on
Thu Sep 24, 2020 2:14 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Troubleshooting Plugin Code

For a number of years I've been using a device called "Web Energy Logger" (WEL) which uses a 1-wire bus to monitor sensors attached to my HVAC system. To display in Indigo, I hacked together a modification of the NOAA Weather plugin to gather data from the WEL, which is accessed as an XML listing via HTTP. This has been working fine for quite some time. This week, I added three sensors to the WEL system, and added them to the plugin.py and devices.xml files. Indigo yields an error when the plugin reloads, stating that one of the new devices is not found in dict. And none of the three new data points are available in Indigo.

The error:
Code: Select all
 Enabling plugin "WEL Data 1.0.0"
   Starting plugin "WEL Data 1.0.0" (pid 562)
   Started plugin "WEL Data 1.0.0"
   WEL Data Error                  exception in deviceStartComm(Web Energy Logger): 'key returnDeltaT not found in dict'
The new devices ("States"), from plugin.py, are the following:
Code: Select all
"hotWaterTemp":'Water_Hot',"coldWaterTemp":'Water_Cold',"returnDeltaT":'AirRetDeltaT'

The XML output from the WEL:
Code: Select all
<Devices>
<Device Name="Date" Value="09/24/2020"/>
<Device Name="Time" Value="15:52:29"/>

********* Snipped to save space

<Device Name="HP_ReturnDnT" Value="70.137489"/>
<Device Name="HP_ReturnUpT" Value="71.599998"/>
<Device Name="AirRetDeltaT" Value="1.480553"/>
<Device Name="Water_Hot" Value="100.399986"/>
<Device Name="Water_Cold" Value="75.537498"/>
</Devices>

The pertinent part of devices.xml from the plugin package:
Code: Select all
<?xml version="1.0"?>
<Devices>
   <!-- Define some devices -->
   <Device type="custom" id="welData">
      <Name>WEL Data</Name>
      <ConfigUI>
      </ConfigUI>
      <States>
         <State id="dataDate">
            <ValueType>String</ValueType>
            <TriggerLabel>Data Date</TriggerLabel>
            <ControlPageLabel>Data Date</ControlPageLabel>
         </State>         
         <State id="dataTime">
            <ValueType>String</ValueType>
            <TriggerLabel>Data Time</TriggerLabel>
            <ControlPageLabel>Data Time</ControlPageLabel>
         </State>

         *******Snipped for brevity ***********

         <State id="upstairsReturnTemp">
            <ValueType>Number</ValueType>
            <TriggerLabel>Upstairs Return Temp °F</TriggerLabel>
            <ControlPageLabel>Upstairs Return Temp °F</ControlPageLabel>
         </State>
         <State id="downstairsReturnTemp">
            <ValueType>Number</ValueType>
            <TriggerLabel>Downstairs Return Temp °F</TriggerLabel>
            <ControlPageLabel>Downstairs Return Temp °F</ControlPageLabel>
         </State>
         <State id="hotWaterTemp">
            <ValueType>Number</ValueType>
            <TriggerLabel>Hot Water Temp °F</TriggerLabel>
            <ControlPageLabel>Hot Water Temp °F</ControlPageLabel>
         </State>
         <State id="coldWaterTemp">
            <ValueType>Number</ValueType>
            <TriggerLabel>Cold Water Temp °F</TriggerLabel>
            <ControlPageLabel>Cold Water Temp °F</ControlPageLabel>
         <State id="returnDeltaT">
            <ValueType>Number</ValueType>
            <TriggerLabel>Return Temp Difference °F</TriggerLabel>
            <ControlPageLabel>Return Temp Difference °F</ControlPageLabel>
         </State>
         </State>
      </States>
   </Device>
</Devices>

The Global fields from plugin.py:
Code: Select all
fields = {"dataDate":'Date',"dataTime":'Time',"TEST":'test',"propHeat":'PropHeating',"outdoorTemp":'OutdoorT',"stage2":'HP_ComprHi',"cooling":'HP_Cool1S',"heating":'HP_Heat1S',"defrost":'HP_Defrost',"vaporTemp":'HP_VaporT',"liquidTemp":'HP_LiquidT',"supplyTemp":'HP_SupplyT',"downstairsReturnTemp":'HP_ReturnDnT',"upstairsReturnTemp":'HP_ReturnUpT',"hotWaterTemp":'Water_Hot',"coldWaterTemp":'Water_Cold',"returnDeltaT":'AirRetDeltaT'}

The Device Update code from plugin.py:
Code: Select all
def update(self,device):
      self.debugLog("Updating device: " + device.name)
      # download the file
      try:
         f = urllib2.urlopen(theUrl)
      except urllib2.HTTPError, e:
         self.errorLog("Error getting data: %s" % (device.pluginProps["address"], str(e)))
         return
      theXml = f.read()
      theDocTree = parseString(theXml)
      for node in theDocTree.getElementsByTagName("Device"):
         for state,fieldName in fields.iteritems():
            name = node.getAttribute("Name")
            value = node.getAttribute("Value")
            if name == fieldName:
               newValue = value
               if (fieldName == "OutdoorT")|(fieldName=="HP_VaporT")|(fieldName=="HP_LiquidT")|(fieldName=="HP_SupplyT")|(fieldName=="HP_ReturnDnT")|(fieldName=="HP_ReturnUpT")|(fieldName=="AirRetDeltaT")|(fieldName=="Water_Hot")|(fieldName=="Water_Cold"):
                  newValue = str(round(float(value),1))
               if value == "0.000000":
                  newValue = "0"
               if value == "1.000000":
                  newValue = "1"
               self.updateDeviceState(device, state, newValue)

I've obviously made an error entering the three new devices/states, but I can't see any discrepancy among the various places the new name pairs appear, nor do I see any difference with the already added devices, which the plugin processes without a problem. Any help here would be appreciated!

Posted on
Thu Sep 24, 2020 2:54 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

If this is occurring on an existing Indigo device (that is, you didn't delete and re-create a new device after your changes), then try calling stateListOrDisplayStateIdChanged() on the device instance in your plugin. That will force Indigo to read in the XML changes.

Code: Select all
dev.stateListOrDisplayStateIdChanged()

Image

Posted on
Thu Sep 24, 2020 3:21 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

Thanks, Matt. Must admit I really don't know where to put that. Tried in the following block
Code: Select all
   def updateDeviceState(self,device,state,newValue):
      dev.stateListOrDisplayStateIdChanged()
      if (newValue != device.states[state]):
         device.updateStateOnServer(key=state, value=newValue)

and got this error:
Code: Select all
   WEL Data Error                  exception in deviceStartComm(Web Energy Logger): global name 'dev' is not defined


I'm not at all comfortable in python and just hacked the NOAA weather plugin (since it uses XML calls) to work.

I also saved a copy of the DB, recreated the device,, and could not check the "comm enabled" block, so that approach didn't work either.

Posted on
Thu Sep 24, 2020 3:39 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

In that method the instance is referred to as 'device' and not 'dev.' I would also only call it when needed, so try something like this:

Code: Select all
   def updateDeviceState(self,device,state,newValue):
      if state not in device.states:
         device.stateListOrDisplayStateIdChanged()
      if (newValue != device.states[state]):
         device.updateStateOnServer(key=state, value=newValue)

Image

Posted on
Thu Sep 24, 2020 3:54 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

Tried your code block and got the same error from my OP:

Code: Select all
WEL Data Error                  exception in deviceStartComm(Web Energy Logger): 'key returnDeltaT not found in dict'

Posted on
Thu Sep 24, 2020 3:58 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

Has that updateDeviceState() method been called yet? Maybe it just hasn't had an update yet?

Image

Posted on
Thu Sep 24, 2020 4:04 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

The device is set to update at 10 second intervals, but doesn't update after the plugin reloads.

However, two of the new states (hot and cold water) are now shown in Indigo device details --> custom states, although with values of zero. The state in the error does not appear in the custom states listing.

Posted on
Thu Sep 24, 2020 4:16 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

Let's take a step back – can you just create a new version of the device (and delete the old)? I believe that will fix the problem. Note all of the Device's dependencies will need to be updated (which may make this solution not viable). I would suggest creating the new device, then updating all the dependencies (triggers, control page controls, etc.) to use the new device then finally delete the old device. Basically, don't delete the old device until all the dependencies are fixed or Indigo might delete those Triggers, etc. It will warn you first though, so you can try out the delete to see if you get the warning. Also make a backup of your database first.

Image

Posted on
Thu Sep 24, 2020 4:24 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

New device in the main window will not let me check "Comm Enabled" even though that block is checked in the edit device window. And the "returnDeltaT" state is not listed in the custom states window; all other states show zero values (which I would presume is consistent with no comms.

Posted on
Thu Sep 24, 2020 4:53 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

Copy/paste what you are seeing in the Event Log into a reply when creating a new device.

Image

Posted on
Thu Sep 24, 2020 5:24 pm
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

Only the following line:
Code: Select all
Error (client)                  runDialogForDevice() caught exception: PAXDialogControllerError -- Dialogs must contain at least one <Field> element.


I believe that's because there is no configure dialog in the plugin.

Posted on
Fri Sep 25, 2020 7:41 am
BillC offline
Posts: 237
Joined: Mar 09, 2008

Re: Troubleshooting Plugin Code

OK, with the original device still in place (and no new one) I have managed to get two of the new custom states to register by removing the state shown in the error 'key returnDeltaT not found in dict' from the "Globals - Fields= " declaration.

Now to see what the issue is with that custom state.

Really appreciate your help, Matt. Will report anything new (or if I'm still frustrated in a few hours!)

EDIT: SOLVED but I don't know how. When I removed the state as described above, I cmd-x deleted and pasted as a remark line. I then copied the same state declaration and pasted it back into the Fields declaration, and it worked.

As I said, I'm not that familiar with python, but I know it's picky about formatting (spaces, tabs, etc.). I must have corrected something but darned if I know what.

Again, bottom line, it works. Thanks so much for your time, Matt. Sorry to have wasted it!

Posted on
Sat Sep 26, 2020 2:50 pm
matt (support) offline
Site Admin
User avatar
Posts: 21411
Joined: Jan 27, 2003
Location: Texas

Re: Troubleshooting Plugin Code

Tabs versus spaces don't matter for XML but they can confuse things for python files. Sounds like you were editing the XML file (I think?), so the spacing shouldn't have mattered.

Regardless, I'm glad you got it working!

Image

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 6 guests