Dear Anygate,
There are a few ways the script may be slow:
1) time.sleep()
if the script needs to wait for some action, this may take a long time, and prevent other scripts from running.
Example:
Current = scada.getValue(‘battery.current’) # The current right now is 50A
currentLimit = 20A
scada.setValue(‘battery.currentLimit’, currentLimit)
# wait 10 seconds for the inverter to adjust the current
time.sleep(10)
newCurrent = scada.getValue(‘battery.current’)
if newCurrent > currentLimit:
scada.setValue(‘battery.alarm’, True)
# This script is a very simple method to make sure that an applied setting is followed after some reasonably short delay, but due to the time.sleep() call, stops all other scripts from running.
Anything that relies on time differences between actions, or otherwise needs to take time into account becomes significantly harder, more complicated, and less reliable due to this. For example, simply creating LED blink codes becomes a hard problem to solve because we cannot simply run:
# Try to blink LED 3 times fast, 3 times slow.
for i in range(3):
remote.setValue(‘LED.onOff’, 1)
time.sleep(0.25)
remote.setValue(‘LED.onOff’, 0
time.sleep(0.25)
for i in range(3):
remote.setValue(‘LED.onOff’, 1)
time.sleep(1)
remote.setValue(‘LED.onOff’, 0)
time.sleep(1)
# This script will take 9 seconds to run, blocking everything else just to blink an LED.
This can probably be done using trigger controls and multiple scada points, but that is much less flexible and more complicated than a simple script like this.
2) Remote.setValue with device timeout
If my system has many inverters, and I need to write a command to all of them, but there is a network issue, when I call remote.setValue() on each inverter, we have to wait for the timeout (set in DataExplorer) before this script will continue, which blocks other scripts from running:
For example
Npcs = scada.getValue(‘System.Npcs’) # This is 12, each with a modbus timeout of 2 seconds
for i in range(Npcs):
scada.setValue(f’PCS-{i+1}.power’, 0’)
# This script will take 24 seconds to run while it waits for the modbus communication timeout for each PCS. This stops all other scripts, for example, battery voltage checking while we wait for the PCS modbus.
3) Process a large amount of data from trendGroup
By nature of the amount of data stored in trend groups, scripts that analyze the data from trendGroups can take a long time to run.
trendGroup1 stores the power and current from all 12 inverters, stored once every 250ms.
Every 5 minutes, I want to do calculations on this data. Simply loading this data may take 4-8 seconds.
If I want to integrate this data for the whole day to get, for example, the total charge energy and total discharge energy, I have to check the timestamps and values of power individually to check when it was negative, when it was positive, and verify the data saving timesteps. Looping through all this data may take another 2-4 seconds for each of the 12 inverters. This script takes a long time to run sometimes over one minute, blocking other python scripts from running.
4) Cannot have a script which runs continuously.
Since each script must run and complete, then start from the beginning the next time Power Scene runs it, scripts cannot maintain their state or context.
? This creates significant overhead in performance because scripts must re-initialize for each run, reloading all their scada points and imports each time.
? Scripts must be more complicated because scripts need extensive code to be added to account for saving state information to files or scada points, then loading them again at the beginning of the script, which introduces more chances for bugs, and results in scada point clutter for things that really should just be variables in scripts.
? It limits the ability for scripts to handle real-time events effectively, for example, this makes it much more complicated to write a simple CCCV charge control algorithm because it relies on previous data and present data.
I hope these examples make sense.
Thank you,
RPE |