plcopen/Additional_Function_Blocks.xml
author Andrey Skvortsov <andrej.skvortzov@gmail.com>
Fri, 10 Aug 2018 17:45:33 +0300
changeset 2278 a3ac46366b86
parent 1410 0d34b69cc9b5
permissions -rw-r--r--
Dirty fix for error '_object_has_no_attribute_'getSlave' in EtherCAT extension

traceback:
File "/home/developer/WorkData/PLC/beremiz/beremiz/IDEFrame.py", line 1433, in OnPouSelectedChanged
window.RefreshView()
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/ConfigEditor.py", line 837, in RefreshView
self.RefreshProcessVariables()
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/ConfigEditor.py", line 886, in RefreshProcessVariables
slaves = self.Controler.GetSlaves(**self.CurrentNodesFilter)
File "/home/developer/WorkData/PLC/beremiz/beremiz/etherlab/EthercatMaster.py", line 341, in GetSlaves
for slave in self.Config.getConfig().getSlave():
<type 'exceptions.AttributeError'>:_'lxml.etree._Element'_object_has_no_attribute_'getSlave'

Steps to reproduce problem:

- Add new EtherCAT master
- Add new EthercatNode to the master
- double click on


this is looks like dirty hack to fix strange problem with initial[0]
changing its type after returning from _init_ method to lxml.etree._Element
As a result all methods generated by class factory are lost.

For example, in function initMethod initial[0].__class__ points to
xmlclass.xmlclass.Config. After map(self.append, initial)
self.Config.__class__ is 'xmlclass.xmlclass.Config' as well.
But after returning from initMethod (_init) in CreateElement
self.Config.__class__ has changed to lxml.etree._Element.


I've noticed similar behavior if copy/deepcopy is used for any child
of etree.ElementBase. See simple example below.
[-------------------------------------------------------------]
#!/usr/bin/python

from __future__ import print_function
from lxml import etree
import copy

class DefaultElementClass(etree.ElementBase):
def getLocalTag(self):
return etree.QName(self.tag).localname


def printInformation(x):
print(x, x.__class__, "getLocalTag" in dir(x))


a = DefaultElementClass()
printInformation(a)

#
printInformation(copy.copy(a))
printInformation(copy.deepcopy(a))
[-------------------------------------------------------------]
<?xml version='1.0' encoding='utf-8'?>
<project xmlns:ns1="http://www.plcopen.org/xml/tc6_0201" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://www.plcopen.org/xml/tc6_0201">
  <fileHeader companyName="Beremiz" productName="Additional Function Blocks Library" productVersion="1.0" creationDateTime="2013-09-09T09:56:11"/>
  <contentHeader name="Standard Funtion Blocks" author="Laurent Bessard" modificationDateTime="2013-09-10T22:45:31">
    <coordinateInfo>
      <fbd>
        <scaling x="0" y="0"/>
      </fbd>
      <ld>
        <scaling x="0" y="0"/>
      </ld>
      <sfc>
        <scaling x="0" y="0"/>
      </sfc>
    </coordinateInfo>
  </contentHeader>
  <types>
    <dataTypes/>
    <pous>
      <pou name="RTC" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="IN">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[0 - current time, 1 - load time from PDT]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="PDT">
              <type>
                <DT/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Preset datetime]]></xhtml:p>
              </documentation>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="Q">
              <type>
                <BOOL/>
              </type>
              <initialValue>
                <simpleValue value="FALSE"/>
              </initialValue>
              <documentation>
                <xhtml:p><![CDATA[Copy of IN]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="CDT">
              <type>
                <DT/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Datetime, current or relative to PDT]]></xhtml:p>
              </documentation>
            </variable>
          </outputVars>
          <localVars>
            <variable name="PREV_IN">
              <type>
                <BOOL/>
              </type>
              <initialValue>
                <simpleValue value="FALSE"/>
              </initialValue>
            </variable>
            <variable name="OFFSET">
              <type>
                <TIME/>
              </type>
            </variable>
            <variable name="CURRENT_TIME">
              <type>
                <DT/>
              </type>
            </variable>
          </localVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[{__SET_VAR(data__->,CURRENT_TIME,,__CURRENT_TIME)}

 IF IN
 THEN
   IF NOT PREV_IN
   THEN
       OFFSET := PDT - CURRENT_TIME;
   END_IF;

   (* PDT + time since PDT was loaded *)
   CDT := CURRENT_TIME + OFFSET;
 ELSE
   CDT := CURRENT_TIME;
 END_IF;

 Q := IN;
 PREV_IN := IN;
]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The real time clock has many uses including time stamping, setting dates and times of day in batch reports, in alarm messages and so on.]]></xhtml:p>
        </documentation>
      </pou>
      <pou name="INTEGRAL" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="RUN">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[1 = integrate, 0 = hold]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="R1">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Overriding reset]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="XIN">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Input variable]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="X0">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Initial value]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="CYCLE">
              <type>
                <TIME/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Sampling period]]></xhtml:p>
              </documentation>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="Q">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[NOT R1]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="XOUT">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Integrated output]]></xhtml:p>
              </documentation>
            </variable>
          </outputVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[Q := NOT R1 ;
IF R1 THEN XOUT := X0;
ELSIF RUN THEN XOUT := XOUT + XIN * TIME_TO_REAL(CYCLE);
END_IF;]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The integral function block integrates the value of input XIN over time.]]></xhtml:p>
        </documentation>
      </pou>
      <pou name="DERIVATIVE" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="RUN">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[0 = reset]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="XIN">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Input to be differentiated]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="CYCLE">
              <type>
                <TIME/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Sampling period]]></xhtml:p>
              </documentation>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="XOUT">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Differentiated output]]></xhtml:p>
              </documentation>
            </variable>
          </outputVars>
          <localVars>
            <variable name="X1">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="X2">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="X3">
              <type>
                <REAL/>
              </type>
            </variable>
          </localVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[IF RUN THEN
  XOUT := (3.0 * (XIN - X3) + X1 - X2)
          / (10.0 * TIME_TO_REAL(CYCLE));
  X3 := X2;
  X2 := X1;
  X1 := XIN;
ELSE 
  XOUT := 0.0;
  X1 := XIN;
  X2 := XIN;
  X3 := XIN;
END_IF;]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The derivative function block produces an output XOUT proportional to the rate of change of the input XIN.]]></xhtml:p>
        </documentation>
      </pou>
      <pou name="PID" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="AUTO">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[0 - manual , 1 - automatic]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="PV">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Process variable]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="SP">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Set point]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="X0">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Manual output adjustment - Typically from transfer station]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="KP">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Proportionality constant]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="TR">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Reset time]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="TD">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Derivative time constant]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="CYCLE">
              <type>
                <TIME/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Sampling period]]></xhtml:p>
              </documentation>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="XOUT">
              <type>
                <REAL/>
              </type>
            </variable>
          </outputVars>
          <localVars>
            <variable name="ERROR">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[PV - SP]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="ITERM">
              <type>
                <derived name="INTEGRAL"/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[FB for integral term]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="DTERM">
              <type>
                <derived name="DERIVATIVE"/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[FB for derivative term]]></xhtml:p>
              </documentation>
            </variable>
          </localVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[ERROR := PV - SP ;
(*** Adjust ITERM so that XOUT := X0 when AUTO = 0 ***)
ITERM(RUN := AUTO, R1 := NOT AUTO, XIN := ERROR,
      X0 := TR * (X0 - ERROR), CYCLE := CYCLE);
DTERM(RUN := AUTO, XIN := ERROR, CYCLE := CYCLE);
XOUT := KP * (ERROR + ITERM.XOUT/TR + DTERM.XOUT*TD);]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The PID (proportional, Integral, Derivative) function block provides the classical three term controller for closed loop control.]]></xhtml:p>
        </documentation>
      </pou>
      <pou name="RAMP" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="RUN">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[0 - track X0, 1 - ramp to/track X1]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="X0">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="X1">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="TR">
              <type>
                <TIME/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Ramp duration]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="CYCLE">
              <type>
                <TIME/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Sampling period]]></xhtml:p>
              </documentation>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="BUSY">
              <type>
                <BOOL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[BUSY = 1 during ramping period]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="XOUT">
              <type>
                <REAL/>
              </type>
              <initialValue>
                <simpleValue value="0.0"/>
              </initialValue>
            </variable>
          </outputVars>
          <localVars>
            <variable name="XI">
              <type>
                <REAL/>
              </type>
              <documentation>
                <xhtml:p><![CDATA[Initial value]]></xhtml:p>
              </documentation>
            </variable>
            <variable name="T">
              <type>
                <TIME/>
              </type>
              <initialValue>
                <simpleValue value="T#0s"/>
              </initialValue>
              <documentation>
                <xhtml:p><![CDATA[Elapsed time of ramp]]></xhtml:p>
              </documentation>
            </variable>
          </localVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[BUSY := RUN ;
IF RUN THEN
  IF T >= TR THEN 
    BUSY := 0;
    XOUT := X1;
  ELSE XOUT := XI + (X1-XI) * TIME_TO_REAL(T)
                            / TIME_TO_REAL(TR);
    T := T + CYCLE;
  END_IF;
ELSE
  XOUT := X0;
  XI := X0;
  T := T#0s;
END_IF;]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The RAMP function block is modelled on example given in the standard.]]></xhtml:p>
        </documentation>
      </pou>
      <pou name="HYSTERESIS" pouType="functionBlock">
        <interface>
          <inputVars>
            <variable name="XIN1">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="XIN2">
              <type>
                <REAL/>
              </type>
            </variable>
            <variable name="EPS">
              <type>
                <REAL/>
              </type>
            </variable>
          </inputVars>
          <outputVars>
            <variable name="Q">
              <type>
                <BOOL/>
              </type>
            </variable>
          </outputVars>
        </interface>
        <body>
          <ST>
            <xhtml:p><![CDATA[IF Q THEN
  IF XIN1 < (XIN2 - EPS) THEN 
    Q := 0;
  END_IF;
ELSIF XIN1 > (XIN2 + EPS) THEN
  Q := 1;
END_IF;]]></xhtml:p>
          </ST>
        </body>
        <documentation>
          <xhtml:p><![CDATA[The hysteresis function block provides a hysteresis boolean output driven by the difference of two floating point (REAL) inputs XIN1 and XIN2.]]></xhtml:p>
        </documentation>
      </pou>
    </pous>
  </types>
  <instances>
    <configurations/>
  </instances>
</project>