|
From: <ma...@us...> - 2011-05-07 19:39:53
|
Revision: 322
http://openautomation.svn.sourceforge.net/openautomation/?rev=322&view=rev
Author: mayerch
Date: 2011-05-07 19:39:44 +0000 (Sat, 07 May 2011)
Log Message:
-----------
* Initial import of the logic server
* Update of the logic editor to use informations provided by the logic server
NOTE:
This is just an import of the current development version. It will NOT run (but it will also not affect the currently available other code of the PyWireGate)
Modified Paths:
--------------
PyWireGate/trunk/logic_editor/backendCommunication.js
PyWireGate/trunk/logic_editor/gle/gle.block.js
PyWireGate/trunk/logic_editor/gle/gle.connection.js
PyWireGate/trunk/logic_editor/logicEditor.js
Added Paths:
-----------
PyWireGate/trunk/logic_editor/LogicEditor.py
PyWireGate/trunk/logic_editor/__init__.py
PyWireGate/trunk/logic_server/
PyWireGate/trunk/logic_server/CodeClass.py
PyWireGate/trunk/logic_server/LogicImportJSON.py
PyWireGate/trunk/logic_server/LogicLibrary.py
PyWireGate/trunk/logic_server/LogicModule.py
PyWireGate/trunk/logic_server/LogicServer.py
PyWireGate/trunk/logic_server/TaskManager.py
PyWireGate/trunk/logic_server/__init__.py
PyWireGate/trunk/logic_server/test.py
PyWireGate/trunk/logik.json
PyWireGate/trunk/logik2.json
Added: PyWireGate/trunk/logic_editor/LogicEditor.py
===================================================================
--- PyWireGate/trunk/logic_editor/LogicEditor.py (rev 0)
+++ PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,147 @@
+#!/usr/bin/env python
+# -*- coding: iso8859-1 -*-
+## -----------------------------------------------------
+## LogicEditor.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+
+from connector import ConnectorServer
+from StringIO import StringIO
+import shutil
+import BaseHTTPServer
+import SimpleHTTPServer
+import SocketServer
+import threading
+
+import re
+
+from logic_server import LogicLibrary
+
+# tmp:
+import time
+
+thisPath = '/'
+
+class logic_editor(ConnectorServer):
+ CONNECTOR_NAME = 'Logic Editor'
+ CONNECTOR_VERSION = 0.1
+ CONNECTOR_LOGNAME = 'logic_editor'
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ global thisPath
+ thisPath = parent.scriptpath + '/logic_editor'
+ else:
+ self.WG = False
+ self.instanceName = instanceName
+ defaultconfig = {
+ 'port' : 8080
+ }
+
+ self.WG.checkconfig(self.instanceName,defaultconfig)
+ config = self.WG.config[self.instanceName]
+ ConnectorServer.__init__(self,("0.0.0.0",config['port']),LERequestHandler )
+ self.start()
+
+
+class LERequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
+ def handle2(self):
+ data = self.request.recv(1024)
+ cur_thread = threading.currentThread()
+ response = "%s: %s: %s" % (self.server.WG.getname(),cur_thread.getName(), data)
+ self.request.send(response)
+
+ def log_message(self, format, *args):
+ self.server.log("%s - %s" %
+ (self.address_string(),
+ format%args))
+
+ def do_GET(self):
+ f = StringIO()
+ contentType="application/json"
+ if self.path.startswith("/config"):
+ contentType="text/plain"
+ f.write('{ \x22v\x22:\x220.0.1\x22, \x22s\x22:\x22SESSION\x22 }\n\n')
+ elif self.path.startswith("/logicLib"):
+ lib = LogicLibrary.LogicLibrary().getLibrary()
+ f.write( '{"MainLib":{' )
+ blockPrefix = ''
+ for blockName in lib:
+ f.write( '%s"%s":{"name":"%s",' % (blockPrefix, blockName, blockName) )
+ block = lib[ blockName ]
+
+ f.write( '"inPorts":[' )
+ prefix = ''
+ for inPort in block.inPorts():
+ f.write( '%s{"name":"%s","type":"signal"}' % (prefix, inPort) )
+ prefix = ','
+ f.write( '],' )
+
+ f.write( '"outPorts":[' )
+ prefix = ''
+ for outPort in block.outPorts():
+ portType = 'UNKNOWN'
+ if outPort[1] in ( 'const', 'signal', 'state' ):
+ portType = 'state'
+ f.write( '%s{"name":"%s","type":"%s"}' % (prefix, outPort[0], portType) )
+ prefix = ','
+ f.write( '],' )
+
+ f.write( '"parameters":[' )
+ prefix = ''
+ for parameter in block.parameters():
+ f.write( '%s{"name":"%s","type":"float","default":0.0}' % (prefix, parameter) )
+ prefix = ','
+ f.write( '],' )
+
+ f.write( '"width":100,"height":50,"rotation":0,"flip":false,"color":[0.0,0.0,0.0],"background":[1.0, 1.0, 1.0]' )
+
+ f.write( '}' )
+ blockPrefix = ','
+ f.write( '}}' )
+ elif self.path.startswith("/logicCode"):
+ contentType="text/plain"
+ self.path = self.path.replace('/logicCode', thisPath + '/..')
+ return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
+ elif self.path.startswith('/live'):
+ self.send_response(200)
+ self.send_header("Content-type", 'text/plain')
+ self.send_header("Access-Control-Allow-Origin", "*")
+ self.end_headers()
+ while True:
+ self.wfile.write( "new line\n" )
+ self.wfile.flush()
+ time.sleep( 1.0 )
+ else:
+ self.path = "%s%s" % ( thisPath, self.path )
+ return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
+
+ length = f.tell()
+ f.seek(0)
+ print "Length: "+str(length)
+ self.send_response(200)
+ self.send_header("Content-type", contentType)
+ self.send_header("Access-Control-Allow-Origin", "*")
+ self.send_header("Content-Length", str(length))
+ self.end_headers()
+ if f:
+ print "send"
+ self.copyfile(f, self.wfile)
+ f.close()
+
+ def copyfile(self, source, outputfile):
+ shutil.copyfileobj(source, outputfile)
+
\ No newline at end of file
Added: PyWireGate/trunk/logic_editor/__init__.py
===================================================================
--- PyWireGate/trunk/logic_editor/__init__.py (rev 0)
+++ PyWireGate/trunk/logic_editor/__init__.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1 @@
+from LogicEditor import logic_editor
\ No newline at end of file
Modified: PyWireGate/trunk/logic_editor/backendCommunication.js
===================================================================
--- PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-07 09:29:04 UTC (rev 321)
+++ PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-07 19:39:44 UTC (rev 322)
@@ -1,5 +1,5 @@
// Sollte das Backend dynamisch aus den verfuegbaren Bloecken generieren:
- var libJSON = {
+ /*var libJSON = {
'sourceLib': {
'source1': {
'width': 100,
@@ -260,7 +260,21 @@
]
}
}
-};
+};*/
-// Die Struktur mit der feritgen Logik
-var logicJSON = {};
+var libJSON = {};
+$.getJSON('/logicLib', function(data) {
+ libJSON = data;
+ drawLibrary();
+});
+
+// The array with all known logics (should be filled on demand later)
+var logics = {};
+$.getJSON('/logicCode/logik.json', function(data) {
+ logics['logik'] = data;
+ updateKnownLogics('logik');
+});
+$.getJSON('/logicCode/logik2.json', function(data) {
+ logics['logik2'] = data;
+ updateKnownLogics('logik2');
+});
Modified: PyWireGate/trunk/logic_editor/gle/gle.block.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-07 09:29:04 UTC (rev 321)
+++ PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-07 19:39:44 UTC (rev 322)
@@ -33,6 +33,7 @@
var outset = 3; // how far should the handle stick out
// setup the private variables
+ var name = type.name || 'UNKNOWN';
var x = type.x || 0;
var y = type.y || 0;
var width = type.width || 100;
@@ -199,6 +200,9 @@
{'dominant-baseline':'middle','text-anchor':'end'} );
});
+ // Draw the label
+ canvas.text( body, width/2, height+15, name, {'text-anchor':'middle'} );
+
// shotcut
function editorDrag( obj, handle )
{
Modified: PyWireGate/trunk/logic_editor/gle/gle.connection.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.connection.js 2011-05-07 09:29:04 UTC (rev 321)
+++ PyWireGate/trunk/logic_editor/gle/gle.connection.js 2011-05-07 19:39:44 UTC (rev 322)
@@ -60,6 +60,7 @@
stroke: colorByArray( origin.getColor() ),
'stroke-width': 1,
'marker-end' : 'url(#ArrowEnd)',
+ 'z-index': 999,
fill: 'none'
};
@@ -318,5 +319,7 @@
paths : paths
};
}
+
+ draw(); // show directly after construction
}
Modified: PyWireGate/trunk/logic_editor/logicEditor.js
===================================================================
--- PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-07 09:29:04 UTC (rev 321)
+++ PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-07 19:39:44 UTC (rev 322)
@@ -37,10 +37,12 @@
south__closable : false,
south__resizable: false
});
- $('#structureTree').jstree({
- plugins : [ 'json_data', 'themes', 'types' ],
+ $('#structureTree').bind("select_node.jstree", function (event, data) {
+ displayLogic( $.trim( $(data.args[0]).text() ) );
+ }).jstree({
+ plugins : [ 'json_data', 'themes', 'types', 'ui' ],
json_data : {
- data : [
+ data : [/*
{
data : 'System 1',
attr : { rel : 'logic' },
@@ -65,7 +67,7 @@
title : 'System 2',
attr : { href : "#" }
}
- }
+ }*/
]
},
themes: {
@@ -77,7 +79,11 @@
types: {
logic : { icon: { image: 'icon/16/code-block.png' } },
subsystem: { icon: { image: 'icon/16/code-block.png' } }
- }
+ },
+ },
+ 'ui' : {
+ 'select_limit' : 1,
+ 'selected_parent_close' : 'select_parent'
}
});
@@ -129,10 +135,10 @@
$.each( libJSON, function( libName ){
var lib = $('<div class="lib"><div class="libName">'+libName+'</div></div>');
$.each( this, function( element ){
- var entry = $('<div class="libEntry"><div class="libEntryName">'+element+'</div></div>');
+ var entry = $('<div class="libEntry"></div>');
var obj = this;
var width = this.width+20;
- var height = this.height+20;
+ var height = this.height+35;
entry.prepend(
$('<div style="width:'+width+'px;height:'+height+'px;" ></div>').
svg({onLoad:function(svg){drawElement(svg,obj,false);},settings:{width:width,height:height,viewBox:'-10 -10 '+width+' '+height}}).
@@ -147,12 +153,47 @@
});
}
-var blockRegistry = [];
+function updateKnownLogics( newLogicName )
+{
+ $('#structureTree').jstree('create_node', -1, 'after', {
+ 'data' : newLogicName,
+ 'attr' : { rel : 'logic'}
+ });
+}
+function displayLogic( logicName )
+{
+ console.log( '"'+logicName+'"' );
+ logic = logics[ logicName ];
+ $.each( logic.blocks, function( name, def ){
+ var newBlock = $.extend( true, {}, libJSON['MainLib'][ def.type ], def, {'name':name} );
+ drawElement( undefined, newBlock, true );
+ });
+ console.log( blockRegistry );
+ $.each( logic.signals, function( name, def ){
+ console.log( name, def, blockRegistry[ def[0] ] );
+
+ var startBlock = blockRegistry[ def[0] ];
+ var endBlock = blockRegistry[ def[2] ];
+ var pn = def[1];
+ var op = startBlock.outPortPos( pn )[0];
+ var ip = endBlock.inPortPos( def[3] )[0];
+ var c = new Connection({
+ origin : startBlock,
+ originPortNumber: pn,
+ paths : [{path:[ [op.x, op.y], [ip.x, ip.y] ],target:endBlock}]
+ });
+ startBlock.setConnection( 'outPort', pn, c );
+ endBlock.setConnection( 'inPort', def[3], c );
+ });
+}
+
+var blockRegistry = {};
+
function drawElement( svg, element, addEvent ){
if( addEvent === undefined ) addEvent = true;
var b = new Block( element, svg, addEvent );
- if( addEvent ) blockRegistry.push( b );
+ if( addEvent ) blockRegistry[ element.name ] = b;
}
function colorByArray( a )
Added: PyWireGate/trunk/logic_server/CodeClass.py
===================================================================
--- PyWireGate/trunk/logic_server/CodeClass.py (rev 0)
+++ PyWireGate/trunk/logic_server/CodeClass.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## CodeClass.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+class CodeClass:
+ """The object that contains the code to run from the task manager and the
+ definied entry points for that"""
+ def getParameter( self, parameter ):
+ return getattr( self, parameter )
+
+ def setParameter( self, parameter, value ):
+ setattr( self, parameter, value )
\ No newline at end of file
Added: PyWireGate/trunk/logic_server/LogicImportJSON.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicImportJSON.py (rev 0)
+++ PyWireGate/trunk/logic_server/LogicImportJSON.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,113 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## LogicImportJSON.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+import codecs
+import simplejson as json
+import networkx as nx
+import LogicLibrary
+
+def get( file, printCode = False, displayGraph = False ):
+ G=nx.DiGraph()
+ lib = LogicLibrary.LogicLibrary().getLibrary()
+
+ db = codecs.open( file, 'r', encoding = 'UTF-8' )
+ data = db.read()
+ loaddict = json.loads(data)
+ db.close()
+
+ parameter = '' # the string to set up the block parameters
+ init = '' # the string containing the inital setup
+ program = '' # the string containing the concatenated instructions
+ stateupdate = '' # the string containing the update of the states
+
+ for name, attribute in loaddict['blocks'].iteritems():
+ block = lib[ attribute['type'] ]
+ G.add_node( name, attribute )
+ # Add aditional, virtual node "<name>.state" that is treates as an additional
+ # input with no dependancy as the state won't change during an update cycle,
+ # only afterwards
+ if block.hasState():
+ G.add_node( name + '.state' )
+ for p in block.outPorts():
+ if block.outPortNameHasState( p[0] ):
+ stateupdate += " self.%s_%s = %s_%s_next\n" % ( name, p[0], name, p[0] )
+
+ for signal in loaddict['signals']:
+ b = loaddict['blocks']
+ if lib[ loaddict['blocks'][ signal[0] ]['type'] ].outPortNameHasState( signal[1] ):
+ G.add_edge( signal[0] + '.state', signal[2], { 'ports': ( signal[1], signal[3] ), 'start': signal[0] } )
+ else:
+ G.add_edge( signal[0], signal[2], { 'ports': ( signal[1], signal[3] ), 'start': signal[0] } )
+
+ intructionOrder = nx.topological_sort(G)
+
+ for instruction in intructionOrder:
+ if not instruction in loaddict['blocks']:
+ continue # ignore the virtual state nodes
+ libBlock = lib[ loaddict['blocks'][ instruction ]['type'] ]
+ ins = []
+ for i in libBlock.inPorts():
+ for e in G.in_edges_iter( instruction, True ):
+ if e[2]['ports'][1] == i:
+ if lib[ loaddict['blocks'][ e[2]['start'] ]['type'] ].outPortNameHasState( e[2]['ports'][0] ):
+ ins.append( "self.%s_%s" % ( e[2]['start'], e[2]['ports'][0] ) )
+ else:
+ ins.append( "%s_%s" % ( e[2]['start'], e[2]['ports'][0] ) )
+ outs = []
+ for o in libBlock.outPorts():
+ outs.append( "%s_%s" % (instruction, o[0]) )
+ params = []
+ for p in G.node[instruction]['parameters']:
+ paramName = "%s_%s" % (instruction, p)
+ paramValue = G.node[instruction]['parameters'][p]
+ if isinstance( paramValue, basestring):
+ paramValue = "globalVariables['%s']" % paramValue
+ parameter += " self.%s = %s\n" % (paramName, paramValue)
+ params.append( "self." + paramName )
+ i = libBlock.codingIntructions( instruction, ins, outs, params )
+ if None != i[0]:
+ init += " self.%s\n" % i[0]
+ program += " %s\n" % i[1]
+
+ code = """import CodeClass
+class LogikClass( CodeClass.CodeClass ):
+ def __init__( self, globalVariables ):
+%s
+%s
+ def run( self, globalVariables ):
+ __dt = globalVariables['__dt']
+ __time = globalVariables['__elapsedTime']
+%s
+%s
+""" % ( parameter, init, program, stateupdate )
+
+ if printCode:
+ print code
+
+ if displayGraph:
+ # just to show - connect the states
+ for name, attribute in loaddict['blocks'].iteritems():
+ block = lib[ attribute['type'] ]
+ if block.hasState():
+ G.add_edge( name, name + '.state' )
+ import matplotlib.pyplot as plt
+ nx.draw(G)
+ plt.show()
+
+ c = compile( code, '<string>', 'exec' )
+ return c
\ No newline at end of file
Added: PyWireGate/trunk/logic_server/LogicLibrary.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicLibrary.py (rev 0)
+++ PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## LogicLibrary.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+import LogicModule
+
+class ConstBlock( LogicModule.LogicModule ):
+ _name = "const"
+ _inPorts = []
+ _outPorts = [ ( 'out', 'const' ) ]
+ _parameters = [ 'value' ]
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( "%s = %s" % ( o[0], p[0] ), "%s_next = %s" % ( o[0], p[0] ) )
+
+class LogBlock( LogicModule.LogicModule ):
+ _name = "log"
+ _inPorts = [ 'in' ]
+ _outPorts = []
+ _parameters = []
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( None, "print __time,',','\"%%s\"' %% globalVariables['__name'],',','%s',',',%s" % ( n, i[0]) )
+
+class GainBlock( LogicModule.LogicModule ):
+ _name = "gain"
+ _inPorts = [ 'in' ]
+ _outPorts = [ ( 'out', 'signal' ) ]
+ _parameters = [ 'gain' ]
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( None, "%s = %s * %s" % ( o[0], p[0], i[0] ) )
+
+class SumBlock( LogicModule.LogicModule ):
+ _name = "sum"
+ _inPorts = [ 'in1', 'in2' ]
+ _outPorts = [ ( 'out', 'signal' ) ]
+ _parameters = []
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( None, "%s = %s + %s" % ( o[0], i[0], i[1] ) )
+
+class MemoryBlock( LogicModule.LogicModule ):
+ _name = "memory"
+ _inPorts = [ 'in' ]
+ _outPorts = [ ( 'out', 'state' ) ]
+ _parameters = [ 'inital_value' ]
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( "%s = %s" % (o[0], p[0]), "%s_next = %s" % ( o[0], i[0] ) )
+
+class IntegralBlock( LogicModule.LogicModule ):
+ _name = "integral"
+ _inPorts = [ 'in' ]
+ _outPorts = [ ( 'out', 'state' ) ]
+ _parameters = [ 'initial_value' ]
+ _drawingInstructions = ""
+ _codingInstructions = lambda s, n, i, o, p: ( "%s = %s" % (o[0], p[0]), "%s_next = %s * %s + self.%s" % ( o[0], "__dt", i[0], o[0] ) )
+
+class LogicLibrary:
+ """The container for all known library blocks"""
+ _db = {}
+
+ def __init__( self ):
+ self.addBlock( ConstBlock )
+ self.addBlock( LogBlock )
+ self.addBlock( GainBlock )
+ self.addBlock( SumBlock )
+ self.addBlock( MemoryBlock )
+ self.addBlock( IntegralBlock )
+
+ def addBlock( self, block ):
+ b = block()
+ self._db[ b.name() ] = b
+
+ def getLibrary( self ):
+ return self._db
+
Added: PyWireGate/trunk/logic_server/LogicModule.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicModule.py (rev 0)
+++ PyWireGate/trunk/logic_server/LogicModule.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,56 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## LogicModule.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+class LogicModule:
+ """The base class for a generic logic module"""
+ def name( self ):
+ return self._name
+
+ def inPorts( self ):
+ return self._inPorts
+
+ def outPorts( self ):
+ return self._outPorts
+
+ def parameters( self ):
+ return self._parameters
+
+ def drawingIntructions( self ):
+ return self._drawingInstructions
+
+ def codingIntructions( self, name, ins, outs, params ):
+ return self._codingInstructions( name, ins, outs, params )
+
+ def hasState( self ):
+ for port in self.outPorts():
+ if ('state' == port[1]) or ('const' == port[1]):
+ return True
+ return False
+
+ def outPortNumberHasState( self, i ):
+ portType = self.outPorts()[ i ][1]
+ if ('state' == portType) or ('const' == portType):
+ return True
+ return False
+
+ def outPortNameHasState( self, n ):
+ for port in self.outPorts():
+ if port[0] == n:
+ if ('state' == port[1]) or ('const' == port[1]):
+ return True
+ return False
Added: PyWireGate/trunk/logic_server/LogicServer.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicServer.py (rev 0)
+++ PyWireGate/trunk/logic_server/LogicServer.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## LogicServer.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+from connector import Connector
+import LogicImportJSON
+import TaskManager
+
+import time
+
+## Load logik.json
+#exec LogicImportJSON.get( 'logik.json' )
+#Logik1 = LogikClass
+
+## Load logik2.json - and show code and diagram
+#exec LogicImportJSON.get( 'logik2.json' )
+#Logik2 = LogikClass
+
+#t = TaskManager.TaskManager()
+#t.addInterval( 'Interval 1 - 75 ms Task', 0.075 )
+#t.addInterval( 'Interval 2 - 10 ms Task', 0.01 )
+#t.addTask( 'Interval 1 - 75 ms Task', 'Logik1', Logik1 )
+#t.addTask( 'Interval 2 - 10 ms Task', 'Logik2', Logik2 )
+#for i in range(10):
+ #t.addInterval( 'i%s' % i, 6.0 )
+ #t.addTask( 'i%s' % i, 'foo', Logik1 )
+#t.start()
+#time.sleep(6.5)
+#t.stop()
+
+class logic_server(Connector):
+ CONNECTOR_NAME = 'Logic Server'
+ CONNECTOR_VERSION = 0.1
+ CONNECTOR_LOGNAME = 'logic_server'
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ self.WG = parent.WG
+ self.instanceName = instanceName
+
+ ## Deafaultconfig
+ defaultconfig = {
+ }
+
+ ## check Defaultconfig Options in main configfile
+ self.WG.checkconfig(self.instanceName,defaultconfig)
+
+ ## set local config
+ self.config = self.WG.config[self.instanceName]
+
+ ## Start the Thread
+ self.start()
+
+ def run(self):
+ # Load logik.json
+ exec LogicImportJSON.get( self._parent.scriptpath + '/logik.json' )
+ self.Logik1 = LogikClass
+
+ # Load logik2.json - and show code and diagram
+ exec LogicImportJSON.get( self._parent.scriptpath + '/logik2.json' )
+ self.Logik2 = LogikClass
+
+ cnt = 0
+ while self.isrunning:
+ if cnt == 60 and self.isrunning:
+ self.statistics()
+ if self.isrunning:
+ cnt +=1
+ self.idle(5)
Added: PyWireGate/trunk/logic_server/TaskManager.py
===================================================================
--- PyWireGate/trunk/logic_server/TaskManager.py (rev 0)
+++ PyWireGate/trunk/logic_server/TaskManager.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,85 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+## -----------------------------------------------------
+## TaskManager.py
+## -----------------------------------------------------
+## Copyright (c) 2011, Christian Mayer, All rights reserved.
+##
+## 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 3 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, see <http://www.gnu.de/documents/gpl-3.0.de.html>.
+
+# A task manager that runs the little code snippets
+from multiprocessing import Process, Queue as mpQueue
+import Queue
+import time
+
+class TaskManager:
+ """The task manager that called all programs in the defined order at the
+ specified interval"""
+ taskList = {}
+
+ def addInterval( self, name, interval ):
+ if name in self.taskList:
+ raise # Name already in interval list!
+ q = mpQueue()
+ self.taskList[name] = [ None, interval, q, [] ]
+
+ def addTask( self, interval, name, code ):
+ if interval in self.taskList:
+ self.taskList[ interval ][3].append( code )
+ else:
+ raise # interval doesn't exist
+
+ def start( self ):
+ # start the task handling
+ self.startTime = time.time() # only *nix is interesting here
+ for i in self.taskList:
+ interval = self.taskList[ i ][1]
+ q = self.taskList[ i ][2]
+ self.taskList[ i ][0] = Process( target = self.aIntervall, args = ( i, interval, q, self.startTime ) )
+ self.taskList[ i ][0].start()
+
+ def stop( self ):
+ # stop all tasks
+ for i in self.taskList:
+ self.taskList[ i ][2].put( 'STOP' )
+ self.taskList[ i ][0].join()
+
+ def aIntervall( self, name, interval, q, startTime ):
+ globalVariables = {
+ '__name' : name,
+ '__interval' : interval,
+ '__startTime' : startTime,
+ '__elapsedTime': 0.0,
+ '__dt' : interval
+ }
+ # initialize the classes
+ for i in range( len( self.taskList[ name ][3] )):
+ print i, self.taskList[ name ][3][i]
+ self.taskList[ name ][3][i] = self.taskList[ name ][3][i]( globalVariables )
+ # main loop
+ while 1:
+ __elapsedTime = time.time() - startTime
+ globalVariables['__dt'] = __elapsedTime - globalVariables['__elapsedTime']
+ globalVariables['__elapsedTime'] = __elapsedTime
+ for i in self.taskList[ name ][3]:
+ i.run( globalVariables )
+ try:
+ message = q.get( True, interval )
+ except Queue.Empty:
+ continue # just start next iteration immediately
+
+ if 'STOP' == message:
+ break
+
+ def showStatus( self ):
+ print self.taskList
+
\ No newline at end of file
Added: PyWireGate/trunk/logic_server/__init__.py
===================================================================
--- PyWireGate/trunk/logic_server/__init__.py (rev 0)
+++ PyWireGate/trunk/logic_server/__init__.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1 @@
+from LogicServer import logic_server
\ No newline at end of file
Added: PyWireGate/trunk/logic_server/test.py
===================================================================
--- PyWireGate/trunk/logic_server/test.py (rev 0)
+++ PyWireGate/trunk/logic_server/test.py 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+import LogicImportJSON
+import TaskManager
+import LogicCommander
+
+import time
+
+# Load logik.json
+exec LogicImportJSON.get( 'logik.json' )
+Logik1 = LogikClass
+
+# Load logik2.json - and show code and diagram
+exec LogicImportJSON.get( 'logik2.json', True, True )
+Logik2 = LogikClass
+
+t = TaskManager.TaskManager()
+t.addInterval( 'Interval 1 - 75 ms Task', 0.075 )
+t.addInterval( 'Interval 2 - 10 ms Task', 0.01 )
+t.addTask( 'Interval 1 - 75 ms Task', 'Logik1', Logik1 )
+t.addTask( 'Interval 2 - 10 ms Task', 'Logik2', Logik2 )
+for i in range(10):
+ t.addInterval( 'i%s' % i, 6.0 )
+ t.addTask( 'i%s' % i, 'foo', Logik1 )
+t.start()
+time.sleep(6.5)
+t.stop()
Property changes on: PyWireGate/trunk/logic_server/test.py
___________________________________________________________________
Added: svn:executable
+ *
Added: PyWireGate/trunk/logik.json
===================================================================
--- PyWireGate/trunk/logik.json (rev 0)
+++ PyWireGate/trunk/logik.json 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,53 @@
+{
+ "blocks": {
+ "Const1": {
+ "type": "const",
+ "x": 50, "y": 50, "width": 50, "height": 50,
+ "parameters": { "value": 1.0 }
+ },
+ "Gain1": {
+ "type": "gain",
+ "x": 150, "y": 50, "width": 50, "height": 50,
+ "parameters": { "gain": 5.0 }
+ },
+ "Log1": {
+ "type": "log",
+ "x": 250, "y": 150, "width": 50, "height": 50,
+ "parameters": {}
+ },
+ "Log2": {
+ "type": "log",
+ "x": 250, "y": 50, "width": 50, "height": 50,
+ "parameters": {}
+ },
+ "Integral1": {
+ "type": "integral",
+ "x": 50, "y": 250, "width": 50, "height": 50,
+ "parameters": { "inital_value": 1.0 }
+ },
+ "Integral2": {
+ "type": "integral",
+ "x": 150, "y": 250, "width": 50, "height": 50,
+ "parameters": { "inital_value": 0.0 }
+ },
+ "Gain2": {
+ "type": "gain",
+ "x": 150, "y": 350, "width": 50, "height": 50,
+ "parameters": { "gain": -1.0 }
+ },
+ "Log3": {
+ "type": "log",
+ "x": 250, "y": 250, "width": 50, "height": 50,
+ "parameters": {}
+ }
+ },
+ "signals": [
+ [ "Const1" , 0, "Log1" , 0, {} ],
+ [ "Const1" , 0, "Gain1" , 0, {} ],
+ [ "Gain1" , 0, "Log2" , 0, {} ],
+ [ "Integral1", 0, "Integral2" , 0, {} ],
+ [ "Integral2", 0, "Gain2" , 0, {} ],
+ [ "Gain2" , 0, "Integral1" , 0, {} ],
+ [ "Integral2", 0, "Log3" , 0, {} ]
+ ]
+}
\ No newline at end of file
Added: PyWireGate/trunk/logik2.json
===================================================================
--- PyWireGate/trunk/logik2.json (rev 0)
+++ PyWireGate/trunk/logik2.json 2011-05-07 19:39:44 UTC (rev 322)
@@ -0,0 +1,43 @@
+{
+ "blocks": {
+ "Memory1": {
+ "type": "memory",
+ "x": 150, "y": 300, "width": 50, "height": 50,
+ "parameters": { "initial_value": 1.0 }
+ },
+ "Gain1": {
+ "type": "gain",
+ "x": 50, "y": 150, "width": 50, "height": 50,
+ "parameters": { "gain": "__dt" }
+ },
+ "Sum1": {
+ "type": "sum",
+ "x": 150, "y": 200, "width": 50, "height": 50,
+ "parameters": {}
+ },
+ "Log22": {
+ "type": "log",
+ "x": 350, "y": 300, "width": 50, "height": 50,
+ "parameters": {}
+ },
+ "Integral2": {
+ "type": "integral",
+ "x": 250, "y": 300, "width": 50, "height": 50,
+ "parameters": { "inital_value": 0.0 }
+ },
+ "Gain2": {
+ "type": "gain",
+ "x": 150, "y": 50, "width": 50, "height": 50,
+ "parameters": { "gain": -1.0 }
+ }
+ },
+ "signals": [
+ [ "Memory1" , 0, "Integral2" , 0, {} ],
+ [ "Gain1" , 0, "Sum1" , 0, {} ],
+ [ "Sum1" , 0, "Memory1" , 0, {} ],
+ [ "Memory1" , 0, "Sum1" , 1, {} ],
+ [ "Integral2", 0, "Gain2" , 0, {} ],
+ [ "Gain2" , 0, "Gain1" , 0, {} ],
+ [ "Integral2", 0, "Log22" , 0, {} ]
+ ]
+}
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|