0% found this document useful (0 votes)
32 views41 pages

05 EcoSUI - Python Scripting - Rev0

The EcoSUI Scripting Engine allows for flexible modifications and additions to the system using Python scripts, which can be integrated with the .NET Framework via Iron Python. Users can implement various functionalities such as automation, reporting, and data acquisition, but must be cautious as scripts can access all system and network resources. The document also provides an overview of Python syntax, data types, operators, and special functions relevant to EcoSUI scripting.

Uploaded by

lukinhass22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
32 views41 pages

05 EcoSUI - Python Scripting - Rev0

The EcoSUI Scripting Engine allows for flexible modifications and additions to the system using Python scripts, which can be integrated with the .NET Framework via Iron Python. Users can implement various functionalities such as automation, reporting, and data acquisition, but must be cautious as scripts can access all system and network resources. The document also provides an overview of Python syntax, data types, operators, and special functions relevant to EcoSUI scripting.

Uploaded by

lukinhass22
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 41

EcoSUI

Python Scripting

F. Birke - Schneider Electric - 2015


EcoSUI – Scripting Engine – Why ?

Benefits of a scripting engine :

“The compiled part of the system is optimized for speed of execution, but
is harder to modify (because it must be compiled and reloaded), whereas
the scripted part of the system is optimized for flexibility, it will run slower
but can be quickly and easily modified by anyone with a text editor.”

In EcoSUI, Scripting Engine lets you add


- Slow Automatisms
- Reporting Facilities
- Additional Slow Acquisition
- Additional Slow Scada Interface
-…

Schneider Electric 2
EcoSUI – Scripting Engine – How ?

EcoSUI is developed with .NET Framework. Iron Python is an open-source


implementation of the Python programming language which is tightly
integrated with .NET Framework

An additional package ‘IronPython-2.7.3.msi’ must be installed

Schneider Electric 3
EcoSUI – Scripting Engine – Where ?

Python Scripts can be used in

a- HMI, using action ‘EXECUTESCRIPT “PathToScript”’ (Script


is executed asynchronously. There is no return value)

b- SBUS Server, ‘Scripts’ Tab

c- In Response to a xPC from a Virtual Ring (DefaultActions.py)

Schneider Electric 4
EcoSUI – Scripting Engine – !! WARNING !!

Python Scripts are very powerful and therefore dangerous if used in an
inappropriate way.

- Scripts are not compiled and can be changed by anyone using a


Text Editor
- Scripts have access to all EcoSUI datapoints (xPS, xPC , MV)

- Scripts have access to all computer ressources

- Scripts have access to all network ressources

=> If you don’t need Python scripts, do not install Python

Schneider Electric 5
EcoSUI – Python Overview

Python source code is located in .py files



Python source code can be edited by any Text Editor (ie. Notepad++)

Schneider Electric 6
EcoSUI – Python Overview

!! WHITE SPACE MATTERS !!



YOUR CODE WILL NOT RUN CORRECTLY IF YOU USE IMPROPER
INDENTATION.
DON’T MIX WHITESPACE AND TABS FOR INDENTATION

Python is Case-Sensitive

Use # for Comments


Use ; for Multiple Statements on a Single Line

Integer, Float, Boolean,Complex Number, String, List, Dictionary, Tuple,


File, Set

Python is not strongly typed

Python does not require declaration of variables before their use

Schneider Electric 7
EcoSUI – Python Overview – Variables 1/3

BOOLEAN (bool)

•True
•False

NUMBERS
•Decimal integer and Lonf integer: 1234, 1234567890546378940L (or l)
•Binary integer: 0b10, 0B10, 0b10101010101010101010101010101010L (begins with a 0b or 0B)
•Octal integer: 0177, 0o177, 0O177, 0177777777777777777L (begins with a 0 , 0o, or 0O)
•Hex integer: 0xFF, 0XFFFFffffFFFFFFFFFFL (begins with 0x or 0X)
•Float (double precision): 3.14e-10, .001, 10., 1E3
•Complex: 1J, 2+3J, 4+5j (ends with J or j, + separates (float) real and imaginary parts)

Schneider Electric 8
EcoSUI – Python Overview – Variables 2/3

SEQUENCES
•Strings
'', '1', "12", 'hello\n'
•Tuples (type tuple) of length 0, 1, 2, etc: (cannot be changed after initialization ‘=immutable’)
() (1,) (1,2) # parentheses are optional if len > 0
•Lists (type list) of length 0, 1, 2, etc:
[] [1] [1,2]

Indexing is 0-based. Negative indices (usually) mean count backwards from end of sequence.
Sequence slicing [starting-at-index : but-less-than-index [ : step]]. Start defaults to 0, end to
len(sequence), step to 1. a = (0,1,2,3,4,5,6,7)
a[3] == 3
a[-1] == 7
a[2:4] == (2, 3)
a[1:] == (1, 2, 3, 4, 5, 6, 7)
a[:3] == (0, 1, 2)
a[:] == (0,1,2,3,4,5,6,7) # makes a copy of the sequence.
a[::2] == (0, 2, 4, 6) # Only even numbers.
a[::-1] = (7, 6, 5, 4, 3 , 2, 1, 0) # Reverse order.

Schneider Electric 9
EcoSUI – Python Overview – Variables 3/3

Dictionary
•dict = {'Name': 'Zara', 'Age': 7, 'Class': 'First'};

print "dict['Name']: ", dict['Name']; # Gives « dict['Name']: Zara »


print "dict['Age']: ", dict['Age']; # Gives « dict['Age']: 7 »

Schneider Electric 10
EcoSUI – Python Overview – Basic Operators

Operator Description Example
+ Addition Adds values on either side of the operator. a + b = 30
- Subtraction Subtracts right hand operand from left hand operand. a – b = -10

* Multiplication Multiplies values on either side of the operator a * b = 200

/ Division Divides left hand operand by right hand operand b/a=2

% Modulus Divides left hand operand by right hand operand and returns b%a=0
remainder
** Exponent Performs exponential (power) calculation on operators a**b =10 to the power 20

// Floor Division - The division of operands where the result is 9//2 = 4 and 9.0//2.0 = 4.0
the quotient in which the digits after the decimal point are
removed.

Schneider Electric 11
EcoSUI – Python Overview - Comparisons

Operator Description Example
== If the values of two operands are equal, then the condition becomes true. (a == b) is not true.

!= If values of two operands are not equal, then condition becomes true.
<> If values of two operands are not equal, then condition becomes true. (a <> b) is true. This is
similar to != operator.

> If the value of left operand is greater than the value of right operand, then (a > b) is not true.
condition becomes true.

< If the value of left operand is less than the value of right operand, then (a < b) is true.
condition becomes true.
>= If the value of left operand is greater than or equal to the value of right (a >= b) is not true.
operand, then condition becomes true.

<= If the value of left operand is less than or equal to the value of right (a <= b) is true.
operand, then condition becomes true.

Schneider Electric 12
EcoSUI – Python Overview - Assignment
Operator Description Example
= Assigns values from right side operands to left c = a + b assigns value of a + b into c

side operand
+= Add It adds right operand to the left operand and c += a is equivalent to c = c + a
assign the result to left operand

-= Subtract It subtracts right operand from the left operand c -= a is equivalent to c = c - a


and assign the result to left operand

*= Multiply It multiplies right operand with the left operand c *= a is equivalent to c = c * a


and assign the result to left operand

/= Divide It divides left operand with the right operand and c /= a is equivalent to c = c / ac /= a is
assign the result to left operand equivalent to c = c / a

%= Modulus It takes modulus using two operands and assign c %= a is equivalent to c = c % a


the result to left operand

**= Exponent Performs exponential (power) calculation on c **= a is equivalent to c = c ** a


operators and assign value to the left operand

//= Floor It performs floor division on operators and assign c //= a is equivalent to c = c // a
Division value to the left operand

Schneider Electric 13
EcoSUI – Python Overview – Bitwise Operators
With a=0011 1100 and b=0000 1101 ’

Operator Description Example

& Binary AND Operator copies a bit to the result if it exists in (a & b) (means 0000 1100)
both operands

| Binary OR It copies a bit if it exists in either operand. (a | b) = 61 (means 0011 1101)

^ Binary XOR It copies the bit if it is set in one operand but not (a ^ b) = 49 (means 0011 0001)
both.

~ Binary Ones It is unary and has the effect of 'flipping' bits. (~a ) = -61 (means 1100 0011 in 2's
Complement complement form due to a signed binary
number.

<< Binary Left The left operands value is moved left by the a << = 240 (means 1111 0000)
Shift number of bits specified by the right operand.

>> Binary Right The left operands value is moved right by the a >> = 15 (means 0000 1111)
Shift number of bits specified by the right operand.

Schneider Electric 14
EcoSUI – Python Overview – IF…ELIF…ELSE
Syntax: ’
if expression1:
statement(s)
elif expression2:
statement(s)
elif expression3:
statement(s)
else:
statement(s)

Ex:
if n == 0:
print("None")
elif n < 0:
print("Low")
else: # Handle values greater than zero.
if n > 100:
print("Out of range")
else:
print("High“)

Schneider Electric 15
EcoSUI – Python Overview – Loops

Syntax:

for iterating_var in sequence:


statements(s)

Ex:

fruits = ['banana', 'apple', 'mango']


for fruit in fruits:
print 'Current fruit :', fruit

Schneider Electric 16
EcoSUI – Python Overview – Loops

Syntax:

while expression:
statement(s)

Ex:

while (count < 9):


print 'The count is:', count
count = count + 1

Schneider Electric 17
EcoSUI – Script – Add a new script in SBUSServer

Edit C:\MCIS\Scripts\[ComputerName]\Scripts_SBUSServer.xml

<?xml version="1.0" encoding="utf-8"?>


<Scripts>
<Script filename="c:\mcis\scripts\scriptonchange.py" enabled="1" when="0" description="" />
<Script filename="c:\mcis\scripts\scriptcyclic.py" enabled="1" when="0" description="" />
<Script filename="c:\mcis\scripts\scriptgetmvarchives.py" enabled="0" when="0" description="" />
</Scripts>

Schneider Electric 18
EcoSUI – Special Python Functions

Logging Functions

Log message in DbgView and SBUS Server Scripts Tab

MCISLog(string message)

Ex:
MCISLog("Script Startup")

REMARK : Don’t forget to enable Script logs in DbgView (see


c:\Mcis\Debug\Debug.ini [Script] Log=1)

Schneider Electric 19
EcoSUI – Special Python Functions

EcoSUI Qualities (based on IEC61850)

0 – Valid
1 – Disconnected
2 – Invalid
3 – Forced
4 – Questionable
5 – Overflow
6 – OutOfRange
7 – BadReference
8 – Oscillatory
9 – Failure
10 – OldData
11 – Inconsistent
12 – Inaccurate
13 – Substituted
14 – Test
15 – Operator Blocked

Schneider Electric 20
EcoSUI – Special Python Functions

Variable Status Functions

Get the Current Value of a Datapoint

Res=MCISGetValue(string mnemonic)

Res[0] -> boolean, datapoint found


Res[1] -> double, value of datapoint
Res[2] -> integer, quality of datapoint
Res[3] -> datetime, last update of datapoint

Ex:
Res = MCISGetValue("SUBSTATION / VL / BAY / Q0 / CB POSITION")
MCISLog("Value=" + str( int( Res[1] ) ) + ", Quality=" +
str(Res[2]) + ", Found=" + str(Res[0]) ))

Schneider Electric 21
EcoSUI – Special Python Functions

Variable Attributes Functions
Get Attribute of a Datapoint (See Attributes in signalList)

Res=MCISGetAttribute(string mnemonic, int attributeIdx)

Res -> string, attribute of datapoint

Ex:
Res = MCISGetAttribute("SUBSTATION / VL / BAY / Q0 / CB POSITION",5)
MCISLog("Attribute 5 =" + Res)

Schneider Electric 22
EcoSUI – Special Python Functions

Variable Acquisition Functions 1/2
Set Value of a Datapoint

MCISSetValue(mnemonic, double value, int quality)

Ex:
MCISSetValue("SUBSTATION / VL / BAY / VOLTAGE",110,0)

Schneider Electric 23
EcoSUI – Special Python Functions

Variable Acquisition Functions 2/2

Force Quality of a Datapoint

MCISForceQuality(string mnemonic, int quality)

Ex:
MCISForceQuality("SUBSTATION / VL / BAY / CURRENT",5)

Unforce Quality of a Datapoint

MCISUnforceQuality(string mnemonic)

Ex:
MCISUnforceQuality("SUBSTATION / VL / BAY / CURRENT")

Schneider Electric 24
EcoSUI – Special Python Functions

Command Functions 1/2

Send Select Command

MCISSendSelectCommand(string mnemonic, bool value)

Ex:
MCISSendSelectCommand("SUBSTATION / VL / BAY / Q0 /
CONTROL",true)

Send Execute Command

MCISSendDECommand(string mnemonic, bool value)

Ex:
MCISSendDECommand("SUBSTATION / VL / BAY / Q0 /
CONTROL",true)

Schneider Electric 25
EcoSUI – Special Python Functions

Command Functions 2/2
Send SetPoint

MCISSendSetPoint(string mnemonic, double value)

Ex:
MCISSendSetPoint("SUBSTATION / VL / BAY / TAP",15)

Schneider Electric 26
EcoSUI – Special Python Functions

Command Functions 2/2
Send FreeCommand (Modbus only)

MCISSendFreeCommand(string eqptName, byte typeCmd, int dataAddr, int


uniqueID, byte[] freemCmd)

Schneider Electric 27
EcoSUI – Special Python Functions - Callbacks

MCISContinueAfterExit()
MCISRegisterSignal(mnemonic, callbackFunctionName)
MCISRegisterTime_Cyclically(seconds, callbackFunctionName)
MCISRegisterTime_EveryMinute(second, callbackFunctionName)
MCISRegisterTime_EveryHour(minute,second,callbackFunctionName)
MCISRegisterTime_EveryDay(hour,minute,second,callbackFunctionName)
MCISRegisterTime_EveryWeek(dayOfWeek,hour,minute,second,callbackFuntionName)
MCISRegisterTime_EveryMonth(day,hour,minute,second,callbackFunctionName)

Schneider Electric 28
EcoSUI – Special Python Functions - Callbacks

Callbacks are used when you want EcoSUI to call a function of your
scripts when

- A specific time/date or duration has been reached


- Value of a Datapoint has been updated

To tell EcoSUI when to call back your script, you will use functions to
register datapoint, cycle/duration.

EcoSUI, please call


EcoSUI
EcoSUI Python Execute
myFunction every
Scripting Engine myFunction
minute

Every Minute

Schneider Electric 29
EcoSUI – Special Python Functions – On Change

Ex:
def Main():
MCISLog("Start of ScriptOnChange")
RegisterSignals()
MCISContinueAfterExit(True)# Mandatory when using Registered signals or time.

def RegisterSignals():
MCISLog("Registering Signals")
MCISRegisterSignal("STATION / SEC1 / OUTCOMER1 / CLOSE", "OnEvent" ) # When
"STATION / SEC1 / OUTCOMER1 / CLOSE" is updated, OnEvent function is called
MCISRegisterSignal("STATION / SEC1 / OUTCOMER2 / CLOSE", "OnEvent" ) # When
"STATION / SEC1 / OUTCOMER2 / CLOSE" is updated, OnEvent function is called

def OnEvent(mnemonic):
MCISLog("" + mnemonic + " has been updated")
DoMyWork()

def DoMyWork():
MCISLog("DoMyWork when a signal is updated")

Main()

Schneider Electric 30
EcoSUI – Special Python Functions – On Change
Two different way of coding – Loop or OnChange (Callback) ’

Loop (Unefficient)
import time

while 1:
debarras=MCISGetValue('Débarras Haut / Volet Roulant / Switch')
sejour=MCISGetValue('Séjour / Volet Roulant / Switch')

if (debarras[1]!=sejour[1]) & (debarras[2]==0) & (sejour[2]==0):


if sejour[1]==0:
MCISSendDECommand('Débarras Haut / Volet Roulant / Descendre',1)
else:
MCISSendDECommand('Débarras Haut / Volet Roulant / Monter',1)

time.sleep(30)

Schneider Electric 31
EcoSUI – Special Python Functions – On Change
Two different way of coding – Loop or OnChange (Callback) ’

OnChange using Callback (efficient)


def Main():
MCISLog("Start of ScriptOnChange")
RegisterSignals()
MCISContinueAfterExit(True) # Mandatory when using Registered signals or time.

def RegisterSignals():
MCISLog("Registering Signals")
MCISRegisterSignal('Débarras Haut / Volet Roulant / Switch', "OnEvent" )
MCISRegisterSignal('Séjour / Volet Roulant / Switch', "OnEvent" )

def OnEvent(mnemonic):
MCISLog("" + mnemonic + " has been updated")
debarras=MCISGetValue('Débarras Haut / Volet Roulant / Switch')
sejour=MCISGetValue('Séjour / Volet Roulant / Switch')

if (debarras[1]!=sejour[1]) & (debarras[2]==0) & (sejour[2]==0):


if sejour[1]==0:
MCISSendDECommand('Débarras Haut / Volet Roulant / Descendre',1)
else:
MCISSendDECommand('Débarras Haut / Volet Roulant / Monter',1)

Main()

Schneider Electric 32
EcoSUI – Special Python Functions - Archives
MCISGetMVArchives(mnemonic, startdate, enddate) ’
Ex:
def Main():
MCISLog("Start of MCISGetMVArchives")
res=MCISGetMVArchives("STATION / SEC1 / MEASURE","2015/01/20","2015/01/24")
v=res[0]
t=res[1]
q=res[2]

for i in range(0,len(v)-1):
MCISLog(str(i) + ' v=' + str(v[i]) + ', t=' + str(t[i]) + ', q=' +
str(q[i]))

Main()

Schneider Electric 33
EcoSUI – Interfaces with a DLL 1/2

Use of cdll (from ctypes) to Load Libraries


Ex:
from ctypes import *

def Main():
os.chdir( "C:\\MCIS\\Scripts" )
global TopoDll
TopoDll = cdll.LoadLibrary( "C:\\MCIS\\Scripts\\Topology.dll" )
TopoDll.Topology_StartDebug()
DllVersion = TopoDll.Topology_Init()
if DllVersion == -1:
MCISLog( "Main: INIT TOPOLOGY, *** ERROR: Run time exception in Topology_Init ***" )
else:
MCISLog( "Main: INIT TOPOLOGY, Topology.dll version is %.3f" %(float(DllVersion)/1000 ))
RefreshTopo()
AssignTopoEvents()
MCISLog( "Main: Waiting for values" )
MCISContinueAfterExit(True)
#OnChangeLoop()
return

In that example, TopoDll contains all functions exposed by


Topology.dll

Schneider Electric 34
EcoSUI – Interfaces with a DLL 2/2

Use of create_string_buffer to create a string, byref() to get pointer ’


Ex:
def PopActions():
MCISLog( "PopActions:" )
Ptr = create_string_buffer( 256 )
Value = c_int(0)
while TopoDll.Topology_GetAction( Ptr, byref( Value ) ):
StoreVoltageValue( str(Ptr.value)[1:], Value.value )
return

Schneider Electric 35
EcoSUI – Interface with .NET functions

In py code, you can use any .NET function (Network/WEB, File, ’


Computer, Mathematics, Registry, Windows Forms, …)

Ex:

import clr
clr.AddReference("System.Windows.Forms")

from System.Windows.Forms import Application, Form

class HelloWorldForm(Form):

def __init__(self):
self.Text = 'Hello World'
self.Name = 'Hello World'

form = HelloWorldForm()
Application.Run(form)

Schneider Electric 36
EcoSUI – Virtual Ring

Automatic Feedback

When two signals (xPS/xPC or MV/SetPoint) have same names, there


is an automatic feedback.

-> If we send a command on xPC, associated xPS will get the new
value

-> If we send a setpoint, associated MV will get the new value

Schneider Electric 37
EcoSUI – Virtual Ring

Initial Values

If Ring.ini [InitialValues] LoadInitialValuesFromLastValues is 1,


values are stored in file. At next startup, values are reloaded from
this file

If this virtual ring is redundant, initial values can also be read from
other computer (newest value is read)

Schneider Electric 38
EcoSUI – Virtual Ring

Python Script

Each time a command/setpoint is sent to a datapoint belonging to a


virtual ring, DefaultActions.py is started.

command variable describes the type (command or setpoint)


commandvalue variable gives command value (0 or 1)
setpointvalue variable gives setpoint value

Ex:

if commandtype=='command':
MCISLog('Command '+str(commandvalue)+' on '+mnemonic)
elif commandtype=='setpoint':
MCISLog('SetPoint '+str(setpointvalue)+' on '+mnemonic)

Schneider Electric 39
EcoSUI – Exercises

- Create an operation counter. Each time a command is send to a
virtual DPC, a counter is increased

- Create a keepalive counter. Each minute, a counter is increased

Schneider Electric 40
End of Document

You might also like