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.