--- a/Beremiz_service.py Fri Mar 22 11:10:37 2019 +0100
+++ b/Beremiz_service.py Fri Mar 22 13:26:31 2019 +0100
@@ -31,7 +31,6 @@
import getopt
import threading
from threading import Thread, Semaphore, Lock, currentThread
-import __builtin__
from builtins import str as text
from past.builtins import execfile
from six.moves import builtins
--- a/PLCOpenEditor.py Fri Mar 22 11:10:37 2019 +0100
+++ b/PLCOpenEditor.py Fri Mar 22 13:26:31 2019 +0100
@@ -62,7 +62,8 @@
# Define PLCOpenEditor FileMenu extra items id
[
ID_PLCOPENEDITORFILEMENUGENERATE,
-] = [wx.NewId() for _init_coll_FileMenu_Items in range(1)]
+ ID_PLCOPENEDITORFILEMENUGENERATEAS,
+] = [wx.NewId() for _init_coll_FileMenu_Items in range(2)]
beremiz_dir = paths.AbsDir(__file__)
@@ -86,6 +87,8 @@
kind=wx.ITEM_NORMAL, text=_(u'Save As...') + '\tCTRL+SHIFT+S')
AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATE,
kind=wx.ITEM_NORMAL, text=_(u'Generate Program') + '\tCTRL+G')
+ AppendMenu(parent, help='', id=ID_PLCOPENEDITORFILEMENUGENERATEAS,
+ kind=wx.ITEM_NORMAL, text=_(u'Generate Program As...') + '\tCTRL+SHIFT+G')
parent.AppendSeparator()
AppendMenu(parent, help='', id=wx.ID_PAGE_SETUP,
kind=wx.ITEM_NORMAL, text=_(u'Page Setup') + '\tCTRL+ALT+P')
@@ -108,6 +111,8 @@
self.Bind(wx.EVT_MENU, self.OnSaveProjectAsMenu, id=wx.ID_SAVEAS)
self.Bind(wx.EVT_MENU, self.OnGenerateProgramMenu,
id=ID_PLCOPENEDITORFILEMENUGENERATE)
+ self.Bind(wx.EVT_MENU, self.OnGenerateProgramAsMenu,
+ id=ID_PLCOPENEDITORFILEMENUGENERATEAS)
self.Bind(wx.EVT_MENU, self.OnPageSetupMenu, id=wx.ID_PAGE_SETUP)
self.Bind(wx.EVT_MENU, self.OnPreviewMenu, id=wx.ID_PREVIEW)
self.Bind(wx.EVT_MENU, self.OnPrintMenu, id=wx.ID_PRINT)
@@ -118,7 +123,8 @@
(wx.ID_OPEN, "open", _(u'Open'), None),
(wx.ID_SAVE, "save", _(u'Save'), None),
(wx.ID_SAVEAS, "saveas", _(u'Save As...'), None),
- (wx.ID_PRINT, "print", _(u'Print'), None)])
+ (wx.ID_PRINT, "print", _(u'Print'), None),
+ (ID_PLCOPENEDITORFILEMENUGENERATE, "Build", _(u'Generate Program'), None)])
def _init_coll_HelpMenu_Items(self, parent):
AppendMenu(parent, help='', id=wx.ID_HELP,
@@ -232,6 +238,8 @@
self.FileMenu.Enable(wx.ID_SAVEAS, True)
MenuToolBar.EnableTool(wx.ID_SAVEAS, True)
self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, True)
+ MenuToolBar.EnableTool(ID_PLCOPENEDITORFILEMENUGENERATE, True)
+ self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATEAS, True)
else:
self.FileMenu.Enable(wx.ID_CLOSE, False)
self.FileMenu.Enable(wx.ID_PAGE_SETUP, False)
@@ -245,6 +253,8 @@
self.FileMenu.Enable(wx.ID_SAVEAS, False)
MenuToolBar.EnableTool(wx.ID_SAVEAS, False)
self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATE, False)
+ MenuToolBar.EnableTool(ID_PLCOPENEDITORFILEMENUGENERATE, False)
+ self.FileMenu.Enable(ID_PLCOPENEDITORFILEMENUGENERATEAS, False)
def OnNewProjectMenu(self, event):
if self.Controler is not None and not self.CheckSaveBeforeClosing():
@@ -305,27 +315,39 @@
self.SaveProjectAs()
def OnGenerateProgramMenu(self, event):
+ result = self.Controler.GetProgramFilePath()
+ if not result:
+ self.GenerateProgramAs()
+ else:
+ self.GenerateProgram(result)
+
+ def OnGenerateProgramAsMenu(self, event):
+ self.GenerateProgramAs()
+
+ def GenerateProgramAs(self):
dialog = wx.FileDialog(self, _("Choose a file"), os.getcwd(), os.path.basename(self.Controler.GetProgramFilePath()), _("ST files (*.st)|*.st|All files|*.*"), wx.SAVE | wx.CHANGE_DIR)
if dialog.ShowModal() == wx.ID_OK:
- filepath = dialog.GetPath()
- message_text = ""
- header, icon = _("Done"), wx.ICON_INFORMATION
- if os.path.isdir(os.path.dirname(filepath)):
- _program, errors, warnings = self.Controler.GenerateProgram(filepath)
- message_text += "".join([_("warning: %s\n") % warning for warning in warnings])
- if len(errors) > 0:
- message_text += "".join([_("error: %s\n") % error for error in errors])
- message_text += _("Can't generate program to file %s!") % filepath
- header, icon = _("Error"), wx.ICON_ERROR
- else:
- message_text += _("Program was successfully generated!")
+ self.GenerateProgram(dialog.GetPath())
+ dialog.Destroy()
+
+ def GenerateProgram(self, filepath=None):
+ message_text = ""
+ header, icon = _("Done"), wx.ICON_INFORMATION
+ if os.path.isdir(os.path.dirname(filepath)):
+ _program, errors, warnings = self.Controler.GenerateProgram(filepath)
+ message_text += "".join([_("warning: %s\n") % warning for warning in warnings])
+ if len(errors) > 0:
+ message_text += "".join([_("error: %s\n") % error for error in errors])
+ message_text += _("Can't generate program to file %s!") % filepath
+ header, icon = _("Error"), wx.ICON_ERROR
else:
- message_text += _("\"%s\" is not a valid folder!") % os.path.dirname(filepath)
- header, icon = _("Error"), wx.ICON_ERROR
- message = wx.MessageDialog(self, message_text, header, wx.OK | icon)
- message.ShowModal()
- message.Destroy()
- dialog.Destroy()
+ message_text += _("Program was successfully generated!")
+ else:
+ message_text += _("\"%s\" is not a valid folder!") % os.path.dirname(filepath)
+ header, icon = _("Error"), wx.ICON_ERROR
+ message = wx.MessageDialog(self, message_text, header, wx.OK | icon)
+ message.ShowModal()
+ message.Destroy()
def OnPLCOpenEditorMenu(self, event):
wx.MessageBox(_("No documentation available.\nComing soon."))
--- a/README.md Fri Mar 22 11:10:37 2019 +0100
+++ b/README.md Fri Mar 22 13:26:31 2019 +0100
@@ -25,6 +25,9 @@
sudo apt-get install python-nevow python-matplotlib python-lxml python-zeroconf python-cycler
sudo apt-get install python-autobahn python-u-msgpack
+ sudo apt-get install libpython2.7-dev
+ pip2 install --use sslpsk posix_spawn
+
* Prepare
mkdir ~/Beremiz
@@ -66,7 +69,8 @@
cd ~/Beremiz
svn checkout https://svn.code.sf.net/p/bacnet/code/trunk/bacnet-stack/ BACnet
cd BACnet
- make MAKE_DEFINE='-fPIC' all
+ make MAKE_DEFINE='-fPIC' MY_BACNET_DEFINES='-DPRINT_ENABLED=1 -DBACAPP_ALL -DBACFILE -DINTRINSIC_REPORTING -DBACNET_TIME_MASTER -DBACNET_PROPERTY_LISTS=1 -DBACNET_PROTOCOL_REVISION=16' library
+
* Launch Beremiz IDE
--- a/connectors/ConnectorBase.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/ConnectorBase.py Fri Mar 22 13:26:31 2019 +0100
@@ -4,7 +4,7 @@
# See COPYING file for copyrights details.
from __future__ import absolute_import
-import md5
+import hashlib
class ConnectorBase(object):
@@ -12,7 +12,7 @@
chuncksize = 1024*1024
def BlobFromFile(self, filepath, seed):
- s = md5.new()
+ s = hashlib.new('md5')
s.update(seed)
blobID = self.SeedBlob(seed)
with open(filepath, "rb") as f:
--- a/connectors/PYRO/PSK_Adapter.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/PYRO/PSK_Adapter.py Fri Mar 22 13:26:31 2019 +0100
@@ -1,10 +1,40 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+# This file is part of Beremiz, a Integrated Development Environment for
+# programming IEC 61131-3 automates supporting plcopen standard and CanFestival.
+#
+# Copyright (C) 2019: Edouard TISSERANT
+#
+# See COPYING file for copyrights details.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+
+"""
+The TLS-PSK adapter that handles SSL connections instead of regular sockets,
+but using Pre Shared Keys instead of Certificates
+"""
+
from __future__ import absolute_import
from __future__ import print_function
import socket
import re
+import ssl
import sslpsk
-import ssl
import Pyro
from Pyro.core import PyroURI
from Pyro.protocol import _connect_socket, TCPConnection, PYROAdapter
@@ -12,13 +42,13 @@
from Pyro.util import Log
-# The TLS-PSK adapter that handles SSL connections instead of regular sockets,
-# but using Pre Shared Keys instead of Certificates
-#
class PYROPSKAdapter(PYROAdapter):
- # This is essentialy the same as in Pyro/protocol.py
- # only raw_sock wrapping into sock through sslpsk.wrap_socket was added
- # Pyro unfortunately doesn't allow cleaner customization
+ """
+ This is essentialy the same as in Pyro/protocol.py
+ only raw_sock wrapping into sock through sslpsk.wrap_socket was added
+ Pyro unfortunately doesn't allow cleaner customization
+ """
+
def bindToURI(self, URI):
with self.lock: # only 1 thread at a time can bind the URI
try:
@@ -37,7 +67,7 @@
# receive the authentication challenge string, and use that to build the actual identification string.
try:
authChallenge = self.recvAuthChallenge(conn)
- except ProtocolError, x:
+ except ProtocolError as x:
# check if we were denied
if hasattr(x, "partialMsg") and x.partialMsg[:len(self.denyMSG)] == self.denyMSG:
raise ConnectionDeniedError(Pyro.constants.deniedReasons[int(x.partialMsg[-1])])
@@ -70,9 +100,6 @@
return _getProtocolAdapter(protocol)
-Pyro.protocol.getProtocolAdapter = getProtocolAdapter
-
-
_processStringURI = Pyro.core.processStringURI
@@ -91,4 +118,13 @@
return _processStringURI(URI)
-Pyro.core.processStringURI = processStringURI
+def setupPSKAdapter():
+ """
+ Add PyroAdapter to the list of available in
+ Pyro adapters and handle new supported protocols
+
+ This function should be called after
+ reimport of Pyro module to enable PYROS:// again.
+ """
+ Pyro.protocol.getProtocolAdapter = getProtocolAdapter
+ Pyro.core.processStringURI = processStringURI
--- a/connectors/PYRO/__init__.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/PYRO/__init__.py Fri Mar 22 13:26:31 2019 +0100
@@ -37,13 +37,19 @@
from Pyro.errors import PyroError
import PSKManagement as PSK
+import connectors.PYRO.PSK_Adapter
from runtime import PlcStatus
-# this module attribute contains a list of DNS-SD (Zeroconf) service types
-# supported by this connector confnode.
-#
-# for connectors that do not support DNS-SD, this attribute can be omitted
-# or set to an empty list.
+
+def switch_pyro_adapter(use_ssl):
+ """
+ Reloads Pyro module with new settings.
+ This is workaround for Pyro, because it doesn't work with SSL wrapper.
+ """
+ # Pyro.config.PYRO_BROKEN_MSGWAITALL = use_ssl
+ reload(Pyro.protocol)
+ if use_ssl:
+ connectors.PYRO.PSK_Adapter.setupPSKAdapter()
def PYRO_connector_factory(uri, confnodesroot):
@@ -53,8 +59,9 @@
confnodesroot.logger.write(_("PYRO connecting to URI : %s\n") % uri)
scheme, location = uri.split("://")
- if scheme == "PYROS":
- import connectors.PYRO.PSK_Adapter # pylint: disable=wrong-import-order,unused-import,wrong-import-position
+ use_ssl = scheme == "PYROS"
+ switch_pyro_adapter(use_ssl)
+ if use_ssl:
schemename = "PYROLOCPSK"
url, ID = location.split('#') # TODO fix exception when # not found
# load PSK from project
@@ -73,10 +80,10 @@
# Try to get the proxy object
try:
RemotePLCObjectProxy = Pyro.core.getAttrProxyForURI(schemename + "://" + location + "/PLCObject")
- except Exception, e:
+ except Exception as e:
confnodesroot.logger.write_error(
_("Connection to {loc} failed with exception {ex}\n").format(
- loc=location, exo=str(e)))
+ loc=location, ex=str(e)))
return None
RemotePLCObjectProxy.adapter.setTimeout(60)
--- a/connectors/PYRO_dialog.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/PYRO_dialog.py Fri Mar 22 13:26:31 2019 +0100
@@ -6,7 +6,6 @@
from __future__ import absolute_import
from itertools import repeat, islice, chain
-import wx
from connectors.SchemeEditor import SchemeEditor
--- a/connectors/SchemeEditor.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/SchemeEditor.py Fri Mar 22 13:26:31 2019 +0100
@@ -26,7 +26,7 @@
self.txtctrls[tag] = txtctrl
for win, flag in [
(wx.StaticText(self, label=label),
- wx.ALIGN_CENTER_VERTICAL),
+ wx.ALIGN_CENTER_VERTICAL),
(txtctrl, wx.GROW)]:
self.fieldsizer.AddWindow(win, flag=flag)
@@ -39,7 +39,7 @@
self, parent.ctr,
# use a callafter, as editor can be deleted by calling SetURI
partial(wx.CallAfter, parent.SetURI),
- self.txtctrls[tag].SetValue)
+ self.txtctrls["ID"].SetValue)
self.mainsizer.AddWindow(self.idselector)
self.SetSizer(self.mainsizer)
else:
--- a/connectors/__init__.py Fri Mar 22 11:10:37 2019 +0100
+++ b/connectors/__init__.py Fri Mar 22 13:26:31 2019 +0100
@@ -28,9 +28,7 @@
from __future__ import absolute_import
from os import listdir, path
-import util.paths as paths
from connectors.ConnectorBase import ConnectorBase
-from types import ClassType
connectors_packages = ["PYRO", "WAMP"]
@@ -119,8 +117,8 @@
return None
# new class inheriting from generic and specific connector base classes
- return ClassType(_scheme + "_connector",
- (ConnectorBase, connector_specific_class), {})()
+ return type(_scheme + "_connector",
+ (ConnectorBase, connector_specific_class), {})()
def EditorClassFromScheme(scheme):
--- a/controls/IDBrowser.py Fri Mar 22 11:10:37 2019 +0100
+++ b/controls/IDBrowser.py Fri Mar 22 13:26:31 2019 +0100
@@ -98,8 +98,8 @@
args(_("Last URI"), COL_URI, width=300 if big else 80),
args(_("Description"), COL_DESC, width=300 if big else 200,
mode=dv.DATAVIEW_CELL_EDITABLE
- if self.isManager
- else dv.DATAVIEW_CELL_INERT),
+ if self.isManager
+ else dv.DATAVIEW_CELL_INERT),
args(_("Last connection"), COL_LAST, width=120),
]
--- a/runtime/PLCObject.py Fri Mar 22 11:10:37 2019 +0100
+++ b/runtime/PLCObject.py Fri Mar 22 13:26:31 2019 +0100
@@ -28,14 +28,14 @@
import os
import sys
import traceback
+import shutil
from time import time
-import _ctypes # pylint: disable=wrong-import-order
+import hashlib
+from tempfile import mkstemp
+from functools import wraps, partial
from six.moves import xrange
from past.builtins import execfile
-import md5
-from tempfile import mkstemp
-import shutil
-from functools import wraps, partial
+import _ctypes
from runtime.typemapping import TypeTranslator
from runtime.loglevels import LogLevelsDefault, LogLevelsCount
@@ -465,7 +465,7 @@
@RunInMain
def SeedBlob(self, seed):
- blob = (mkstemp(dir=self.tmpdir) + (md5.new(),))
+ blob = (mkstemp(dir=self.tmpdir) + (hashlib.new('md5'),))
_fobj, _path, md5sum = blob
md5sum.update(seed)
newBlobID = md5sum.digest()
@@ -606,7 +606,7 @@
@RunInMain
def GetTraceVariables(self, DebugToken):
- if (DebugToken is not None and DebugToken == self.DebugToken):
+ if DebugToken is not None and DebugToken == self.DebugToken:
return self.PLCStatus, self._TracesSwap()
return PlcStatus.Broken, []
--- a/runtime/Stunnel.py Fri Mar 22 11:10:37 2019 +0100
+++ b/runtime/Stunnel.py Fri Mar 22 13:26:31 2019 +0100
@@ -1,4 +1,5 @@
from __future__ import absolute_import
+from __future__ import print_function
import os
from binascii import b2a_hqx
try:
@@ -11,6 +12,17 @@
_PSKpath = None
+def restartStunnel():
+ """
+ Restart stunnel service using SysV init stript
+ to apply new generated credentials
+ """
+ try:
+ call(restart_stunnel_cmdline)
+ except OSError:
+ print(_("Couldn't restart stunnel service"))
+
+
def PSKgen(ID, PSKpath):
# b2a_hqx output len is 4/3 input len
@@ -20,7 +32,7 @@
PSKstring = ID+":"+secretstring
with open(PSKpath, 'w') as f:
f.write(PSKstring)
- call(restart_stunnel_cmdline)
+ restartStunnel()
def ensurePSK(ID, PSKpath):
--- a/runtime/WampClient.py Fri Mar 22 11:10:37 2019 +0100
+++ b/runtime/WampClient.py Fri Mar 22 13:26:31 2019 +0100
@@ -135,7 +135,7 @@
self.register(GetCallee(name), u'.'.join((ID, name)), registerOptions)
for name in SubscribedEvents:
- self.subscribe(GetCallee(name), unicode(name))
+ self.subscribe(GetCallee(name), text(name))
for func in DoOnJoin:
func(self)
@@ -151,7 +151,7 @@
def publishWithOwnID(self, eventID, value):
ID = self.config.extra["ID"]
- self.publish(unicode(ID+'.'+eventID), value)
+ self.publish(text(ID+'.'+eventID), value)
class ReconnectingWampWebSocketClientFactory(WampWebSocketClientFactory, ReconnectingClientFactory):
@@ -343,12 +343,12 @@
def PublishEvent(eventID, value):
if getWampStatus() == "Attached":
- _WampSession.publish(unicode(eventID), value)
+ _WampSession.publish(text(eventID), value)
def PublishEventWithOwnID(eventID, value):
if getWampStatus() == "Attached":
- _WampSession.publishWithOwnID(unicode(eventID), value)
+ _WampSession.publishWithOwnID(text(eventID), value)
# WEB CONFIGURATION INTERFACE
--- a/runtime/Worker.py Fri Mar 22 11:10:37 2019 +0100
+++ b/runtime/Worker.py Fri Mar 22 13:26:31 2019 +0100
@@ -9,9 +9,9 @@
from __future__ import absolute_import
import sys
-import thread
from threading import Lock, Condition
import six
+from six.moves import _thread
class job(object):
@@ -51,20 +51,27 @@
self.free = Condition(self.mutex)
self.job = None
+ def reraise(self, job):
+ """
+ reraise exception happend in a job
+ @param job: job where original exception happend
+ """
+ exc_type = job.exc_info[0]
+ exc_value = job.exc_info[1]
+ exc_traceback = job.exc_info[2]
+ six.reraise(exc_type, exc_value, exc_traceback)
+
def runloop(self, *args, **kwargs):
"""
meant to be called by worker thread (blocking)
"""
- self._threadID = thread.get_ident()
+ self._threadID = _thread.get_ident()
self.mutex.acquire()
if args or kwargs:
_job = job(*args, **kwargs)
_job.do()
- if _job.success:
- # result is ignored
- pass
- else:
- raise _job.exc_info[0], _job.exc_info[1], _job.exc_info[2]
+ if not _job.success:
+ self.reraise(_job)
while not self._finish:
self.todo.wait()
@@ -86,7 +93,7 @@
_job = job(*args, **kwargs)
- if self._threadID == thread.get_ident():
+ if self._threadID == _thread.get_ident():
# if caller is worker thread execute immediately
_job.do()
else:
@@ -106,10 +113,7 @@
if _job.success:
return _job.result
else:
- exc_type = _job.exc_info[0]
- exc_value = _job.exc_info[1]
- exc_traceback = _job.exc_info[2]
- six.reraise(exc_type, exc_value, exc_traceback)
+ self.reraise(_job)
def quit(self):
"""
--- a/runtime/spawn_subprocess.py Fri Mar 22 11:10:37 2019 +0100
+++ b/runtime/spawn_subprocess.py Fri Mar 22 13:26:31 2019 +0100
@@ -3,6 +3,7 @@
# subset of subprocess built-in module using posix_spawn rather than fork.
+from __future__ import print_function
from __future__ import absolute_import
import os
import signal
--- a/tests/first_steps/plc.xml Fri Mar 22 11:10:37 2019 +0100
+++ b/tests/first_steps/plc.xml Fri Mar 22 13:26:31 2019 +0100
@@ -1,7 +1,7 @@
<?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="Beremiz" productVersion="1" creationDateTime="2016-10-24T18:09:22"/>
- <contentHeader name="First Steps" modificationDateTime="2019-02-13T10:30:06">
+ <contentHeader name="First Steps" modificationDateTime="2018-09-26T12:52:51">
<coordinateInfo>
<fbd>
<scaling x="0" y="0"/>
@@ -676,11 +676,6 @@
<INT/>
</type>
</variable>
- <variable name="R2">
- <type>
- <BOOL/>
- </type>
- </variable>
</localVars>
<externalVars constant="true">
<variable name="ResetCounterValue">
@@ -813,7 +808,7 @@
<relPosition x="85" y="15"/>
</connectionPointOutAction>
</step>
- <actionBlock localId="8" height="63" width="148" executionOrderId="0">
+ <actionBlock localId="8" height="52" width="164" executionOrderId="0">
<position x="154" y="191"/>
<connectionPointIn>
<relPosition x="0" y="15"/>
@@ -830,14 +825,6 @@
</ST>
</inline>
</action>
- <action localId="0" qualifier="S">
- <relPosition x="0" y="0"/>
- <inline>
- <ST>
- <xhtml:p><![CDATA[ R2 := True;]]></xhtml:p>
- </ST>
- </inline>
- </action>
<action localId="0">
<relPosition x="0" y="0"/>
<inline>
@@ -848,18 +835,18 @@
</action>
</actionBlock>
<selectionConvergence localId="10" height="1" width="431">
- <position x="70" y="657"/>
+ <position x="70" y="273"/>
<connectionPointIn>
<relPosition x="0" y="0"/>
<connection refLocalId="13">
- <position x="70" y="657"/>
+ <position x="70" y="273"/>
<position x="70" y="244"/>
</connection>
</connectionPointIn>
<connectionPointIn>
<relPosition x="431" y="0"/>
<connection refLocalId="14">
- <position x="501" y="657"/>
+ <position x="501" y="273"/>
<position x="501" y="250"/>
</connection>
</connectionPointIn>
@@ -868,12 +855,12 @@
</connectionPointOut>
</selectionConvergence>
<jumpStep localId="12" targetName="Start" height="13" width="12">
- <position x="280" y="701"/>
+ <position x="280" y="317"/>
<connectionPointIn>
<relPosition x="6" y="0"/>
<connection refLocalId="10">
- <position x="286" y="701"/>
- <position x="286" y="658"/>
+ <position x="286" y="317"/>
+ <position x="286" y="274"/>
</connection>
</connectionPointIn>
</jumpStep>
@@ -883,7 +870,7 @@
<relPosition x="10" y="0"/>
<connection refLocalId="7">
<position x="70" y="242"/>
- <position x="70" y="221"/>
+ <position x="70" y="215"/>
</connection>
</connectionPointIn>
<connectionPointOut>
@@ -983,11 +970,6 @@
</variable>
</inputVars>
<outputVars>
- <variable name="Reset0">
- <type>
- <BOOL/>
- </type>
- </variable>
<variable name="Out">
<type>
<INT/>
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/tools/Docker/beremiz-requirements/Dockerfile Fri Mar 22 13:26:31 2019 +0100
@@ -0,0 +1,69 @@
+#
+# Dockerfile for Beremiz
+# This container is used to run tests for Beremiz
+#
+# To run test localy use following command executed from beremiz directory:
+# $ docker run --volume=$PWD:/beremiz --workdir="/beremiz" --volume=$PWD/../CanFestival-3:/CanFestival-3 --memory=1g --entrypoint=/beremiz/tests/tools/check_source.sh skvorl/beremiz-requirements
+#
+
+FROM skvorl/python2.7-wxpython
+MAINTAINER Andrey Skvortsov <andrej.skvortzov@gmail.com>
+
+RUN set -xe \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends \
+ python-nevow \
+ python-lxml \
+ python-zeroconf \
+ python-m2crypto \
+ python-autobahn \
+ python-future \
+ python-simplejson \
+ && apt-get install -y --no-install-recommends ca-certificates \
+ && apt-get install -y --no-install-recommends wxglade python-cwiid \
+ && apt-get install -y --no-install-recommends build-essential automake flex bison mercurial python-pip \
+ && apt-get install -y --no-install-recommends \
+ pep8 \
+ pylint \
+ python-pytest \
+ python-pytest-timeout \
+ gettext \
+ python-ddt \
+ libpython2.7-dev \
+ \
+ && apt-get install -y python3-pip \
+ && pip3 install crossbar \
+ \
+ && /usr/bin/pip install gnosis \
+ pyro \
+ sslpsk \
+ posix_spawn \
+ && cd / \
+ && hg clone http://dev.automforge.net/CanFestival-3 \
+ && cd CanFestival-3 \
+ && ./configure \
+ \
+ && cd / \
+ && hg clone -r 24ef30a9bcee1e65b027be2c7f7a8d52c41a7479 https://bitbucket.org/automforge/matiec \
+ && cd matiec \
+ && autoreconf -i \
+ && ./configure \
+ && make \
+ && make install \
+ && mkdir /usr/lib/matiec \
+ && cp -vR lib/* /usr/lib/matiec \
+ && rm -rf /matiec \
+ \
+ && cd / \
+ && hg clone https://bitbucket.org/mjsousa/modbus Modbus \
+ && cd Modbus \
+ && make \
+ \
+ && cd / \
+ && svn checkout https://svn.code.sf.net/p/bacnet/code/trunk/bacnet-stack/ BACnet \
+ && cd BACnet \
+ && make MAKE_DEFINE='-fPIC' all \
+ \
+ && apt-get remove -y bison flex automake python-pip python3-pip libpython2.7-dev \
+ && apt-get autoremove -y \
+ && apt-get clean -y \
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/tools/Docker/python2.7-wxpython/Dockerfile Fri Mar 22 13:26:31 2019 +0100
@@ -0,0 +1,11 @@
+#
+# Dockerfile for wxPython3.0 running on python2.7
+#
+
+FROM python:2.7-stretch
+
+RUN set -xe \
+ && apt-get update \
+ && apt-get install -y --no-install-recommends python-wxgtk3.0 python-matplotlib \
+ && apt-get install -y --no-install-recommends python-xvfbwrapper xvfb \
+ && apt-get clean
--- a/tests/tools/check_source.sh Fri Mar 22 11:10:37 2019 +0100
+++ b/tests/tools/check_source.sh Fri Mar 22 13:26:31 2019 +0100
@@ -66,7 +66,7 @@
# remove compiled Python files
find . -name '*.pyc' -exec rm -f {} \;
- for i in $py_files; do
+ for i in $py3_files; do
# echo $i
python3 -m py_compile $i
if [ $? -ne 0 ]; then
@@ -444,6 +444,8 @@
echo "No files to check"
exit 0;
fi
+
+ py3_files=$(echo $py_files | sed 's/ [[:alnum:]_\-\/.]*pyjslib.py//')
}