Page 2 of 2

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 2:14 pm
by Suncroft
DaveL17 wrote:
What are you cutting and pasting from? There could be hidden characters that the embedded route doesn’t like.


Sent from my iPhone using Tapatalk


I have tried cut and paste from Ultra Edit text editor, also from a file via nano and finally I tried entering each line by line incase I was getting some strange carriage returns, Nothing changes.

Appreciate the ideas guys.

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 2:18 pm
by DaveL17
That is so weird. I’m stumped. If I think of any other possibilities, I’ll pass them on.


Sent from my iPhone using Tapatalk

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 2:43 pm
by FlyingDiver
And there's no errors in the Indigo log when you run the embedded script?

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 2:56 pm
by Suncroft
No errors in the indigo log :(

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 3:00 pm
by FlyingDiver
Where is the embedded script called from? A Schedule, Trigger, or Action Group? Are there any other actions before or after the script?

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Tue Feb 20, 2018 5:18 pm
by jay (support)
Also, how are you testing the embedded script?

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 4:36 am
by Suncroft
The embedded script is run via a schedule set to run every 1 minute, the condition is always and the action is Embedded Python. There are no other actions before or after the script. I have tried testing using the run command on the actions page of the schedule but I have also tried leaving the schedule to run on its own, but neither work.

@Jay, If you have 5 minutes spare I could setup team viewer for you to login to the box at your convenience that way you can see for yourself exactly whats happening.

Thanks

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 9:19 am
by matt (support)
After this line:

le = pyloopenergy.LoopEnergy(elec_serial, elec_secret)

add the following lines and copy/paste the Event Log results from running them both via a script and the interactive shell:
Code: Select all
indigo.server.log(str(elec_serial))
indigo.server.log(str(len(elec_serial)))
indigo.server.log(str(elec_secret))
indigo.server.log(str(len(elec_secret)))
indigo.server.log(str(type(pyloopenergy)))
indigo.server.log(str(pyloopenergy))
indigo.server.log(str(type(pyloopenergy.LoopEnergy)))
indigo.server.log(str(pyloopenergy.LoopEnergy))
indigo.server.log(str(type(le)))
indigo.server.log(str(le))
indigo.server.log(str(type(le.electricity_useage)))
indigo.server.log(str(le.electricity_useage))

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 5:51 pm
by Suncroft
Matt, here are the log outputs, I have had to replace the txt for 'elec_serial' and 'elec_secret' as these allow access to my Online Loop account, however the values in the log are identical and correct.

Log output run via script

21 Feb 2018, 23:16:08
Script xxxxxxxxxxxx
Script 12
Script yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
Script 64
Script <type 'module'>
Script <module 'pyloopenergy' from '/Library/Python/2.7/site-packages/pyloopenergy/__init__.pyc'>
Script <type 'classobj'>
Script pyloopenergy.loop_energy.LoopEnergy
Script <type 'instance'>
Script <pyloopenergy.loop_energy.LoopEnergy instance at 0x107fc0638>
Script <type 'NoneType'>
Script None

Log output run via interactive shell

21 Feb 2018, 23:37:28
Interactive Shell xxxxxxxxxxxx
Interactive Shell 12
Interactive Shell yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
Interactive Shell 64
Interactive Shell <type 'module'>
Interactive Shell <module 'pyloopenergy' from '/Library/Python/2.7/site-packages/pyloopenergy/__init__.pyc'>
Interactive Shell <type 'classobj'>
Interactive Shell pyloopenergy.loop_energy.LoopEnergy
Interactive Shell <type 'instance'>
Interactive Shell <pyloopenergy.loop_energy.LoopEnergy instance at 0x1144cc368>
Interactive Shell <type 'NoneType'>
Interactive Shell 1.267

Thanks

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 7:49 pm
by FlyingDiver
The first (embedded) output is missing the last line:
Code: Select all
indigo.server.log(str(le.electricity_useage))


What's really interesting is that both scripts are reporting "<type 'NoneType'>" for "type(le.electricity_useage)". That would indicate to me that they're both failing, but differently. Does the value
of 1.267 match the expected value from the website or app?

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 8:28 pm
by matt (support)
FlyingDiver wrote:
The first (embedded) output is missing the last line:
Code: Select all
indigo.server.log(str(le.electricity_useage))

Actually, it looks like the first script has it showing as "None." But you are correct in that it is really strange that the interactive shell is showing that le.electricity_useage has a type of NoneType but it still returns a value of 1.267. I don't understand how that is possible.

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Wed Feb 21, 2018 8:31 pm
by FlyingDiver
matt (support) wrote:
Actually, it looks like the first script has it showing as "None."


Oops. You're right. But the question remains...

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Thu Feb 22, 2018 11:02 am
by jay (support)
I have a theory: the pyloopenergy library creates a thread when you create the LoopEnergy object which creates a socket network connection. That thread adds an event callback handler for a message of 'electric_realtime' type. That, in turn, updates the self.elec_kw with the value received on the socket, but at init time that variable is initialized to None. That's the value that's represented in your script as le.electricity_useage.

My guess is that it takes a short amount of time for the value to be received from the network call and for that short amount of time, the value is None, and when we try to print it it returns None. However, once the value is received from the socket connection, the value updates, and we see the real value. Bottom line: you're seeing a slight timing difference between executing the script in the embedded script handler (where all embedded scripts run) and when running in the interactive shell (a different process, but using an identical environment).

Your script needs to give the library a chance to open the socket connection and then wait until it gets an update from that connection that contains the current electricity usage. We don't generally recommend sleeping in an embedded script, and further we don't really recommend doing network IO in an embedded script since network operations will often times time out (if you have network issues, if the remote system you're talking to goes down, etc).

Also, because creating/tearing down connections is expensive and your library is built to be used in a somewhat asynchronous way, I would recommend running the script as an external Python script from a Startup trigger so that it's just always running, getting the latest value from the LoopEnergy object, updating the Indigo variable, sleeping for a short time, and repeat. Here's a modified script:

Code: Select all
import pyloopenergy
import time
import traceback

elec_serial = 'xxxxxxxx';
elec_secret = 'yyyyyyyy';

try:
   # Create the LoopEnergy object, which will open network connections,
   # spawn it's network communication thread, and then just wait for
   # updates
   le = pyloopenergy.LoopEnergy(elec_serial, elec_secret)
   # Loop forever (until Indigo shuts down or there's an error)
   while True:
      try:
         # if le.electricity_usage has been updated and isn't None
         if le.electricity_usage:
            # update the Indigo variable with the value
            indigo.variable.updateValue(932431696,str(le.electricity_useage))
      except Exception as exc:
         # Because the pyloopenergy library may throw errors at any time, like
         # for instance if the network goes away, catch the error here but
         # continue to try to process. I don't know how the library handles
         # errors so an error here could be fatal but we assume that it can
         # recover.
         indigo.server.log(
            "Received an exception:\n{}".format(traceback.format_exc(10)),
            isError=True,
            type="LoopEnergy Script")
      # Sleep for 10 seconds before updating the Indigo variable again with the
      # new value.
      time.sleep(10)
except Exception as exc:
   # This will catch fatal errors that aren't handled elsewhere, primarily when
   # creating the LoopEnergy object.
   indigo.server.log(
      "Failed to start with exception:\n{}".format(traceback.format_exc(10)),
      isError=True,
      type="LoopEnergy Script")


Save this to a python file and run it in a Startup trigger. Untested of course since I can't test the library, but it should be close.

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Fri Feb 23, 2018 7:19 am
by Suncroft
Jay, your script works great and now gives me a constant Energy reading that I can now graph and use to trigger other actions. Thanks for great support from a great product.
Also thank you to everyone else who provided support on this thread,

Thanks

Stephen

Re: Python code working outside of Indigo but not as Embedde

PostPosted: Fri Feb 23, 2018 7:24 am
by DaveL17
Glad to hear that you’ve got a working script. That was a tricky one.


Sent from my iPhone using Tapatalk