Framework Reference¶
Device Object¶
- class PyPlcnextRsc.common.device.ExtraConfigure[source]¶
Additional configure for RscClient
timeout - default is 10s
useTls - default is True
keepAlive_ms - default is 30000ms
- class PyPlcnextRsc.common.device.Device(ip: str, user: Optional[str] = None, passwd: Optional[str] = None, port: int = 41100, config: Optional[PyPlcnextRsc.common.device.ExtraConfigure] = None, secureInfoSupplier: Optional[Callable[[Optional[dict]], Tuple[str, str]]] = None)[source]¶
PLCnext Device Object ,this is the main object for end-user.
In order to get any RSC service , this object must be created and connect (log-in) successfully.
Warning
Always use secureInfoSupplier to supply security information instead of use ‘user’ and ‘passwd’ argument
Usage:
Typical way : using with-block for auto connect and dispose , and use secureInfoSupplier to provide secure login-information.
from PyPlcnextRsc import Device, GUISupplierExample if __name__ == "__main__": with Device('192.168.1.10', secureInfoSupplier=GUISupplierExample) as device: ...
- Parameters
ip (str) – the IP address of the target PLCnext for connecting
user (str) – user name for login if user authentication is enabled. (deprecated ,use secureInfoSupplier instead)
port (int) – socket port of target , default is set to 41100
passwd (str) – passwd for login if user authentication is enabled. (deprecated ,use secureInfoSupplier instead)
config (
ExtraConfigure
) – additional setting for this client , such as switch of TLS and socket time-outsecureInfoSupplier (Callable[[Optional[dict]],Tuple[str,str]]) –
a callback function for getting secure info. the function’s signature can have no or only one argument, if one argument is in signature,then during login period the details about target (such as serial number ,firmware-version) will be passed by the argument
Note
The function will not be called if user-authentication is disabled on target PLCnext
- Raises
#TODO
- PyPlcnextRsc.common.device.GUISupplierExample(detail)[source]¶
A simple GUI for authentication login based on tkinter
Note
This GUI will not be called if user-authentication is disabled.
- PyPlcnextRsc.common.device.ConsoleSupplierExample(detail)[source]¶
A simple console interface for authentication login based on getpass module
Note
This will not be called if user-authentication is disabled.
If is running by PyCharm , the
getpass module
’s behavior is changed, the password will be echoed. This will not happen if you run this directly through python
Type Tags¶
- class PyPlcnextRsc.common.tag_type.RscType(value)[source]¶
Datatypes supported by Rsc.
- Null = 0¶
No data type set
- End = 255¶
End of stream (EOS)
- Void = 1¶
void or null object
- Bool = 2¶
bool type
- Char = 3¶
16 bit character
- Int8 = 4¶
signed 8 bit integer (I1)
- Uint8 = 5¶
unsigned 8 bit integer (U1)
- Int16 = 6¶
signed 16 bit integer (I2)
- Uint16 = 7¶
unsigned 16 bit integer (U2)
- Int32 = 8¶
signed 32 bit integer (I4)
- Uint32 = 9¶
unsigned 32 bit integer (U4)
- Int64 = 10¶
signed 64 bit integer (I8)
- Uint64 = 11¶
unsigned 64 bit integer (U8)
- Real32 = 12¶
32 bit floating point number (R4)
- Real64 = 13¶
64 bit floating point number (R8)
- Struct = 18¶
Complex datatype
- Utf8String = 19¶
Utf-8 string
- String = 14¶
String with undefined format. Deprecated with remoting version 4 used by common.In common context with at least remoting version 4 RscType String is mapped to Utf8String
- Array = 20¶
Array type
- Datetime = 23¶
Datetime
- Version = 24¶
Version
- Guid = 25¶
Universal unique ID
- AnsiString = 26¶
Ansi string, not implemented in common context
- Object = 28¶
Object type handled by common as
RscVariant
- Utf16String = 30¶
Utf-16 string, not implemented in common context
- Stream = 34¶
Stream type to marshal large data packets
- Enumerator = 35¶
Enumerator type
- SecureString = 36¶
String for security context
- Enum = 37¶
Enum type
- Dictionary = 38¶
Dictionary type
- SecurityToken = 39¶
Security token needed for security Services
- Exception = 40¶
Exception
- IecTime = 41¶
IEC type: TIME [int32]
- IecTime64 = 42¶
IEC type: LTIME [int64]
- IecDate = 43¶
IEC type: DATE [N/A]
- IecDate64 = 44¶
IEC type: LDATE [int64]
- IecDateTime = 45¶
IEC type: DATE_AND_TIME, DT [N/A]
- IecDateTime64 = 46¶
IEC type: LDATE_AND_TIME, LDT [int64]
- IecTimeOfDay = 47¶
IEC type: TIME_OF_DAY, TOD [N/A]
- IecTimeOfDay64 = 48¶
IEC type: LTIME_OF_DAY, LTOD [int64]
- class PyPlcnextRsc.common.tag_type.IecType[source]¶
Concrete annotation for IEC61131 data space
this is just a helper map from IEC61131 data type to
RscType
- Null = 0¶
- TIME = 41¶
- LTIME = 42¶
- LDATE = 44¶
- LDATE_AND_TIME = 46¶
Mapped to
PyPlcnextRsc.common.tag_type.RscType.IecDateTime64
- LTIME_OF_DAY = 48¶
Mapped to
PyPlcnextRsc.common.tag_type.RscType.IecTimeOfDay64
- BOOL = 2¶
- STRING = 19¶
- LREAL = 13¶
- REAL = 12¶
- LWORD = 11¶
- DWORD = 9¶
- WORD = 7¶
- BYTE = 5¶
- LINT = 10¶
- DINT = 8¶
- INT = 6¶
- SINT = 4¶
- ULINT = 11¶
- UDINT = 9¶
- UINT = 7¶
- USINT = 5¶
Tools¶
DataTypeStore¶
- PyPlcnextRsc.tools.PlcDataTypeSchema.NewSchemaInstance(schema)[source]¶
Construct a new data type instance defined by schema this instance is used for Write complex data to PLCnext
Note
In the created instance , all values have been set to its’ default value, means that if user don’t change the element (field) in it, it can also send to PLCnext successfully , but all elements (or fields) are 0 , 0.0 , False or “”(empty str)
- Parameters
schema – type schema, get from
PyPlcnextRsc.tools.PlcDataTypeSchema.DataTypeStore.__getitem__()
- Returns
a new data type instance for user to fill elements or fields
- PyPlcnextRsc.tools.PlcDataTypeSchema.ReceiveAsSchemaInstance(schema, variant: PyPlcnextRsc.common.objects.rsc_variant.RscVariant, builderMode: bool = False)[source]¶
Receive the certain value from
RscVariant
as data_type defined in schema- Parameters
schema – type schema
variant (
RscVariant
) – from IDataAccessService or ISubscriptionService or some other service , which represent the meta-value of the data_type defined in schemabuilderMode (bool) – if set true, all the struct received will be the
RscStructBuilder
, so it is possible for user to change the fields’ value and send back to device directly.
- Returns
final value , which has the same element type or fields defined in schema
- class PyPlcnextRsc.tools.PlcDataTypeSchema.DataTypeStore(SIO)[source]¶
This is a helper function for python user to create the equivalent variable model to IEC61131, it is the most convenient way to construct a complex value such as Array and Struct for sending or receiving.
Basic usage:
from PyPlcnextRsc import Device, RscVariant, GUISupplierExample from PyPlcnextRsc.Arp.Plc.Gds.Services import IDataAccessService, WriteItem from PyPlcnextRsc.tools import DataTypeStore if __name__ == "__main__": TypeStore = DataTypeStore.fromString( ''' TYPE DemoStruct : STRUCT Field1 : INT; Field2 : BOOL; END_STRUCT DemoArray : ARRAY[0..10] OF INT; END_TYPE ''') with Device('192.168.1.10', secureInfoSupplier=GUISupplierExample) as device: # create DemoStruct demo1 = TypeStore.NewSchemaInstance("DemoStruct") demo1.Field1 = 123 demo1.Field2 = True # create DemoArray demo2 = TypeStore.NewSchemaInstance("DemoArray") demo2[:] = [i * 2 for i in range(11)] # get raw data access service data_access_service = IDataAccessService(device) # Write demo1 to PLCnext data_access_service.Write((WriteItem("Arp.Plc.Eclr/demo1", RscVariant.of(demo1)),)) # Read demo1 read_item = data_access_service.Read(("Arp.Plc.Eclr/demo1",))[0] rcv_demo1 = TypeStore.ReceiveAsSchemaInstance("DemoStruct", read_item.Value) print(rcv_demo1) # --------------- data_access_service.Write((WriteItem("Arp.Plc.Eclr/demo2", RscVariant.of(demo2)),)) read_item = data_access_service.Read(("Arp.Plc.Eclr/demo2",))[0] rcv_demo2 = TypeStore.ReceiveAsSchemaInstance("DemoArray", read_item.Value) print(rcv_demo2)
- classmethod fromFile(file_or_filename: Union[str, TextIO])[source]¶
Create the DataTypeStore using local file.
- Parameters
file_or_filename (TextIO or str) – file object or the path of the local file.
- classmethod fromString(string: str)[source]¶
Using DataType string to create the DataTypeStore
- Parameters
string (str) – the DataType code.
- __getitem__(item) any [source]¶
Get type schema
- Parameters
item (str) – type named defined in DataTypeStore
- Returns
type schema
- NewSchemaInstance(data_type_name: str)[source]¶
Construct a new data type instance defined by schema this instance is used for Write complex data to PLCnext
Note
In the created instance , all values have been set to its’ default value, means that if user don’t change the element (field) in it, it can also send to PLCnext successfully ,but all elements (or fields) are 0,*0.0*,*False* or “”(empty str)
- Parameters
data_type_name (str) – type named defined in DataTypeStore
- Returns
a new data type instance for user to fill elements or fields
- ReceiveAsSchemaInstance(data_type_name: str, variant: PyPlcnextRsc.common.objects.rsc_variant.RscVariant, builderMode: bool = False)[source]¶
Receive the certain value from PLCnext as data_type defined in schema
- Parameters
data_type_name (str) – type named defined in DataTypeStore
variant (
RscVariant
) – from IDataAccessService or ISubscriptionService or some other service , which represent the meta-value of the data_type defined in schemabuilderMode (bool) – if set true, all the struct received will be the
RscStructBuilder
, so it is possible for user to change the fields’ value and send back to device directly.
- Returns
final value , which has the same element type or fields defined in schema
Data Objects¶
General Object¶
RscVariant¶
- class PyPlcnextRsc.common.objects.rsc_variant.RscVariant(value, rscType: PyPlcnextRsc.common.tag_type.RscType)[source]¶
This is used to represent an data-object (py-value with its’ RscType)
Create a RscVariant object by providing both the definite
RscType
and python value- Parameters
- classmethod of(value)[source]¶
Create RscVariant from some special python object that
RscType
is clearly to tell fromWarning
This is not suitable for some value that is ambiguous , for example you give number 100 use this method, but for this method it is not possible to know which INT (or in other word, which
RscType
)you are talking about: it shell bePyPlcnextRsc.common.tag_type.RscType.Uint8
?PyPlcnextRsc.common.tag_type.RscType.Int16
? orPyPlcnextRsc.common.tag_type.RscType.Int64
…?So in this case, you must use
__init__()
to give theRscType
explicitly.bool value : the
PyPlcnextRsc.common.tag_type.RscType.Bool
will be filledstr value : the
PyPlcnextRsc.common.tag_type.RscType.Utf8String
will be filledRscTuple
orRscList
: thePyPlcnextRsc.common.tag_type.RscType.Array
will be filledRscStructMeta
orRscStructBuilder
:thePyPlcnextRsc.common.tag_type.RscType.Struct
will be filled
- Returns
RscVariant instance
- GetValue() any [source]¶
Get the python value in this RscVariant object.
- Returns
any python value that represent the corresponding value from PLC
Note
Special case of
RscType
PyPlcnextRsc.common.tag_type.RscType.Array
: the value type might beRscList
PyPlcnextRsc.common.tag_type.RscType.Struct
: the value type might beRscStructMeta
- GetType() PyPlcnextRsc.common.tag_type.RscType [source]¶
Get the
RscType
corresponding to the contained value.- Return type
RscStream¶
- class PyPlcnextRsc.common.objects.rsc_stream.RscStream(bytesBuffer)[source]¶
This is used to represent a stream object
Normally used to transfer files with device
- classmethod ofFile(filePath: str)[source]¶
create a RscStream from local file directly
- Parameters
filePath (str) – file path of the local file
- classmethod ofData(data: Union[str, bytes, bytearray])[source]¶
create a RscStream from data directly
- Parameters
data (str,bytes,bytearray) – data to be wrapped in stream object
- getBufferIO() _io.BytesIO [source]¶
get the inner IO reference
- Returns
bytesIO in this stream
- Return type
BytesIO
Struct¶
- class PyPlcnextRsc.common.objects.rsc_struct.RscStructBuilder(prototype, defaults=None)[source]¶
This is a wrapper around RscStruct , supporting filling fields step by step
Normally this is auto created by
PyPlcnextRsc.tools.PlcDataTypeSchema
Note
This class has overload the __eq__ method , so this builder instance is compareable to RscStruct
Tip
Since V0.1.4 :
‘_friendlyMode’:
A syntactic sugar for Array (as a field in Struct) operation has been added ‘Struct.ArrField = [100, 200, 300]’ in now allowed (the old way is ‘Struct.ArrField[:] = [100, 200, 300]’).
Usage:
class ST_Prototype(RscStruct): F0: IecAnnotation.INT F1: IecAnnotation.INT F2: IecAnnotation.BOOL # Not possible to init fields' value separately: # st = ST_Prototype() # st.F0 = 0 # st.F1 = 100 # Illegal ! , because 'RscStruct' is tuple in fact # st.F2 = False # You can only instance it by the following way: # st = ST_Prototype(0,100,False) # use RscStructBuilder: builder = RscStructBuilder(ST_Prototype) builder(F0 = 0,F1 = 100,F2 = False) # by __call__ builder.F1 = 200 # by set attribute builder.F2 = True # not necessary for user to call _getRscStruct because it will auto invoke while sending to PLC st = builder._getRscStruct()
- Parameters
prototype (
RscStruct
) – RscStruct prototypedefaults (dict) – dict with field name and it’s default value if supplied, default it None.
- class PyPlcnextRsc.common.objects.rsc_struct.RscStructMeta(iterable=(), /)[source]¶
Meta-data to represent Struct for transferring with device, it carriers all necessary information of each fields such as
RscType
Should always used as a value in
RscVariant
, and every element are alwaysRscVariant
too- classmethod fromInstance(struct_instance)[source]¶
Create RscStructMeta from a
RscStruct
instance orRscStructBuilder
- Parameters
struct_instance (
RscStruct
instance orRscStructBuilder
) – struct instance, which can be an instance ofRscStruct
directly orRscStructBuilder
- PyPlcnextRsc.common.objects.rsc_struct.RscStruct¶
alias of
NamedTuple
Array¶
- class PyPlcnextRsc.common.objects.rsc_sequence.RscSequence[source]¶
Bases:
object
COMMON ABSTRACT CLASS FOR
RscList
&RscTuple
ALSO USED IN USER STRUCT DEF
- setElementRscType(rscType: PyPlcnextRsc.common.tag_type.RscType)[source]¶
Configure the sequence by passing in primitive type (
RscType
)Warning
This method only support primitive types,
If next-dimension is Array, use
setNextDimension()
instead.else if element is Struct, use
setElementAnnotate()
instead.- Parameters
rscType (
RscType
) – the element type- Returns
self
- setElementAnnotate(annotate)[source]¶
Configure by annotate
Used if element type is Primitive type or
RscStruct
- Parameters
annotate –
field type annotation ,
such as ‘RscTpAnnotate[int, Marshal(rscType=RscType.Int16)]’ or defined
RscStruct
- Returns
self
- setNextDimension(nextDimension)[source]¶
Configure by next
RscSequence
orRscList
Warning
Only used for define a multi-dimension array.
- Parameters
nextDimension (
RscSequence
or factory ofRscList
) – next configuredRscSequence
orRscList
- Returns
self
- getElementRscType() PyPlcnextRsc.common.tag_type.RscType [source]¶
Get the
RscType
of the element.
- setElementContext(context)[source]¶
Set the DataTagContext of the element, this is used internally.
- Parameters
context – DataTagContext of the element
- getElementContext()[source]¶
Get the DataTagContext of the element,, this is used internally.
- Returns
DataTagContext
- setDesireLength(length)[source]¶
if the desire length is set, the framework will check the length before sending to device. this will auto set by
PyPlcnextRsc.tools.PlcDataTypeSchema
internally.- Parameters
length (int) – the desired length of this sequence.
- class PyPlcnextRsc.common.objects.rsc_sequence.RscList(iterable=(), /)[source]¶
Bases:
list
,PyPlcnextRsc.common.objects.rsc_sequence.RscSequence
Use List to represent an array for transferring with device.
Tip
Since V0.1.4 :
‘_friendlyMode’ :
if an element is struct type in this array , use this method is quick !
MyArrayOfStruct[1] = {"Field1": 200, "Field2": False} # or (200,False) or [200,False] MyArrayOfStruct[2] = (300, True)
and this can override all above values (this example showed ‘[:]’ you can use other slice which you want such as ‘[0:8]’ ‘[1:-1]’… )
MyArrayOfStruct[:] = [{"Field1": 200, "Field2": False}, (200, True), (300, True)]
- classmethod factory(funcName, *args)[source]¶
Make a RscList factory, this is only a helper function to create
RscList
of same structure.Usage:
middle_layer_factory = RscList.factory('createNextDimension', RscType.Int16, 3) middle1 = middle_layer_factory.create() middle1[0].extend((1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 11)) middle1[1].extend((1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 11)) middle1[2].extend((1, 3, 2, 1, 1, 1, 1, 1, 1, 1, 11)) middle2 = middle_layer_factory.create() middle2[0].extend((2, 1, 0, 1, 1, 1, 1, 1, 1, 1, 11)) middle2[1].extend((2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 11)) middle2[2].extend((2, 3, 2, 1, 1, 1, 1, 1, 1, 1, 11)) outer = RscList((middle1, middle2)).setNextDimension(middle_layer_factory)
- setOffset(offset: int)[source]¶
Set the start offset of this array object , because in IEC61131, an array can be defined with lower bound not equal to 0
Warning
Although lower bound not equal to 0 is acceptable by this method, but still not recommend to use that kind of array definition! because it can be confused. and slice function of python can not work normally if use negative index.
- Parameters
offset (int) – lower bound of the array
- createNextDimension(elementRscType: PyPlcnextRsc.common.tag_type.RscType, count: int, reserve: int = 0, default: Optional[any] = None)[source]¶
Helper function to create next dimension ,only support for primitive python type as next dimension’s element type!
- reserve(reserve: int = 0, default: Optional[any] = None, use_deepcopy: bool = False)[source]¶
Use the provided value(default) to fill the array
- Parameters
reserve (int) – element count to reserve
default – the value to fill
use_deepcopy (bool) – true if use deepcopy to fill the element,default is False
- setElementRscType(rscType: PyPlcnextRsc.common.tag_type.RscType, reserve: int = 0, default: Optional[any] = None)[source]¶
Overload the
setElementRscType()
, add thereserve()
method.- Parameters
rscType (
RscType
) – the element typereserve (int) – element count to reserve
default – the value to fill
- setElementAnnotate(annotate, reserve: int = 0, default: Optional[any] = None)[source]¶
Overload the
setElementAnnotate()
, add thereserve()
method.- Parameters
annotate –
field type annotation ,
such as ‘RscTpAnnotate[int, Marshal(rscType=RscType.Int16)]’ or defined
RscStruct
reserve (int) – element count to reserve
default – the value to fill
- setNextDimension(nextDimension, count: Optional[int] = None)[source]¶
Overload the
setNextDimension()
, add support for reserve.- Parameters
nextDimension (
RscSequence
or factory ofRscList
) – next configuredRscSequence
orRscList
count (int) – element count to reserve
- Returns
self
- class PyPlcnextRsc.common.objects.rsc_sequence.RscTuple(iterable=(), /)[source]¶
Bases:
tuple
,PyPlcnextRsc.common.objects.rsc_sequence.RscSequence
Use Tuple to represent an array for transferring with device
- setOffset(offset)[source]¶
see doc from
PyPlcnextRsc.common.objects.rsc_sequence.RscList.setOffset()