|
From: <ni...@us...> - 2010-11-03 13:18:06
|
Revision: 65
http://openautomation.svn.sourceforge.net/openautomation/?rev=65&view=rev
Author: nilss1
Date: 2010-11-03 13:17:57 +0000 (Wed, 03 Nov 2010)
Log Message:
-----------
sorry, too many updates cleanup later, just want to keep a version in repo
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/connector.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/BusMonitor.py
PyWireGate/trunk/knx_connector/DPT_Types.py
PyWireGate/trunk/knx_connector/GroupSocket.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
PyWireGate/trunk/owfs_connector/connection.py
Added Paths:
-----------
PyWireGate/trunk/DSupdate.py
PyWireGate/trunk/simplejson/
PyWireGate/trunk/simplejson/.___init__.py
PyWireGate/trunk/simplejson/._decoder.py
PyWireGate/trunk/simplejson/._scanner.py
PyWireGate/trunk/simplejson/__init__.py
PyWireGate/trunk/simplejson/_speedups.c
PyWireGate/trunk/simplejson/decoder.py
PyWireGate/trunk/simplejson/encoder.py
PyWireGate/trunk/simplejson/ordered_dict.py
PyWireGate/trunk/simplejson/scanner.py
PyWireGate/trunk/simplejson/tests/
PyWireGate/trunk/simplejson/tests/.___init__.py
PyWireGate/trunk/simplejson/tests/._test_dump.py
PyWireGate/trunk/simplejson/tests/._test_errors.py
PyWireGate/trunk/simplejson/tests/._test_fail.py
PyWireGate/trunk/simplejson/tests/__init__.py
PyWireGate/trunk/simplejson/tests/test_check_circular.py
PyWireGate/trunk/simplejson/tests/test_decimal.py
PyWireGate/trunk/simplejson/tests/test_decode.py
PyWireGate/trunk/simplejson/tests/test_default.py
PyWireGate/trunk/simplejson/tests/test_dump.py
PyWireGate/trunk/simplejson/tests/test_encode_basestring_ascii.py
PyWireGate/trunk/simplejson/tests/test_encode_for_html.py
PyWireGate/trunk/simplejson/tests/test_errors.py
PyWireGate/trunk/simplejson/tests/test_fail.py
PyWireGate/trunk/simplejson/tests/test_float.py
PyWireGate/trunk/simplejson/tests/test_indent.py
PyWireGate/trunk/simplejson/tests/test_pass1.py
PyWireGate/trunk/simplejson/tests/test_pass2.py
PyWireGate/trunk/simplejson/tests/test_pass3.py
PyWireGate/trunk/simplejson/tests/test_recursion.py
PyWireGate/trunk/simplejson/tests/test_scanstring.py
PyWireGate/trunk/simplejson/tests/test_separators.py
PyWireGate/trunk/simplejson/tests/test_speedups.py
PyWireGate/trunk/simplejson/tests/test_unicode.py
PyWireGate/trunk/simplejson/tool.py
Added: PyWireGate/trunk/DSupdate.py
===================================================================
--- PyWireGate/trunk/DSupdate.py (rev 0)
+++ PyWireGate/trunk/DSupdate.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -0,0 +1,161 @@
+import getopt
+import ConfigParser
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+
+import datastore
+
+import sys
+
+class dbloader:
+ def __init__(self,config,fname):
+ self.config = config
+ self.dataobjects = {}
+ ## load datastore
+ self.load()
+ if config['type'].upper() == "KNX":
+ self.KNXloader(fname)
+ elif config['type'].upper() == "OWFS":
+ self.OWFSloader(fname)
+ self.save()
+
+ def readConfig(self,configfile):
+ cfile = open(configfile,"r")
+ ## fix for missingsectionheaders
+ while True:
+ pos = cfile.tell()
+ if cfile.readline().startswith("["):
+ break
+ cfile.seek(pos)
+ config = {}
+ configparse = ConfigParser.SafeConfigParser()
+ configparse.readfp(cfile)
+ for section in configparse.sections():
+ options = configparse.options(section)
+ config[section] = {}
+ for opt in options:
+ try:
+ config[section][opt] = configparse.getint(section,opt)
+ except ValueError:
+ try:
+ config[section][opt] = configparse.getfloat(section,opt)
+ except ValueError:
+ config[section][opt] = configparse.get(section,opt)
+
+ return config
+
+ def KNXloader(self,fname):
+ ga = self.readConfig(fname)
+ for key in ga.keys():
+ id = "%s:%s" % (self.config['namespace'],key)
+ self.dataobjects[id] = datastore.dataObject(False,id,unicode(ga[key]['name'],errors='ignore'))
+ self.dataobjects[id].config['dptid'] = ga[key]['dptsubid']
+
+ def OWFSloader(self,fname):
+ ow = self.readConfig(fname)
+ for key in ow.keys():
+ id = "%s:%s_temperature" % (self.config['namespace'],key)
+ print "add %s " % id
+ self.dataobjects[id] = datastore.dataObject(False,id,unicode(ow[key]['name'],errors='ignore'))
+ if 'resolution' in ow[key]:
+ self.dataobjects[id].config['resolution'] = ow[key]['resolution']
+ if 'eib_ga_temp' in ow[key]:
+ if len(ow[key]['eib_ga_temp']) >0:
+ knxid = "KNX:%s" % ow[key]['eib_ga_temp']
+ print "Try to attach to %s " % knxid
+ self.dataobjects[id].connected.append(knxid)
+ print "attaached"
+
+
+ def debug(self,msg=''):
+ print msg
+
+ def load(self):
+ ## TODO:
+ self.debug("load DATASTORE")
+ try:
+ db = open(self.config['datastore'],"rb")
+ #loaddict = pickle.Unpickler(db).load()
+ loaddict = json.load(db)
+ db.close()
+ for name, obj in loaddict.items():
+ self.dataobjects[name] = datastore.dataObject(False,obj['id'],obj['name'])
+ self.dataobjects[name].lastupdate = obj['lastupdate']
+ self.dataobjects[name].config = obj['config']
+ self.dataobjects[name].connected = obj['connected']
+ self.debug("%d entries loaded in DATASTORE" % len(self.dataobjects))
+ except:
+ ## no DB File
+ print "DB not found"
+ pass
+ ## Fixme: should belong to conncetor
+
+
+
+ def save(self):
+ ## TODO:
+ self.debug("save DATASTORE")
+ savedict = {}
+ ## FIXME: user create a __reduce__ method for the Datastoreitem object
+ for name,obj in self.dataobjects.items():
+ savedict[name] = {
+ 'name' : obj.name,
+ 'id' : obj.id,
+ 'value' : obj.value,
+ 'lastupdate' : obj.lastupdate,
+ 'config' : obj.config,
+ 'connected' : obj.connected
+ }
+ dbfile = open(self.config['datastore'],"wb")
+ #db = pickle.Pickler(dbfile,-1)
+ #db.dump(savedict)
+ json.dump(savedict,dbfile,sort_keys=True,indent=3)
+ dbfile.close()
+ for i in savedict.keys():
+ if len(savedict[i]['connected'])>0:
+ print savedict[i]
+
+
+if __name__ == "__main__":
+ import os
+ import sys
+ import getopt
+ try:
+ opts, args = getopt.getopt(sys.argv[1:], "f:d:n:t:", ["file=","datastore=","namespace=","type="])
+ except getopt.GetoptError:
+ print "Fehler"
+ sys.exit(2)
+ config = {
+ 'datastore' : 'datastore.db',
+ 'namespace' : 'KNX',
+ 'type' : False
+ }
+ fname = False
+ for opt, arg in opts:
+ if opt in ("-d","--datastore"):
+ config['datastore'] = arg
+
+ if opt in ("-n","--namespace"):
+ config['namespace'] = arg
+
+ if opt in ("-t","--type"):
+ config['type'] = arg
+
+ if opt in ("-f","--file"):
+ fname = arg
+
+ if not fname:
+ print "no configfilename"
+ sys.exit(1)
+ if not config['type']:
+ config['type'] = config['namespace']
+ dbloader(config,fname)
+
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/WireGate.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -58,6 +58,7 @@
self.config = self.readConfig("/etc/wiregate/pywiregate.conf")
defaultconfig = {
'pidfile' : "%s/wiregated.pid" % self.scriptpath,
+ 'datastore' : "%s/datastore.db" % self.scriptpath,
'logfile' : "%s/wiregated.log" % self.scriptpath,
'errorlog' : "%s/wiregated-error.log" % self.scriptpath,
'loglevel': 'info'
@@ -148,6 +149,7 @@
##Set Permissions
os.chown(self.config['WireGate']['pidfile'],runasuser[2],runasuser[3])
os.chown(self.config['WireGate']['logfile'],runasuser[2],runasuser[3])
+ os.chown(self.config['WireGate']['datastore'],runasuser[2],runasuser[3])
os.setregid(runasuser[3],runasuser[3])
os.setreuid(runasuser[2],runasuser[2])
@@ -251,8 +253,6 @@
## Logger for all instances that check/create logger based on Configfile
def log(self,msg,severity="info",instance="WireGate"):
- LEVELS = {'debug': logging.debug,'info': logging.info,'warning': logging.warning,'warn': logging.warning,'error': logging.error,'critical': logging.critical}
- level = LEVELS.get(severity, logging.info)
try:
logger = self.LOGGER[instance]
except KeyError:
@@ -262,8 +262,12 @@
logger.debug(msg)
elif severity=="info":
logger.info(msg)
+ elif severity=="notice":
+ logger.info(msg)
elif severity=="warning":
logger.warning(msg)
+ elif severity=="warn":
+ logger.warning(msg)
elif severity=="error":
logger.error(msg)
elif severity=="critical":
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -47,6 +47,10 @@
pass
+ def setValue(self, dsobj):
+ self.log("unconfigured setValue in %r called for %s" % (self,dsobj.name) ,'warn','WireGate')
+ pass
+
import SocketServer
import socket
class ConnectorServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer,Connector):
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/datastore.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -1,7 +1,19 @@
import time
import threading
+try:
+ import cPickle as pickle
+except ImportError:
+ import pickle
+try:
+ import json
+except ImportError:
+ import simplejson as json
+
+import sys
+import xml.dom.minidom
+
class datastore:
"""
Datastore Instance
@@ -16,23 +28,15 @@
##
####################################################
self.WG = WireGateInstance
+ self.log("DATASTORE starting up")
self.dataobjects = {}
-
+ self.locked = threading.RLock()
+ self.locked.acquire()
+ self.xmltag = lambda x,y,z='': len(z)>0 and "<%s %s>%s</%s>" % (x,z,y,x) or "<%s>%s</%s>" % (x,y,x)
## Load XML Database
self.load()
- ## Fixme: should belong to conncetor
- self.readgaconf()
-
- ## FIXME: that should belong to the Connector
- def readgaconf(self):
- ga = self.WG.readConfig("/etc/wiregate/eibga.conf")
- for key in ga.keys():
- obj = self.get("KNX:%s" % key)
- obj.dptid = ga[key]['dptsubid']
- obj.name = ga[key]['name']
-
def update(self,id,val):
## Update the communication Object with value
####################################################
@@ -44,14 +48,23 @@
## update or create a Datastoreobject
## schould be used by all connectors to set their Values
####################################################
+ ##
## get the Datastore object
obj = self.get(id)
self.debug("Updating %s (%s): %r" % (obj.name,id,val))
## Set the value of the object
obj.setValue(val)
-
+
##TODO: central subscriber function for other connectore or servers
+
+ for attached in obj.connected:
+ try:
+ self.dataobjects[attached].setValue(val,True)
+ except:
+ print "FAILED %s" % attached
+ __import__('traceback').print_exc(file=__import__('sys').stdout)
+ pass
## return the object for additional updates
@@ -66,6 +79,7 @@
## returns or create and returns the Dataobejct with ID id
##
####################################################
+ self.locked.acquire()
try:
## check for existence
type(self.dataobjects[id])
@@ -73,18 +87,88 @@
## create a new one if it don't exist
self.dataobjects[id] = dataObject(self.WG,id)
## return it
+ self.locked.release()
return self.dataobjects[id]
+ ## FIXME: that should belong to the Connector
+ def readgaconf(self):
+ print "SHOULD NOT BE CALLED"
+ ga = self.WG.readConfig("/etc/wiregate/eibga.conf")
+ for key in ga.keys():
+ obj = self.get("KNX:%s" % key)
+ obj.config['dptid'] = ga[key]['dptsubid']
+ obj.name = ga[key]['name']
+ obj._send = self.WG.connectors['KNX'].send
+
+
def load(self):
## TODO:
self.debug("load DATASTORE")
- pass
+ try:
+ db = open(self.WG.config['WireGate']['datastore'],"rb")
+ #loaddict = pickle.Unpickler(db).load()
+ loaddict = json.load(db)
+ db.close()
+ for name, obj in loaddict.items():
+ self.dataobjects[name] = dataObject(self.WG,obj['id'],obj['name'])
+ self.dataobjects[name].lastupdate = obj['lastupdate']
+ self.dataobjects[name].config = obj['config']
+ self.dataobjects[name].connected = obj['connected']
+ self.debug("%d entries loaded in DATASTORE" % len(self.dataobjects))
+ self.locked.release()
+ except IOError:
+ ## no DB File
+ pass
+ ## Fixme: should belong to conncetor
+ self.locked.release()
+ self.readgaconf()
+
+ except:
+ ## error
+ pass
+
def save(self):
## TODO:
self.debug("save DATASTORE")
- pass
+ self.locked.acquire()
+ savedict = {}
+ ## FIXME: user create a __reduce__ method for the Datastoreitem object
+ for name,obj in self.dataobjects.items():
+ savedict[name] = {
+ 'name' : obj.name,
+ 'id' : obj.id,
+ 'value' : obj.value,
+ 'lastupdate' : obj.lastupdate,
+ 'config' : obj.config,
+ 'connected' : obj.connected
+ }
+ dbfile = open(self.WG.config['WireGate']['datastore'],"wb")
+ #db = pickle.Pickler(dbfile,-1)
+ #db.dump(savedict)
+ json.dump(savedict,dbfile,sort_keys=True,indent=3)
+ dbfile.close()
+
+
+ def savetoXML(self):
+ objitemxml = ""
+ for name,obj in self.dataobjects.items():
+ configxml = ""
+ for cname,cval in obj.config.items():
+ configxml += self.xmltag(cname,cval)
+ objitemxml += self.xmltag(
+ "DSitem",
+ self.xmltag("id",name) +
+ self.xmltag("value",obj.getValue(),'type=%r' % type(obj.value).__name__) +
+ self.xmltag("config",configxml)
+ )
+ self.locked.release()
+ xmlout = xml.dom.minidom.parseString(self.xmltag("Datastore",objitemxml))
+ #xmlout = xmlout.toprettyxml(indent=" ")
+ xmlout = xmlout.toxml()
+ ## write binary to preserve UTF8
+ open(self.WG.config['WireGate']['datastore'],"wb").write(xmlout)
def debug(self,msg):
####################################################
@@ -109,6 +193,7 @@
## Threadlocking
self.write_mutex = threading.RLock()
self.read_mutex = threading.RLock()
+
## check for namespace
namespace = id.split(":",1)
if len(namespace)>1:
@@ -116,10 +201,14 @@
else:
## Fixme: maybe default Namespace
namespace = ""
+ self.namespace = namespace
+
+ if not name:
+ ## Initial Name
+ self.name = "%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
+ else:
+ self.name = name
- ## Initial Name
- self.name = "%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
-
## some defaults
self.value = ""
self.lastupdate = 0
@@ -132,9 +221,18 @@
self.config = {}
## connected Logics, communication objects ... goes here
- self.connected = {}
+ self.connected = []
- def setValue(self,val):
+ def _setValue(self,refered_self):
+ ## self override
+ print "Ovveride now"
+ if self.namespace:
+ self._setValue = self.WG.connectors[self.namespace].setValue
+ self.WG.connectors[self.namespace].setValue(refered_self)
+ ## override with connector send function
+ pass
+
+ def setValue(self,val,send=False):
try:
## get read lock
self.read_mutex.acquire()
@@ -143,6 +241,8 @@
## save the modified time
self.lastupdate = time.time()
self.value = val
+ if send:
+ self._setValue(self)
finally:
## release locks
self.write_mutex.release()
@@ -160,3 +260,39 @@
+#import json
+
+def JSON2DataStore(text):
+ obj = {}
+ return obj
+
+
+def DataStore2JSON(obj):
+ text = ""
+ return text
+
+class testtwo:
+ def __init__(self):
+ self.i=10
+ def _send(self,val):
+ """Hallo"""
+ print str(dir(self)) +str(val+self.i)
+
+class testthree:
+ def __init__(self):
+ self.u=1
+ def send(self,val):
+ """its me"""
+ print str(dir(self)) +str(self.u)
+
+
+
+if __name__ == "__main__":
+ two = testtwo()
+ two._send(20)
+ three = testthree()
+ two._send = three.send
+ two._send(20)
+ print two._send
+ print dir(two)
+
\ No newline at end of file
Modified: PyWireGate/trunk/knx_connector/BusMonitor.py
===================================================================
--- PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -20,11 +20,12 @@
import time
class busmonitor:
- def __init__(self, WireGateInstance):
+ def __init__(self, WireGateInstance,connectorInstance):
self.WG = WireGateInstance
+ self.KNX = connectorInstance
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type()
+ self.dpt = DPT_Types.dpt_type(WireGateInstance)
## FIXME: Not fully implemented
self.apcicodes = {
@@ -99,8 +100,9 @@
if msg['ctrl2']['DestAddrType'] == 0 and msg['apdu']['tpdu'] == "T_DATA_XXX_REQ":
msg['dstaddr'] = self._decodeGrpAddr(buf[3:5])
- id = "KNX:%s" % msg['dstaddr']
+ id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
+
## search Datastoreobject
dsobj = self.WG.DATASTORE.get(id)
## Decode the DPT Value
@@ -121,12 +123,8 @@
return msg
- def errormsg(self,msg=''):
- f=open("/tmp/WGerror","a+")
- __import__('traceback').print_exc(file=f)
- f.write(time.asctime())
- f.write("MSG:"+repr(msg))
- f.close()
+ def errormsg(self,msg=False):
+ self.WG.errorlog(msg)
def _decodeCtrlField1(self,raw):
Modified: PyWireGate/trunk/knx_connector/DPT_Types.py
===================================================================
--- PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -21,7 +21,7 @@
### sondern als LIST mit den dezimalen Werten ist das decode hier ein bischen angepasst
class dpt_type:
- def __init__(self,WireGateInstance=False):
+ def __init__(self,WireGateInstance):
self.WG = WireGateInstance
self.DECODER = {
1:self.decodeDPT1, # EIS 1/7 / 1 bit 0=Aus/1=Ein
@@ -50,7 +50,8 @@
if dptid > 0:
dpt = dptid
elif dsobj:
- dpt = dsobj.dptid
+ if "dptid" in dsobj.config:
+ dpt = dsobj.config['dptid']
else:
return False
if dpt == -1:
@@ -75,13 +76,18 @@
self.errormsg()
return raw
- def errormsg(self,msg=''):
- __import__('traceback').print_exc(file=__import__('sys').stdout)
+ def errormsg(self,msg=False):
+ self.WG.errormsg(msg)
def debug(self,msg):
- #print msg
- pass
+ self.log(msg,'debug')
+
+ def log(self,msg,severity='info',instance=False):
+ if not instance:
+ instance = "dpt-types"
+ self.WG.log(msg,severity,instance)
+
def toBigInt(self,raw):
c=0
res = 0
@@ -212,6 +218,7 @@
def decodeDPT16(self,raw):
res = ""
for char in raw:
+ ## stop on terminating \x00
if char == 0:
break
res += chr(char)
Modified: PyWireGate/trunk/knx_connector/GroupSocket.py
===================================================================
--- PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -20,11 +20,12 @@
import time
class groupsocket:
- def __init__(self, WireGateInstance):
+ def __init__(self, WireGateInstance, connectorInstance):
self.WG = WireGateInstance
+ self.KNX = connectorInstance
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type()
+ self.dpt = DPT_Types.dpt_type(WireGateInstance)
def decode(self,buf,src,dst):
## Accept List Hex or Binary Data
@@ -48,7 +49,7 @@
msg['srcaddr'] = self._decodePhysicalAddr(src)
try:
msg['dstaddr'] = self._decodeGrpAddr(dst)
- id = "KNX:%s" % msg['dstaddr']
+ id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
if (buf[0] & 0x3 or (buf[1] & 0xC0) == 0xC0):
##FIXME: unknown APDU
self.debug("unknown APDU from "+msg['srcaddr']+" to "+msg['dstaddr']+ " raw:"+buf)
@@ -78,13 +79,9 @@
return msg
- def errormsg(self,msg=''):
- f=open("/tmp/WGerror","a+")
- __import__('traceback').print_exc(file=f)
- f.write(time.asctime())
- f.write("MSG:"+repr(msg))
- f.close()
-
+ def errormsg(self,msg=False):
+ ## central error handling
+ self.WG.errorlog(msg)
def _decodePhysicalAddr(self,raw):
return "%d.%d.%d" % ((raw >> 12) & 0x0f, (raw >> 8) & 0x0f, (raw) & 0xff)
@@ -93,7 +90,7 @@
return "%d/%d/%d" % ((raw >> 11) & 0x1f, (raw >> 8) & 0x07, (raw) & 0xff)
def debug(self,msg):
- print "DEBUG: GROUPSOCKET: "+ repr(msg)
+ #print "DEBUG: GROUPSOCKET: "+ repr(msg)
pass
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -35,8 +35,8 @@
self.KNXBuffer = EIBConnection.EIBBuffer()
self.KNXSrc = EIBConnection.EIBAddr()
self.KNXDst = EIBConnection.EIBAddr()
- self.busmon = BusMonitor.busmonitor(WireGateInstance)
- self.groupsocket = GroupSocket.groupsocket(WireGateInstance)
+ self.busmon = BusMonitor.busmonitor(WireGateInstance,self)
+ self.groupsocket = GroupSocket.groupsocket(WireGateInstance,self)
## Deafaultconfig
defaultconfig = {
@@ -82,7 +82,7 @@
def _run(self):
while self.isrunning:
## Check if we are alive and responde until 10 secs
- self.WG.watchdog("knx_connector",10)
+ self.WG.watchdog(self.instanceName,10)
try:
vbusmonin, vbusmonout, vbusmonerr = select.select([self.KNX.EIB_Poll_FD()],[],[],1)
except:
@@ -114,3 +114,7 @@
if len(self.KNXBuffer.buffer) > 7 :
self.busmon.decode(self.KNXBuffer.buffer)
+
+
+ def send(self,dsobj):
+ print "SEND to %s" % dsobj.name
\ No newline at end of file
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -172,7 +172,7 @@
## loop through their interfaces
for get in self.busmaster[busname]['sensors'][sensor]['interfaces']:
resolution = ""
- id = "OW:"+sensor+"_"+get
+ id = "%s:%s_%s" % (self.instanceName,sensor,get)
## get the Datastore Object and look for config
obj = self.WG.DATASTORE.get(id)
@@ -205,4 +205,3 @@
threadname = "OWFS-Reader_%s" % busname
self.busmaster[busname]['readthread'] = threading.Thread(target=self._read,args=[busname],name=threadname)
self.busmaster[busname]['readthread'].start()
-
\ No newline at end of file
Modified: PyWireGate/trunk/owfs_connector/connection.py
===================================================================
--- PyWireGate/trunk/owfs_connector/connection.py 2010-11-01 21:14:31 UTC (rev 64)
+++ PyWireGate/trunk/owfs_connector/connection.py 2010-11-03 13:17:57 UTC (rev 65)
@@ -88,6 +88,7 @@
self._server = server
self._port = port
+ self.checknum = re.compile(r"(^\d+$)|(^\d+\x2e\d+$)", re.MULTILINE)
def __str__(self):
@@ -121,91 +122,120 @@
"""
"""
- #print 'Connection.read("%s", %i, "%s")' % (path)
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((self._server, self._port))
+ #print 'Connection.read("%s")' % (path)
+
+ rtn = None
+ ## we don't want errors
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((self._server, self._port))
+ except:
+ ##
+ return rtn
- smsg = self.pack(OWMsg.read, len(path) + 1, 8192)
- s.sendall(smsg)
- s.sendall(path + '\x00')
+ smsg = self.pack(OWMsg.read, len(path) + 1, 8192)
+ s.sendall(smsg)
+ s.sendall(path + '\x00')
- while 1:
- data = s.recv(24)
+ while 1:
+ try:
+ data = s.recv(24)
+ except:
+ ##
+ return rtn
- if len(data) is not 24:
- raise exShortRead
+ payload_len = -1
+ if len(data) is 24:
+ ret, payload_len, data_len = self.unpack(data)
- ret, payload_len, data_len = self.unpack(data)
+ if payload_len >= 0:
+ data = s.recv(payload_len)
+ return self.toNumber(data[:data_len])
+ break
+ else:
+ # ping response
+ return None
- if payload_len >= 0:
- data = s.recv(payload_len)
- rtn = self.toNumber(data[:data_len])
- break
- else:
- # ping response
- rtn = None
- break
+ finally:
+ s.close()
+
- s.close()
- return rtn
-
def write(self, path, value):
"""
"""
+ ret = None
+ try:
+ #print 'Connection.write("%s", "%s")' % (path, str(value))
+ s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ try:
+ s.connect((self._server, self._port))
+ except:
+ return ret
- #print 'Connection.write("%s", "%s")' % (path, str(value))
- s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- s.connect((self._server, self._port))
+ value = str(value)
+ smsg = self.pack(OWMsg.write, len(path) + 1 + len(value) + 1, len(value) + 1)
+ s.sendall(smsg)
+ s.sendall(path + '\...
[truncated message content] |
|
From: <ni...@us...> - 2010-11-04 20:05:18
|
Revision: 73
http://openautomation.svn.sourceforge.net/openautomation/?rev=73&view=rev
Author: nilss1
Date: 2010-11-04 20:05:11 +0000 (Thu, 04 Nov 2010)
Log Message:
-----------
changed datastore.db to UTF-8 and Datastore to unicode
Modified Paths:
--------------
PyWireGate/trunk/DSupdate.py
PyWireGate/trunk/datastore.py
Modified: PyWireGate/trunk/DSupdate.py
===================================================================
--- PyWireGate/trunk/DSupdate.py 2010-11-04 13:27:57 UTC (rev 72)
+++ PyWireGate/trunk/DSupdate.py 2010-11-04 20:05:11 UTC (rev 73)
@@ -1,6 +1,7 @@
import getopt
import ConfigParser
import sys
+import codecs
import datastore
try:
@@ -24,7 +25,7 @@
self.save()
def readConfig(self,configfile):
- cfile = open(configfile,"r")
+ cfile = codecs.open(configfile,"r")
## fix for missingsectionheaders
while True:
pos = cfile.tell()
@@ -52,7 +53,7 @@
ga = self.readConfig(fname)
for key in ga.keys():
id = "%s:%s" % (self.config['namespace'],key)
- self.dataobjects[id] = datastore.dataObject(False,id,unicode(ga[key]['name'],errors='ignore'))
+ self.dataobjects[id] = datastore.dataObject(False,id,ga[key]['name'].decode('iso-8859-15'))
self.dataobjects[id].config['dptid'] = ga[key]['dptsubid']
def OWFSloader(self,fname):
@@ -61,7 +62,7 @@
id = "%s:%s_temperature" % (self.config['namespace'],key)
## Fixme: Humidity ... not included
print "add %s " % id
- self.dataobjects[id] = datastore.dataObject(False,id,unicode(ow[key]['name'],errors='ignore'))
+ self.dataobjects[id] = datastore.dataObject(False,id,ow[key]['name'].decode('iso-8859-15'))
if 'resolution' in ow[key]:
self.dataobjects[id].config['resolution'] = ow[key]['resolution']
if 'eib_ga_temp' in ow[key]:
@@ -78,7 +79,7 @@
def load(self):
self.debug("load DATASTORE")
try:
- db = open(self.config['datastore'],"rb")
+ db = codecs.open(self.config['datastore'],"rb",encoding='utf-8')
loaddict = json.load(db)
db.close()
for name, obj in loaddict.items():
@@ -106,7 +107,7 @@
'config' : obj.config,
'connected' : obj.connected
}
- dbfile = open(self.config['datastore'],"wb")
+ dbfile = codecs.open(self.config['datastore'],"wb",encoding='utf-8')
json.dump(savedict,dbfile,sort_keys=True,indent=3)
dbfile.close()
for i in savedict.keys():
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-04 13:27:57 UTC (rev 72)
+++ PyWireGate/trunk/datastore.py 2010-11-04 20:05:11 UTC (rev 73)
@@ -2,6 +2,8 @@
import time
import threading
+import codecs
+
try:
## use included json in > Python 2.6
import json
@@ -89,7 +91,7 @@
def load(self):
self.debug("load DATASTORE")
try:
- db = open(self.WG.config['WireGate']['datastore'],"rb")
+ db = codecs.open(self.WG.config['WireGate']['datastore'],"rb",encoding='utf-8')
loaddict = json.load(db)
db.close()
for name, obj in loaddict.items():
@@ -127,8 +129,10 @@
'config' : obj.config,
'connected' : obj.connected
}
- dbfile = open(self.WG.config['WireGate']['datastore'],"wb")
- json.dump(savedict,dbfile,sort_keys=True,indent=3)
+ dbfile = codecs.open(self.WG.config['WireGate']['datastore'],"wb",encoding='utf-8')
+ utfdb = json.dumps(savedict,dbfile,ensure_ascii=False,sort_keys=True,indent=3)
+ dbfile.write(utfdb)
+ #json.dump(savedict,dbfile,sort_keys=True,indent=3)
dbfile.close()
@@ -168,12 +172,15 @@
if not name:
## Initial Name
- self.name = "%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
+ self.name = u"%s:unbekannt-%s" % (namespace, time.strftime("%Y-%m-%d_%H:%M:%S"))
else:
self.name = name
+ if type(self.name) <> unicode:
+ ## guess that non unicode is iso8859
+ self.name = name.decode("iso-8859-15")
## some defaults
- self.value = ""
+ self.value = u""
self.lastupdate = 0
self.id = id
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-04 22:27:19
|
Revision: 79
http://openautomation.svn.sourceforge.net/openautomation/?rev=79&view=rev
Author: nilss1
Date: 2010-11-04 22:27:12 +0000 (Thu, 04 Nov 2010)
Log Message:
-----------
put logging to subfolder and include loglevel notice
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
Added Paths:
-----------
PyWireGate/trunk/log/
PyWireGate/trunk/log/__init__.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-04 21:54:13 UTC (rev 78)
+++ PyWireGate/trunk/WireGate.py 2010-11-04 22:27:12 UTC (rev 79)
@@ -22,12 +22,10 @@
import signal
import traceback
import daemon
-import logging
-import logging.handlers
+import log as logging
import ConfigParser
-
import datastore
class WireGate(daemon.Daemon):
@@ -64,11 +62,10 @@
'loglevel': 'info'
}
+ self.checkconfig("WireGate",defaultconfig)
## Remove this later
if "plugins" in self.config['WireGate']:
self.log("old Config",'critical')
-
- self.checkconfig("WireGate",defaultconfig)
@@ -227,7 +224,7 @@
maxlevel = self.config['WireGate']['loglevel']
if not filename:
filename = self.config['WireGate']['logfile']
- LEVELS = {'debug': logging.DEBUG,'info': logging.INFO,'warning': logging.WARNING,'error': logging.ERROR,'critical': logging.CRITICAL}
+ LEVELS = {'debug': logging.DEBUG,'info': logging.INFO,'notice': logging.NOTICE,'warning': logging.WARNING,'error': logging.ERROR,'critical': logging.CRITICAL}
level = LEVELS.get(maxlevel, logging.NOTSET)
# create logger
@@ -248,7 +245,7 @@
# create console handler and set level to debug
if self.REDIRECTIO:
#console = logging.StreamHandler()
- console = isoStreamHandler()
+ console = logging.isoStreamHandler()
console.setFormatter(formatter)
logger.addHandler(console)
return logger
@@ -265,7 +262,7 @@
elif severity=="info":
logger.info(msg)
elif severity=="notice":
- logger.info(msg)
+ logger.notice(msg)
elif severity=="warning":
logger.warning(msg)
elif severity=="warn":
@@ -287,13 +284,6 @@
os.umask(0)
-class isoStreamHandler(logging.StreamHandler):
- def emit(self,record):
- #record.message = record.message.decode('utf-8').encode('iso-8859-15')
- record.message = record.message.encode(sys.stderr.encoding)
- logging.StreamHandler.emit(self,record)
-
-
if __name__ == "__main__":
try:
import os
@@ -340,4 +330,3 @@
-
Added: PyWireGate/trunk/log/__init__.py
===================================================================
--- PyWireGate/trunk/log/__init__.py (rev 0)
+++ PyWireGate/trunk/log/__init__.py 2010-11-04 22:27:12 UTC (rev 79)
@@ -0,0 +1,68 @@
+# -*- coding: iso8859-1 -*-
+from logging import *
+import logging.handlers as handlers
+
+
+## redefine logging
+# Change the default levels to include NOTICE in
+# the proper order of priority
+FATAL = CRITICAL = 60
+ERROR = 50
+WARN = WARNING = 40
+NOTICE = 30
+
+# insert the levels with all the redefined values
+# anything below NOTICE we don't have to add back in, its
+# not getting redefined above with a new value
+addLevelName(NOTICE, 'NOTICE')
+addLevelName(WARNING, 'WARNING')
+addLevelName(WARN, 'WARN')
+addLevelName(ERROR, 'ERROR')
+addLevelName(FATAL, 'FATAL')
+addLevelName(CRITICAL, 'CRITICAL')
+
+# define a new logger function for notice
+# this is exactly like existing info, critical, debug...etc
+def Logger_notice(self, msg, *args, **kwargs):
+ """
+ Log 'msg % args' with severity 'NOTICE'.
+
+ To pass exception information, use the keyword argument exc_info
+with
+ a true value, e.g.
+
+ logger.notice("Houston, we have a %s", "major disaster", exc_info=1)
+ """
+ if self.manager.disable >= NOTICE:
+ return
+ if NOTICE >= self.getEffectiveLevel():
+ apply(self._log, (NOTICE, msg, args), kwargs)
+
+# make the notice function known in the system Logger class
+Logger.notice = Logger_notice
+
+# define a new root level notice function
+# this is exactly like existing info, critical, debug...etc
+def root_notice(msg, *args, **kwargs):
+ """
+ Log a message with severity 'NOTICE' on the root logger.
+ """
+ if len(root.handlers) == 0:
+ basicConfig()
+ apply(root.notice, (msg,)+args, kwargs)
+
+# make the notice root level function known
+notice = root_notice
+
+# add NOTICE to the priority map of all the levels
+handlers.SysLogHandler.priority_map['NOTICE'] = 'notice'
+
+
+class isoStreamHandler(StreamHandler):
+ def emit(self,record):
+ #record.message = record.message.decode('utf-8').encode('iso-8859-15')
+ record.message = record.message.encode(sys.stderr.encoding)
+ StreamHandler.emit(self,record)
+
+
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-05 10:25:19
|
Revision: 80
http://openautomation.svn.sourceforge.net/openautomation/?rev=80&view=rev
Author: nilss1
Date: 2010-11-05 10:25:12 +0000 (Fri, 05 Nov 2010)
Log Message:
-----------
fix loglevel notice, disable user switching until permissions fixed
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/log/__init__.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-04 22:27:12 UTC (rev 79)
+++ PyWireGate/trunk/WireGate.py 2010-11-05 10:25:12 UTC (rev 80)
@@ -22,8 +22,9 @@
import signal
import traceback
import daemon
-import log as logging
+import log
+
import ConfigParser
import datastore
@@ -142,20 +143,23 @@
startuser=pwd.getpwuid(os.getuid())
try:
runasuser=pwd.getpwnam(self.config['WireGate']['user'])
-
- ##Set Permissions
+ getpath = lambda x: "/".join(x.split("/")[:-1])
+
+ ##Set Permissions on
os.chown(self.config['WireGate']['pidfile'],runasuser[2],runasuser[3])
os.chown(self.config['WireGate']['logfile'],runasuser[2],runasuser[3])
os.chown(self.config['WireGate']['datastore'],runasuser[2],runasuser[3])
- os.setregid(runasuser[3],runasuser[3])
- os.setreuid(runasuser[2],runasuser[2])
+
+ ##removed until fixing permissions
+ #os.setregid(runasuser[3],runasuser[3])
+ #os.setreuid(runasuser[2],runasuser[2])
- self.log("Change User/Group from %s(%d) to %s(%d)" % (startuser[0],startuser[2],runasuser[0],runasuser[2]))
+ self.log("Change User/Group from %s(%d) to %s(%d) FIXME: disabled" % (startuser[0],startuser[2],runasuser[0],runasuser[2]))
except KeyError:
pass
- if os.getuid()==0:
- self.log("\n### Run as root is not recommend\n### set user in pywiregate.conf\n\n")
+ if os.getuid() == 0:
+ self.log("### Run as root is not recommend ### set user in pywiregate.conf",'warn')
## Mainloop only checking for Watchdog
while True:
@@ -224,16 +228,16 @@
maxlevel = self.config['WireGate']['loglevel']
if not filename:
filename = self.config['WireGate']['logfile']
- LEVELS = {'debug': logging.DEBUG,'info': logging.INFO,'notice': logging.NOTICE,'warning': logging.WARNING,'error': logging.ERROR,'critical': logging.CRITICAL}
- level = LEVELS.get(maxlevel, logging.NOTSET)
+ LEVELS = {'debug': log.logging.DEBUG,'info': log.logging.INFO,'notice': log.logging.NOTICE,'warning': log.logging.WARNING,'error': log.logging.ERROR,'critical': log.logging.CRITICAL}
+ level = LEVELS.get(maxlevel, log.logging.NOTSET)
# create logger
- formatter = logging.Formatter('%(asctime)s %(name)-12s: %(levelname)-8s %(message)s')
- logger = logging.getLogger(instance)
+ formatter = log.logging.Formatter('%(asctime)s %(name)-12s: %(levelname)-8s %(message)s')
+ logger = log.logging.getLogger(instance)
logger.setLevel(level)
if filename:
## python handle logrotating
- handler = logging.handlers.TimedRotatingFileHandler(filename,'MIDNIGHT',encoding='utf-8',backupCount=7)
+ handler = log.logging.handlers.TimedRotatingFileHandler(filename,'MIDNIGHT',encoding='utf-8',backupCount=7)
## Handler if logrotate handles Logfiles
#handler = logging.handlers.WatchedFileHandle(filename)
@@ -245,7 +249,7 @@
# create console handler and set level to debug
if self.REDIRECTIO:
#console = logging.StreamHandler()
- console = logging.isoStreamHandler()
+ console = log.isoStreamHandler()
console.setFormatter(formatter)
logger.addHandler(console)
return logger
@@ -257,24 +261,31 @@
except KeyError:
logger = self.LOGGER[instance] = self.createLog(instance)
pass
- if severity=="debug":
- logger.debug(msg)
- elif severity=="info":
- logger.info(msg)
- elif severity=="notice":
- logger.notice(msg)
- elif severity=="warning":
- logger.warning(msg)
- elif severity=="warn":
- logger.warning(msg)
- elif severity=="error":
- logger.error(msg)
- elif severity=="critical":
- logger.critical(msg)
- else:
- logger.info(msg)
+ try:
+ if severity=="debug":
+ logger.debug(msg)
+ elif severity=="info":
+ logger.info(msg)
+ elif severity=="notice":
+ logger.notice(msg)
+ elif severity=="warning":
+ logger.warning(msg)
+ elif severity=="warn":
+ #print "SEVERITY: %r " % logging._levelNames
+ logger.warning(msg)
+ elif severity=="error":
+ logger.error(msg)
+ elif severity=="critical":
+ logger.critical(msg)
+ else:
+ logger.info(msg)
+ except:
+ ## logging shouldnt break execution
+ #pass
+ raise
+
def debug(self,msg):
self.log(msg,"debug")
Modified: PyWireGate/trunk/log/__init__.py
===================================================================
--- PyWireGate/trunk/log/__init__.py 2010-11-04 22:27:12 UTC (rev 79)
+++ PyWireGate/trunk/log/__init__.py 2010-11-05 10:25:12 UTC (rev 80)
@@ -1,25 +1,29 @@
# -*- coding: iso8859-1 -*-
-from logging import *
-import logging.handlers as handlers
+## add notice as loglevel
+import logging
+import logging.handlers
+import sys
+
+logging._acquireLock()
## redefine logging
# Change the default levels to include NOTICE in
# the proper order of priority
-FATAL = CRITICAL = 60
-ERROR = 50
-WARN = WARNING = 40
-NOTICE = 30
+logging.FATAL = logging.CRITICAL = FATAL = CRITICAL = 60
+logging.ERROR = ERROR = 50
+logging.WARN = logging.WARNING = WARN = WARNING = 40
+logging.NOTICE = NOTICE = 30
# insert the levels with all the redefined values
# anything below NOTICE we don't have to add back in, its
# not getting redefined above with a new value
-addLevelName(NOTICE, 'NOTICE')
-addLevelName(WARNING, 'WARNING')
-addLevelName(WARN, 'WARN')
-addLevelName(ERROR, 'ERROR')
-addLevelName(FATAL, 'FATAL')
-addLevelName(CRITICAL, 'CRITICAL')
+logging.addLevelName(NOTICE, 'NOTICE')
+logging.addLevelName(WARNING, 'WARNING')
+logging.addLevelName(WARN, 'WARN')
+logging.addLevelName(ERROR, 'ERROR')
+logging.addLevelName(FATAL, 'FATAL')
+logging.addLevelName(CRITICAL, 'CRITICAL')
# define a new logger function for notice
# this is exactly like existing info, critical, debug...etc
@@ -39,7 +43,7 @@
apply(self._log, (NOTICE, msg, args), kwargs)
# make the notice function known in the system Logger class
-Logger.notice = Logger_notice
+logging.Logger.notice = Logger_notice
# define a new root level notice function
# this is exactly like existing info, critical, debug...etc
@@ -52,17 +56,18 @@
apply(root.notice, (msg,)+args, kwargs)
# make the notice root level function known
-notice = root_notice
+logging.notice = root_notice
# add NOTICE to the priority map of all the levels
-handlers.SysLogHandler.priority_map['NOTICE'] = 'notice'
+logging.handlers.SysLogHandler.priority_map['NOTICE'] = 'notice'
+logging._releaseLock()
-class isoStreamHandler(StreamHandler):
+class isoStreamHandler(logging.StreamHandler):
def emit(self,record):
#record.message = record.message.decode('utf-8').encode('iso-8859-15')
record.message = record.message.encode(sys.stderr.encoding)
- StreamHandler.emit(self,record)
+ logging.StreamHandler.emit(self,record)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-10 16:20:07
|
Revision: 101
http://openautomation.svn.sourceforge.net/openautomation/?rev=101&view=rev
Author: nilss1
Date: 2010-11-10 16:20:00 +0000 (Wed, 10 Nov 2010)
Log Message:
-----------
added sendcycle for datastore objects added sendcycleoption average
Modified Paths:
--------------
PyWireGate/trunk/datastore.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
PyWireGate/trunk/owfs_connector/sensors.ini
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-10 14:35:53 UTC (rev 100)
+++ PyWireGate/trunk/datastore.py 2010-11-10 16:20:00 UTC (rev 101)
@@ -33,6 +33,10 @@
self.log("DATASTORE starting up")
self.DBLOADED = False
self.dataobjects = {}
+
+ self.cycleThreadLock = threading.RLock()
+ self.cycleThreads = {}
+
self.locked = threading.RLock()
self.locked.acquire()
## Load JSON Database
@@ -141,8 +145,37 @@
dbfile.write(utfdb)
dbfile.close()
+
+ def attachThread(self,obj,threadObj=False):
+ try:
+ self.cycleThreadLock.acquire()
+ ## check only
+ if not threadObj:
+ return obj in self.cycleThreads
+ self.cycleThreads[obj] = threadObj
+ finally:
+ self.cycleThreadLock.release()
+
+ return self.cycleThreads[obj]
+
+
+ def removeThread(self,obj):
+ self.cycleThreadLock.acquire()
+ del self.cycleThreads[obj]
+ self.cycleThreadLock.release()
+
+
def shutdown(self):
+ self.cycleThreadLock.acquire()
+ for obj in self.cycleThreads:
+ try:
+ obj.cancel()
+ obj.join()
+ except:
+ pass
+ self.cycleThreadLock.release()
self.save()
+
def debug(self,msg):
####################################################
@@ -198,6 +231,8 @@
## connector specific vars
self.config = {}
+ self.cyclestore = []
+
## connected Logics, communication objects ... goes here
self.connected = []
@@ -213,6 +248,23 @@
self.write_mutex.release()
def setValue(self,val,send=False):
+ if 'sendcycle' in self.config:
+ if not self.WG.DATASTORE.attachThread(self):
+ self._parent.debug("start Cycle ID: %s" % self.id)
+ cycletime = float(self.config['sendcycle']) + self.lastupdate - time.time()
+ if cycletime < 0.0:
+ cycletime = 0
+ self.cyclestore.append(val)
+ _cyclethread = self.WG.DATASTORE.attachThread(self,threading.Timer(cycletime,self._cycle))
+ #_cyclethread.setDaemon(1)
+ _cyclethread.start()
+ else:
+ self._parent.debug("ignore Cycle ID: %s" % self.id)
+ self.cyclestore.append(val)
+ else:
+ self._real_setValue(val,send)
+
+ def _real_setValue(self,val,send):
try:
## get read lock
self.read_mutex.acquire()
@@ -241,4 +293,18 @@
## release lock
self.read_mutex.release()
-
+ def _cycle(self):
+ self._parent.debug("execute Cycle ID: %s" % self.id)
+ self.WG.DATASTORE.removeThread(self)
+ val = self.getValue()
+ if 'sendcycleoption' in self.config:
+ if self.config['sendcycleoption'] == 'average' and type(self.cyclestore[0]) in (int,float):
+ val = type(self.cyclestore[0])(0)
+ for i in self.cyclestore:
+ val += i
+ val = val / len(self.cyclestore)
+ self._parent.debug("Cycle ID: %s average: %f (%r)" % (self.id, val, self.cyclestore ))
+ self.cyclestore = []
+ else:
+ val = self.cyclestore.pop()
+ self._real_setValue(val,False)
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-10 14:35:53 UTC (rev 100)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-10 16:20:00 UTC (rev 101)
@@ -37,7 +37,7 @@
self.mutex = threading.RLock()
defaultconfig = {
- 'cycletime' : 60,
+ 'cycletime' : 15,
'server' : '127.0.0.1',
'port' : 4304
}
Modified: PyWireGate/trunk/owfs_connector/sensors.ini
===================================================================
--- PyWireGate/trunk/owfs_connector/sensors.ini 2010-11-10 14:35:53 UTC (rev 100)
+++ PyWireGate/trunk/owfs_connector/sensors.ini 2010-11-10 16:20:00 UTC (rev 101)
@@ -2,9 +2,11 @@
[DS18B20]
-cycle = 60
+cycle = 15
interfaces = temperature,power
config_temperature_resolution = 10
+config_temperature_sendcycle = 60
+config_temperature_sendcycleoption = average
[DS2438]
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-10 23:25:30
|
Revision: 102
http://openautomation.svn.sourceforge.net/openautomation/?rev=102&view=rev
Author: nilss1
Date: 2010-11-10 23:25:23 +0000 (Wed, 10 Nov 2010)
Log Message:
-----------
Fix locking on empty datastore.db
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/datastore.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-10 16:20:00 UTC (rev 101)
+++ PyWireGate/trunk/WireGate.py 2010-11-10 23:25:23 UTC (rev 102)
@@ -147,10 +147,12 @@
getpath = lambda x: "/".join(x.split("/")[:-1])
##Set Permissions on
- os.chown(self.config['WireGate']['pidfile'],runasuser[2],runasuser[3])
- os.chown(self.config['WireGate']['logfile'],runasuser[2],runasuser[3])
- os.chown(self.config['WireGate']['datastore'],runasuser[2],runasuser[3])
+ for sysfile in [self.config['WireGate']['pidfile'],self.config['WireGate']['logfile'],self.config['WireGate']['datastore']]:
+ if not os.path.exists(sysfile):
+ open(sysfile,'w').close()
+ os.chown(sysfile,runasuser[2],runasuser[3])
+
##removed until fixing permissions
#os.setregid(runasuser[3],runasuser[3])
#os.setreuid(runasuser[2],runasuser[2])
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-10 16:20:00 UTC (rev 101)
+++ PyWireGate/trunk/datastore.py 2010-11-10 23:25:23 UTC (rev 102)
@@ -111,16 +111,19 @@
self.dataobjects[name].config = obj['config']
self.dataobjects[name].connected = obj['connected']
self.debug("%d entries loaded in DATASTORE" % len(self.dataobjects))
- self.locked.release()
self.DBLOADED = True
except IOError:
## no DB File
pass
-
+ except ValueError:
+ ## empty DB File
+ self.DBLOADED = True
+ pass
except:
self.WG.errorlog()
## error
pass
+ self.locked.release()
def save(self):
@@ -167,10 +170,10 @@
def shutdown(self):
self.cycleThreadLock.acquire()
- for obj in self.cycleThreads:
+ for obj in self.cycleThreads.keys():
try:
- obj.cancel()
- obj.join()
+ self.cycleThreads[obj].cancel()
+ self.cycleThreads[obj].join()
except:
pass
self.cycleThreadLock.release()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-11 14:49:08
|
Revision: 108
http://openautomation.svn.sourceforge.net/openautomation/?rev=108&view=rev
Author: nilss1
Date: 2010-11-11 14:49:01 +0000 (Thu, 11 Nov 2010)
Log Message:
-----------
add scheduler support
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
Added Paths:
-----------
PyWireGate/trunk/scheduler.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-11 14:48:26 UTC (rev 107)
+++ PyWireGate/trunk/WireGate.py 2010-11-11 14:49:01 UTC (rev 108)
@@ -28,7 +28,9 @@
import ConfigParser
import datastore
+import scheduler
+
class WireGate(daemon.Daemon):
def __init__(self,REDIRECTIO=False):
self._parent = self
@@ -47,7 +49,6 @@
## Start the Datastore
self.DATASTORE = datastore.datastore(self)
-
## Start the Daemon
daemon.Daemon.__init__(self,self.config['WireGate']['pidfile'],REDIRECTIO)
@@ -138,6 +139,10 @@
except:
self.WG.errorlog(connector)
pass
+
+ ## Start the Sheduler
+ self.SCHEDULER = scheduler.scheduler(self)
+ self.SCHEDULER.start()
if os.getuid() == 0:
import pwd
@@ -186,6 +191,8 @@
#for dobj in self.DATASTORE.dataobjects.keys():
# print dobj+": "+str(self.DATASTORE.dataobjects[dobj].getValue())
self.log("### Shutdown WireGated ###")
+
+ self.SCHEDULER.shutdown()
for instance in self.connectors.keys():
try:
self.connectors[instance].shutdown()
Added: PyWireGate/trunk/scheduler.py
===================================================================
--- PyWireGate/trunk/scheduler.py (rev 0)
+++ PyWireGate/trunk/scheduler.py 2010-11-11 14:49:01 UTC (rev 108)
@@ -0,0 +1,88 @@
+# -*- coding: iso8859-1 -*-
+## -----------------------------------------------------
+## Cycler
+## -----------------------------------------------------
+## Copyright (c) 2010, knx-user-forum e.V, 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 time
+import sys
+from datetime import datetime
+try:
+ from apscheduler.scheduler import Scheduler as apscheduler
+except ImportError:
+ print >> sys.stderr, "apt-get install python-apscheduler"
+ sys.exit(1)
+
+
+
+class scheduler:
+ def __init__(self,parent):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ self.SCHEDULER = apscheduler()
+
+ def start(self):
+ self.load()
+ self.log("SCHEDULER starting up")
+ self.SCHEDULER.start()
+
+ def load(self):
+ schedules = filter(lambda x: x.startswith("SCHEDULER:"),self.WG.DATASTORE.dataobjects.keys())
+ for shed in schedules:
+ obj = self.WG.DATASTORE.dataobjects[shed]
+ if 'cron' in obj.config:
+ kwargs = {}
+ for uoption in obj.config['cron'].keys():
+ kwargs[str(uoption)] = str(obj.config['cron'][uoption])
+
+ print "Adding %s - %r" % (shed,obj)
+ setattr(obj.sendConnected.im_func,'__name__',"%s" % shed.encode('UTF-8'))
+ self.SCHEDULER.add_cron_job(self.WG.DATASTORE.dataobjects[shed].sendConnected,**kwargs)
+
+ def shutdown(self):
+ print self.SCHEDULER.dump_jobs()
+ self.SCHEDULER.shutdown()
+
+ def debug(self,msg):
+ self.log(msg,'debug')
+
+
+ ## Central logging
+ def log(self,msg,severity='info',instance=False):
+ self.WG.log(msg,severity,"scheduler")
+
+
+if __name__ == '__main__':
+ s = scheduler(False)
+ time.sleep(155)
+ s.shutdown()
+
+
+## "SHEDULER:cron_job-001": {
+## "config": {
+## "cron" : {
+## "day_of_week" : "mon-fri",
+## "hour" : "8",
+## "minute" : "30"
+## }
+##
+## },
+## "connected": [ "KNX:14/1/50" ],
+## "id": "cron_job-001",
+## "lastupdate": 0,
+## "name": "Test Cronjob weekday 8:30",
+## "value": 1
+## }
+
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-12 10:33:40
|
Revision: 112
http://openautomation.svn.sourceforge.net/openautomation/?rev=112&view=rev
Author: nilss1
Date: 2010-11-12 10:33:27 +0000 (Fri, 12 Nov 2010)
Log Message:
-----------
changed datastore cycles to apscheduler
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/datastore.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-12 08:59:20 UTC (rev 111)
+++ PyWireGate/trunk/WireGate.py 2010-11-12 10:33:27 UTC (rev 112)
@@ -23,8 +23,8 @@
import traceback
import daemon
import log
+import re
-
import ConfigParser
import datastore
@@ -41,7 +41,7 @@
self.REDIRECTIO = REDIRECTIO
## Get the path of this script
- self.scriptpath = str(datastore).split( )[3][1:-15]
+ self.scriptpath = re.findall("from \x27(.*)\x2F",str(datastore))[0]
self.readWireGateConfig()
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-12 08:59:20 UTC (rev 111)
+++ PyWireGate/trunk/datastore.py 2010-11-12 10:33:27 UTC (rev 112)
@@ -15,6 +15,14 @@
sys.exit(1)
+try:
+ from apscheduler.scheduler import Scheduler as apscheduler
+except ImportError:
+ print >> sys.stderr, "apt-get install python-apscheduler"
+ sys.exit(1)
+
+
+
class datastore:
"""
Datastore Instance
@@ -34,8 +42,8 @@
self.DBLOADED = False
self.dataobjects = {}
- self.cycleThreadLock = threading.RLock()
- self.cycleThreads = {}
+ self.CYCLER = apscheduler()
+ self.CYCLER.start()
self.locked = threading.RLock()
self.locked.acquire()
@@ -85,7 +93,7 @@
except KeyError:
## create a new one if it don't exist
self.dataobjects[id] = dataObject(self,id)
- if connector:
+ if hasattr(connector,'get_ds_defaults'):
self.dataobjects[id].config = connector.get_ds_defaults(id)
## return it
self.locked.release()
@@ -143,34 +151,8 @@
dbfile.close()
- def attachThread(self,obj,threadObj=False):
- try:
- self.cycleThreadLock.acquire()
- ## check only
- if not threadObj:
- return obj in self.cycleThreads
- self.cycleThreads[obj] = threadObj
- finally:
- self.cycleThreadLock.release()
-
- return self.cycleThreads[obj]
-
-
- def removeThread(self,obj):
- self.cycleThreadLock.acquire()
- del self.cycleThreads[obj]
- self.cycleThreadLock.release()
-
-
def shutdown(self):
- self.cycleThreadLock.acquire()
- for obj in self.cycleThreads.keys():
- try:
- self.cycleThreads[obj].cancel()
- self.cycleThreads[obj].join()
- except:
- pass
- self.cycleThreadLock.release()
+ self.CYCLER.shutdown()
self.save()
@@ -193,9 +175,7 @@
class dataObject:
def __init__(self,parent,id,name=False):
self._parent = parent
- if parent:
- self.WG = parent.WG
-
+ self.WG = parent.WG
## Threadlocking
self.write_mutex = threading.RLock()
self.read_mutex = threading.RLock()
@@ -220,7 +200,7 @@
## guess that non unicode is iso8859
self.name = name.decode("iso-8859-15")
## some defaults
- self.value = u""
+ self.value = None
self.lastupdate = 0
self.id = id
@@ -231,6 +211,7 @@
self.config = {}
self.cyclestore = []
+ self._cyclejob = False
## connected Logics, communication objects ... goes here
self.connected = []
@@ -249,17 +230,23 @@
self.write_mutex.release()
def setValue(self,val,send=False):
- if 'sendcycle' in self.config:
- if not self.WG.DATASTORE.attachThread(self):
+ if 'sendcycle' in self.config and self.value <> None:
+ if not self._cyclejob:
self._parent.debug("start Cycle ID: %s" % self.id)
cycletime = float(self.config['sendcycle']) + self.lastupdate - time.time()
if cycletime < 0.0:
cycletime = 0
+
+ ## add value to List
self.cyclestore.append(val)
- ## FIXME: create global cycling Thread like in cycle.py
- _cyclethread = self.WG.DATASTORE.attachThread(self,threading.Timer(cycletime,self._cycle))
- #_cyclethread.setDaemon(1)
- _cyclethread.start()
+
+ ##
+ repeat = 1
+ if 'always' in self.config['sendcycleoption'].split(","):
+ repeat = 0
+ self.write_mutex.acquire()
+ self._cyclejob = self.WG.DATASTORE.CYCLER.add_interval_job(self._cycle,seconds=cycletime,repeat=repeat)
+ self.write_mutex.release()
else:
self._parent.debug("ignore Cycle ID: %s" % self.id)
self.cyclestore.append(val)
@@ -293,9 +280,9 @@
try:
self.WG.DATASTORE.dataobjects[attached].setValue(val,True)
except:
- print "FAILED %s" % attached
- __import__('traceback').print_exc(file=__import__('sys').stdout)
- pass
+ self.WG.log("sendconnected failed for %s" % attached,'error')
+ #__import__('traceback').print_exc(file=__import__('sys').stdout)
+
def getValue(self):
@@ -308,17 +295,36 @@
self.read_mutex.release()
def _cycle(self):
- self._parent.debug("execute Cycle ID: %s" % self.id)
- self.WG.DATASTORE.removeThread(self)
- val = self.getValue()
+ self._parent.debug("----------------------execute Cycle ID: %s" % self.id)
+ val = None
+ cycleopts = []
if 'sendcycleoption' in self.config:
- if self.config['sendcycleoption'] == 'average' and type(self.cyclestore[0]) in (int,float):
- val = type(self.cyclestore[0])(0)
- for i in self.cyclestore:
- val += i
- val = val / len(self.cyclestore)
- self._parent.debug("Cycle ID: %s average: %f (%r)" % (self.id, val, self.cyclestore ))
- self.cyclestore = []
+ cycleopts = self.config['sendcycleoption'].split(",")
+ ## average only possible with data in cyclesotre else DivisionByZero
+ if len(self.cyclestore) > 0:
+ ## Average/Min/Max only possible with int and float
+ if type(self.value) in (int,float):
+ val = type(self.value)(0)
+ if 'average' in cycleopts:
+ for i in self.cyclestore:
+ val += i
+ val = val / len(self.cyclestore)
+ self._parent.debug("Cycle ID: %s average: %f (%r)" % (self.id, val, self.cyclestore ))
+ ## default use last
+ else:
+ val = self.cyclestore.pop()
+ else:
+ val = self.cyclestore.pop()
+
+ if 'always' in cycleopts:
+ if val == None:
+ val = self.getValue()
else:
- val = self.cyclestore.pop()
- self._real_setValue(val,False)
+ self.write_mutex.acquire()
+ self._cyclejob = False
+ self.write_mutex.release()
+
+ ## reset cyclestore
+ self.cyclestore = []
+ if val <> None:
+ self._real_setValue(val,False)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-18 19:15:57
|
Revision: 138
http://openautomation.svn.sourceforge.net/openautomation/?rev=138&view=rev
Author: nilss1
Date: 2010-11-18 19:15:50 +0000 (Thu, 18 Nov 2010)
Log Message:
-----------
Fixed some encoding issues
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/lirc_connector/LIRC_Connector.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-18 16:01:07 UTC (rev 137)
+++ PyWireGate/trunk/WireGate.py 2010-11-18 19:15:50 UTC (rev 138)
@@ -63,7 +63,7 @@
'logfile' : "%s/wiregated.log" % self.scriptpath,
'errorlog' : "%s/wiregated-error.log" % self.scriptpath,
'loglevel': 'info',
- 'defaultencoding': 'UTF-8'
+ 'defaultencoding': 'iso-8859-15'
}
self.checkconfig("WireGate",defaultconfig)
@@ -249,7 +249,7 @@
logger.setLevel(level)
if filename:
## python handle logrotating
- handler = log.logging.handlers.TimedRotatingFileHandler(filename,'MIDNIGHT',encoding=self.WG.config['WireGate']['defaultencoding'],backupCount=7)
+ handler = log.logging.handlers.TimedRotatingFileHandler(filename,'MIDNIGHT',encoding='UTF-8',backupCount=7)
## Handler if logrotate handles Logfiles
#handler = logging.handlers.WatchedFileHandle(filename)
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-18 16:01:07 UTC (rev 137)
+++ PyWireGate/trunk/datastore.py 2010-11-18 19:15:50 UTC (rev 138)
@@ -103,7 +103,7 @@
def load(self):
self.debug("load DATASTORE")
try:
- db = codecs.open(self.WG.config['WireGate']['datastore'],"r",encoding=self.WG.config['WireGate']['defaultencoding'])
+ db = codecs.open(self.WG.config['WireGate']['datastore'],"r",encoding='UTF-8')
loaddict = json.load(db)
db.close()
for name, obj in loaddict.items():
@@ -145,7 +145,7 @@
'config' : obj.config,
'connected' : obj.connected
}
- dbfile = codecs.open(self.WG.config['WireGate']['datastore'],"w",encoding=self.WG.config['WireGate']['defaultencoding'])
+ dbfile = codecs.open(self.WG.config['WireGate']['datastore'],"w",encoding='UTF-8')
utfdb = json.dumps(savedict,dbfile,ensure_ascii=False,sort_keys=True,indent=3)
dbfile.write(utfdb)
dbfile.close()
Modified: PyWireGate/trunk/lirc_connector/LIRC_Connector.py
===================================================================
--- PyWireGate/trunk/lirc_connector/LIRC_Connector.py 2010-11-18 16:01:07 UTC (rev 137)
+++ PyWireGate/trunk/lirc_connector/LIRC_Connector.py 2010-11-18 19:15:50 UTC (rev 138)
@@ -74,13 +74,13 @@
try:
raw, counter, button, channel = rawmsg.split()
## default "LIRC:channel_button
- id = "%s:%s_%s" % (self.instanceName,channel,button)
- self.WG.DATASTORE.update(id,counter)
+ id = u"%s:%s_%s" % (self.instanceName,channel,button)
+ self.WG.DATASTORE.update(id,int(counter,16))
- id = "%s:%s" % (self.instanceName,button)
+ id = u"%s:%s" % (self.instanceName,button)
## dont't create it "LIRC:Button"
if id in self.WG.DATASTORE.dataobjects:
- self.WG.DATASTORE.update(id,channel)
+ self.WG.DATASTORE.update(id,channel.decode(self.WG.config['WireGate']['defaultencoding']))
except ValueError:
self.debug("invalid Data %r" % rawmsg)
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ma...@us...> - 2011-01-09 20:15:05
|
Revision: 243
http://openautomation.svn.sourceforge.net/openautomation/?rev=243&view=rev
Author: mayerch
Date: 2011-01-09 20:14:55 +0000 (Sun, 09 Jan 2011)
Log Message:
-----------
Initial commit of the graphical logic editor
Added Paths:
-----------
PyWireGate/trunk/logic_editor/
PyWireGate/trunk/logic_editor/backendCommunication.js
PyWireGate/trunk/logic_editor/gle/
PyWireGate/trunk/logic_editor/gle/gle.block.js
PyWireGate/trunk/logic_editor/gle/gle.connection.js
PyWireGate/trunk/logic_editor/icon/
PyWireGate/trunk/logic_editor/icon/LICENCE.txt
PyWireGate/trunk/logic_editor/icon/align-horizontal-center.png
PyWireGate/trunk/logic_editor/icon/align-horizontal-left.png
PyWireGate/trunk/logic_editor/icon/align-horizontal-right.png
PyWireGate/trunk/logic_editor/icon/align-vertical-bottom.png
PyWireGate/trunk/logic_editor/icon/align-vertical-center.png
PyWireGate/trunk/logic_editor/icon/align-vertical-top.png
PyWireGate/trunk/logic_editor/icon/application-exit.png
PyWireGate/trunk/logic_editor/icon/checkbox.png
PyWireGate/trunk/logic_editor/icon/chronometer.png
PyWireGate/trunk/logic_editor/icon/code-block.png
PyWireGate/trunk/logic_editor/icon/code-class.png
PyWireGate/trunk/logic_editor/icon/code-context.png
PyWireGate/trunk/logic_editor/icon/code-function.png
PyWireGate/trunk/logic_editor/icon/code-typedef.png
PyWireGate/trunk/logic_editor/icon/code-variable.png
PyWireGate/trunk/logic_editor/icon/configure.png
PyWireGate/trunk/logic_editor/icon/dialog-cancel.png
PyWireGate/trunk/logic_editor/icon/dialog-close.png
PyWireGate/trunk/logic_editor/icon/dialog-ok-apply.png
PyWireGate/trunk/logic_editor/icon/dialog-ok.png
PyWireGate/trunk/logic_editor/icon/distribute-horizontal-center.png
PyWireGate/trunk/logic_editor/icon/distribute-vertical-center.png
PyWireGate/trunk/logic_editor/icon/document-close.png
PyWireGate/trunk/logic_editor/icon/document-new.png
PyWireGate/trunk/logic_editor/icon/document-save.png
PyWireGate/trunk/logic_editor/icon/edit-bomb.png
PyWireGate/trunk/logic_editor/icon/edit-cut.png
PyWireGate/trunk/logic_editor/icon/edit-delete.png
PyWireGate/trunk/logic_editor/icon/edit-find.png
PyWireGate/trunk/logic_editor/icon/edit-select.png
PyWireGate/trunk/logic_editor/icon/edit-undo.png
PyWireGate/trunk/logic_editor/icon/format-add-node.png
PyWireGate/trunk/logic_editor/icon/format-break-node.png
PyWireGate/trunk/logic_editor/icon/format-join-node.png
PyWireGate/trunk/logic_editor/icon/format-remove-node.png
PyWireGate/trunk/logic_editor/icon/help-about.png
PyWireGate/trunk/logic_editor/icon/help-hint.png
PyWireGate/trunk/logic_editor/icon/object-flip-horizontal.png
PyWireGate/trunk/logic_editor/icon/object-flip-vertical.png
PyWireGate/trunk/logic_editor/icon/object-rotate-left.png
PyWireGate/trunk/logic_editor/icon/object-rotate-right.png
PyWireGate/trunk/logic_editor/icon/process-stop.png
PyWireGate/trunk/logic_editor/icon/view-refresh.png
PyWireGate/trunk/logic_editor/icon/view-statistics.png
PyWireGate/trunk/logic_editor/icon/window-close.png
PyWireGate/trunk/logic_editor/icon/zoom-in.png
PyWireGate/trunk/logic_editor/icon/zoom-original.png
PyWireGate/trunk/logic_editor/icon/zoom-out.png
PyWireGate/trunk/logic_editor/index.html
PyWireGate/trunk/logic_editor/lib/
PyWireGate/trunk/logic_editor/lib/jquery-1.4.4.js
PyWireGate/trunk/logic_editor/lib/jquery-ui-1.8.7.custom.min.js
PyWireGate/trunk/logic_editor/lib/jquery.jstree.js
PyWireGate/trunk/logic_editor/lib/jquery.layout.js
PyWireGate/trunk/logic_editor/lib/jquery.svg.js
PyWireGate/trunk/logic_editor/lib/themes/
PyWireGate/trunk/logic_editor/lib/themes/classic/
PyWireGate/trunk/logic_editor/lib/themes/classic/d.png
PyWireGate/trunk/logic_editor/lib/themes/classic/dot_for_ie.gif
PyWireGate/trunk/logic_editor/lib/themes/classic/style.css
PyWireGate/trunk/logic_editor/lib/themes/classic/throbber.gif
PyWireGate/trunk/logic_editor/logicEditor.css
PyWireGate/trunk/logic_editor/logicEditor.js
Added: PyWireGate/trunk/logic_editor/backendCommunication.js
===================================================================
--- PyWireGate/trunk/logic_editor/backendCommunication.js (rev 0)
+++ PyWireGate/trunk/logic_editor/backendCommunication.js 2011-01-09 20:14:55 UTC (rev 243)
@@ -0,0 +1,99 @@
+ // Sollte das Backend dynamisch aus den verfuegbaren Bloecken generieren:
+ var libJSON = {
+ 'sourceLib': {
+ 'source1': {
+ 'width': 100,
+ 'height': 50,
+ 'rotation': 0,
+ 'flip': false,
+ 'color': [0.0, 0.0, 0.0],
+ 'background': [1.0, 1.0, 1.0],
+ 'inPorts': [],
+ 'outPorts': [
+ {
+ 'name': 'out1',
+ 'type': 'event'
+ }
+ ],
+ 'parameters':{}
+ },
+ 'source2': {
+ 'width': 100,
+ 'height': 100,
+ 'rotation': 0,
+ 'flip': false,
+ 'color': [0.0, 0.0, 1.0],
+ 'background': [1.0, 1.0, 0.5],
+ 'inPorts': [],
+ 'outPorts': [
+ {
+ 'name': 'out1',
+ 'type': 'event'
+ },
+ {
+ 'name': 'out2',
+ 'type': 'event'
+ }
+ ],
+ 'parameters':{}
+ }
+ },
+ 'sinkLib': {
+ 'sink1': {
+ 'width': 100,
+ 'height': 100,
+ 'rotation': 0,
+ 'flip': false,
+ 'color': [0.0, 0.0, 0.0],
+ 'background': [1.0, 1.0, 1.0],
+ 'inPorts': [
+ {
+ 'name': 'in',
+ 'type': 'event'
+ }
+ ],
+ 'outPorts': [],
+ 'parameters':{}
+ }
+ },
+ 'mathLib': {
+ 'gain': {
+ 'width': 100,
+ 'height': 100,
+ 'rotation': 0,
+ 'flip': false,
+ 'color': [0.0, 0.0, 0.0],
+ 'background': [1.0, 1.0, 1.0],
+ 'mask': [
+ { 'type': 'move', 'x': 0.999, 'y': 0.5 }, // just to show what's possible
+ { 'type': 'line', 'x': 0 , 'y': 0.999 },
+ { 'type': 'line', 'x': 0 , 'y': 0 }
+ // auto close
+ ],
+ 'maskOptions': {
+ 'showLabel': false
+ },
+ 'inPorts': [
+ {
+ 'name': 'in',
+ 'type': 'event'
+ }
+ ],
+ 'outPorts': [
+ {
+ 'name': 'out',
+ 'type': 'event'
+ }
+ ],
+ 'parameters': [
+ {
+ 'name': 'gain',
+ 'type': 'float'
+ }
+ ]
+ }
+ }
+};
+
+// Die Struktur mit der feritgen Logik
+var logicJSON = {};
Added: PyWireGate/trunk/logic_editor/gle/gle.block.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.block.js (rev 0)
+++ PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-01-09 20:14:55 UTC (rev 243)
@@ -0,0 +1,366 @@
+/* gle.block.js (c) 2011 by Christian Mayer [CometVisu at ChristianMayer dot de]
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/**
+ * The element that stores all informations and methods about one block
+ */
+
+/**
+ * The block constructor.
+ * type: the block (proto)type in JSON notation
+ * svg: the link to the SVG canvas
+ * interactive: event handlers will be added, set to false to create picture only
+ */
+function Block( type, svg, interactive )
+{
+ // setup the private "constants"
+ var that = this;
+ var inset = 3; // how far should the handle stick in
+ var outset = 3; // how far should the handle stick out
+
+ // setup the private variables
+ var x = type.x || 0;
+ var y = type.y || 0;
+ var width = type.width || 100;
+ var height = type.height || 100;
+ var rotation = type.rotation || 0;
+ var flip = type.flip || false;
+ var mask = type.mask || undefined;
+ var maskOptions = type.maskOptions || { showLabel: true };
+ var color = type.color || [0.0, 0.0, 0.0];
+ var background = type.background || [1.0, 1.0, 1.0];
+ var inPorts = type.inPorts || [];
+ var outPorts = type.outPorts || [];
+ var parameters = type.parameters || {};
+
+ var canvas = svg || $('#editor').svg('get');
+ var addEvent = interactive !== undefined ? interactive : true;
+ var g = undefined; // link to the representation of the block in the DOM
+
+ // the private functions
+
+ // (re)draw itself on the canvas
+ function draw()
+ {
+ var classList = 'block';
+ if( g )
+ {
+ classList = g.getAttribute('class');
+ g.parentNode.removeChild( g ); // delete the old representation
+ }
+ g = canvas.group( {'transform':'translate(' + x + ',' + y + ')', 'class':classList} );
+
+ // helper function to scale relative positioning
+ function scaleRelPos( value, absValue )
+ {
+ if( value >= 1.0 ) return value; // it is already absolutely scaled
+ if( value < 0 ) return absValue + value; // absolutely from right
+ return absValue * value; // relative scaled
+ }
+
+ var style = {
+ fill: colorByArray( background ),
+ stroke: colorByArray( color ),
+ 'stroke-width': 1
+ };
+
+ // Draw the body
+ var body = canvas.group( g, {'transform':'translate(6,1)'} );
+ if( mask )
+ {
+ var path = canvas.createPath();
+ for( var i in mask )
+ {
+ var obj = mask[i];
+ var sx = scaleRelPos( obj.x, width );
+ var sy = scaleRelPos( obj.y, height );
+ switch( obj.type )
+ {
+ case 'move':
+ path.move( sx, sy );
+ break;
+
+ case 'line':
+ path.line( sx, sy );
+ break;
+ }
+ }
+ canvas.path( body, path.close(), style );
+ } else {
+ canvas.rect( body, 0, 0, width, height, style );
+ }
+
+ // Draw the inports
+ var inPortsLength = inPorts.length;
+ $.each( inPorts, function(i){
+ var y = 1 + height * (0.5 + i)/inPortsLength;
+ if( 'connection' in this )
+ canvas.line( g, 0, y, 6, y, style );
+ else
+ editorConnectionPointCreate( canvas.polyline( g, [[1, y-4],[6, y],[1, y+4]] ), 'inPort', i );
+ if( maskOptions.showLabel )
+ canvas.text( g, 10, y, this.name, {'dominant-baseline':'middle','text-anchor':'start'} );
+ });
+
+ // Draw the outports
+ var outPortsLength = outPorts.length;
+ $.each( outPorts, function(i){
+ var y = 1 + height * (0.5 + i)/outPortsLength;
+ if( 'connection' in this )
+ canvas.line( g, width+6, y, width+12, y, style );
+ else
+ editorConnectionPointCreate( canvas.polyline( g, [[width+6, y-4],[width+11, y],[width+6, y+4]] ), 'outPort', i );
+ if( maskOptions.showLabel )
+ canvas.text( g, width, y, this.name, {'dominant-baseline':'middle','text-anchor':'end'} );
+ });
+
+ // shotcut
+ function editorDrag( obj, handle )
+ {
+ if( addEvent )
+ {
+ $(handle).bind( 'mousedown', {obj:obj}, editorDragMouseDown );
+ }
+ }
+
+ editorDrag( g, g ); // move
+ // Draw the handles
+ editorDrag( g, canvas.rect( g, 5-outset , -outset , 1+inset+outset, 1+inset+outset, {class:'nw-resize'} ) );
+ editorDrag( g, canvas.rect( g, 6+width-inset, -outset , 1+inset+outset, 1+inset+outset, {class:'ne-resize'} ) );
+ editorDrag( g, canvas.rect( g, 5-outset , height+1-inset, 1+inset+outset, 1+inset+outset, {class:'sw-resize'} ) );
+ editorDrag( g, canvas.rect( g, 6+width-inset, height+1-inset, 1+inset+outset, 1+inset+outset, {class:'se-resize'} ) );
+
+ }
+
+ // relocate itself on the canvas
+ function relocate()
+ {
+ if( !g ) return draw(); // nothing to relocate...
+ g.setAttribute( 'transform', 'translate(' + x + ',' + y + ')' );
+ }
+
+ function editorDragMouseDown( event )
+ {
+ console.log( 'eDMD', event );
+ var classList = this.getAttribute('class').split(' ');
+ console.log( 'eDMD', classList );
+ var type = 'move';
+ for( var i = 0; i < classList.length; i++ )
+ if( classList[i] != '' && classList[i] != 'selected' && classList[i] != 'block' ) type = classList[i];
+ if( $.inArray('selected', classList) == -1 && type=='move' ) editorSelect( this );
+
+ var parameter = {
+ type : type,
+ origx : x,
+ origy : y,
+ origw : width,
+ origh : height,
+ startx : event.pageX,
+ starty : event.pageY
+ };
+
+ $(document).bind( 'mousemove', parameter, editorDragMouseMove );
+ $(document).bind( 'mouseup' , editorDragMouseUp );
+ return false;
+ }
+
+ function editorDragMouseMove( event )
+ {
+ var ed = event.data;
+ switch( event.data.type )
+ {
+ case 'move':
+ x = ed.origx - ed.startx + event.pageX;
+ y = ed.origy - ed.starty + event.pageY;
+ break;
+ case 'nw-resize':
+ x = ed.origx - ed.startx + event.pageX;
+ width = ed.origw + ed.startx - event.pageX;
+ y = ed.origy - ed.starty + event.pageY;
+ height = ed.origh + ed.starty - event.pageY;
+ break;
+ case 'ne-resize':
+ width = ed.origw - ed.startx + event.pageX;
+ y = ed.origy - ed.starty + event.pageY;
+ height = ed.origh + ed.starty - event.pageY;
+ break;
+ case 'se-resize':
+ height = ed.origh - ed.starty + event.pageY;
+ width = ed.origw - ed.startx + event.pageX;
+ break;
+ case 'sw-resize':
+ height = ed.origh - ed.starty + event.pageY;
+ x = ed.origx - ed.startx + event.pageX;
+ width = ed.origw + ed.startx - event.pageX;
+ break;
+ }
+ if( 'move' == event.data.type )
+ {
+ relocate(); // shortcut
+ } else {
+ if( width < 10 ) width = 10; // sanity...
+ if( height < 10 ) height = 10; // sanity...
+ draw();
+ }
+
+ $.each( inPorts, function(i){
+ if( 'connection' in this )
+ {
+ this.connection.lastMove( that.inPortPos( i ), true );
+ }
+ });
+
+ $.each( outPorts, function(i){
+ if( 'connection' in this )
+ {
+ this.connection.firstMove( that.outPortPos( i ) );
+ }
+ });
+ }
+
+ function editorDragMouseUp( event )
+ {
+ $(document).unbind( 'mousemove', editorDragMouseMove );
+ $(document).unbind( 'mouseup' , editorDragMouseUp );
+ }
+
+ // the public (privileged) methods:
+ this.getWidth = function() { return width ; }
+ this.setWidth = function( _width ) { width = _width ; draw(); }
+ this.getHeight = function() { return height; }
+ this.setHeight = function( _height ) { height = _height; draw(); }
+ this.getX = function() { return x ; }
+ this.setX = function( _x ) { x = _x ; draw(); }
+ this.getY = function() { return y ; }
+ this.setY = function( _y ) { y = _y ; draw(); }
+ this.getColor = function() { return color ; }
+ this.setColor = function( _color ) { color = _color ; draw(); }
+ this.setConnection = function( portType, portNumber, connection )
+ {
+ if( 'inPort' == portType )
+ inPorts [ portNumber ].connection = connection;
+ else
+ outPorts[ portNumber ].connection = connection;
+ draw();
+ }
+ this.inPortPos = function( number )
+ {
+ return [ x , y + 1 + height * (0.5 + number) / inPorts.length ];
+ }
+ this.outPortPos = function( number )
+ {
+ return [ x + width + 10, y + 1 + height * (0.5 + number) / outPorts.length ];
+ }
+
+ // Dump this Block in JSON notation to serialize it
+ this.getJSON = function()
+ {
+ return {
+ x : x ,
+ y : y ,
+ width : width ,
+ height : height ,
+ rotation : rotation ,
+ flip : flip ,
+ mask : mask ,
+ maskOptions : maskOptions ,
+ color : color ,
+ background : background ,
+ inPorts : inPorts ,
+ outPorts : outPorts ,
+ parameters : parameters
+ };
+ }
+
+ // finally draw itself:
+ draw();
+
+ ////////////////
+ function editorConnectionPointCreate( obj, portType, portNumber )
+ {
+ $(obj).bind( 'mousedown', {
+ portType :portType,
+ portNumber:portNumber
+ }, editorConnectionPointDrag );
+ $(obj).bind( 'mouseover', {
+ portType :portType,
+ portNumber:portNumber
+ }, editorConnectionPointOverPort );
+ $(obj).bind( 'mouseout', {
+ }, editorConnectionPointOverPortOut );
+ }
+
+ function editorConnectionPointDrag( event )
+ {
+ console.log( 'Block: eCPD', event );
+ var pn = event.data.portNumber;
+ var pt = event.data.portType;
+ var c = new Connection({
+ origin : that,
+ originPortNumber: pn,
+ paths : [{path:[that.outPortPos( pn )]}]
+ });
+ that.setConnection( pt, pn,c );
+ ///???
+ var parameter = {con:c};
+
+ $(document).bind( 'mousemove', parameter, editorConnectionPointMouseMove );
+ $(document).bind( 'mouseup' , parameter, editorConnectionPointMouseUp );
+
+ return false;
+ }
+
+ function editorConnectionPointMouseMove( event )
+ {
+ //console.log( event.data.con );
+ var x = event.pageX - $('#editor')[0].offsetLeft;
+ var y = event.pageY - $('#editor')[0].offsetTop;
+ event.data.con.lastMove( [x, y] );
+ }
+
+ function editorConnectionPointMouseUp( event )
+ {
+ console.log( 'eCPMU' );
+ $(document).unbind( 'mousemove', editorConnectionPointMouseMove );
+ $(document).unbind( 'mouseup' , editorConnectionPointMouseUp );
+ var target = event.data.con.lastTarget();
+ if( target )
+ {
+ target.block.setConnection( target.type, target.number, event.data.con );
+ }
+ }
+
+ function editorConnectionPointOverPort( event )
+ {
+ console.log( 'eCPOP', event.data.portType );
+ overPort = {
+ block : that,
+ type : event.data.portType,
+ number: event.data.portNumber
+ };
+ }
+
+ function editorConnectionPointOverPortOut( event )
+ {
+ console.log( 'eCPOPO' );
+ overPort = false;
+ }
+}
+Block.prototype = {
+ globalTestFunc: function(){ alert('test'+ this.getWidth()); }
+};
+
Added: PyWireGate/trunk/logic_editor/gle/gle.connection.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.connection.js (rev 0)
+++ PyWireGate/trunk/logic_editor/gle/gle.connection.js 2011-01-09 20:14:55 UTC (rev 243)
@@ -0,0 +1,126 @@
+/* gle.connection.js (c) 2011 by Christian Mayer [CometVisu at ChristianMayer dot de]
+ *
+ * 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, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ */
+
+/**
+ * The element that stores all informations and methods about one connection
+ */
+
+/**
+ * The connection constructor.
+ * type: the block (proto)type in JSON notation
+ * svg: the link to the SVG canvas
+ * interactive: event handlers will be added, set to false to create picture only
+ */
+function Connection( JSON, svg, interactive )
+{
+ // setup the private "constants"
+ var that = this;
+ var inset = 3; // how far should the handle stick in
+ var outset = 3; // how far should the handle stick out
+
+ // setup the private variables
+ var origin = JSON.origin || undefined;
+ var paths = JSON.paths || [];
+ var branch = 0; // the current branch to edit
+ var lastFixed = 0; // the last fixed position
+
+ var canvas = svg || $('#editor').svg('get');
+ var addEvent = interactive !== undefined ? interactive : true;
+ var g = undefined; // link to the representation of the block in the DOM
+
+ // the private functions
+
+ // (re)draw itself on the canvas
+ function draw()
+ {
+ var classList = 'connection';
+ if( g )
+ {
+ classList = g.getAttribute('class');
+ g.parentNode.removeChild( g ); // delete the old representation
+ }
+ g = canvas.group( { 'class':classList } );
+
+ var parameter = {
+ class: classList,
+ stroke: colorByArray( origin.getColor() ),
+ 'stroke-width': 1,
+ 'marker-end' : 'url(#ArrowEnd)',
+ fill: 'none'
+ };
+ for( var i in paths )
+ {
+ if( paths[i].target == undefined || origin == undefined )
+ parameter['stroke-dasharray'] = '1,3';
+ else
+ parameter['stroke-dasharray'] = 'none';
+ var x = canvas.polyline( g, paths[i].path, parameter );
+ }
+ }
+
+ this.firstMove = function( pos )
+ {
+ if( paths[0].path[0][1] == paths[0].path[1][1] ) // keep horizontal line
+ {
+ paths[0].path[0] = pos;
+ paths[0].path[1][1] = pos[1];
+ } else {
+ paths[0].path[0] = pos;
+ }
+ draw();
+ }
+
+ this.lastMove = function( pos, force )
+ {
+ while( paths[branch].path.length > lastFixed+1 )
+ paths[branch].path.pop();
+ var start = paths[branch].path[ paths[branch].path.length - 1 ];
+ var op = overPort;
+ if( !force && op && op.type == 'inPort' )
+ {
+ pos = op.block.inPortPos( op.number );
+ }
+ if( force || (op && op.type == 'inPort') )
+ {
+ paths[branch].target = op;
+ if( Math.abs( start[1] - pos[1] ) > 1.0 )
+ paths[branch].path.push( [ (pos[0]+start[0])/2, start[1] ] );
+ paths[branch].path.push( [ (pos[0]+start[0])/2, pos[1] ] );
+ } else {
+ paths[branch].target = undefined;
+ if( Math.abs( start[1] - pos[1] ) > 1.0 )
+ paths[branch].path.push( [ pos[0], start[1] ] );
+ }
+ paths[branch].path.push( pos );
+ draw();
+ }
+
+ this.lastTarget = function()
+ {
+ return paths[branch].target;
+ }
+
+ // Dump this Block in JSON notation to serialize it
+ this.getJSON = function()
+ {
+ return {
+ origin : origin,
+ paths : paths
+ };
+ }
+}
+
Added: PyWireGate/trunk/logic_editor/icon/LICENCE.txt
===================================================================
--- PyWireGate/trunk/logic_editor/icon/LICENCE.txt (rev 0)
+++ PyWireGate/trunk/logic_editor/icon/LICENCE.txt 2011-01-09 20:14:55 UTC (rev 243)
@@ -0,0 +1 @@
+Oxygen icon theme is dual licensed. You may copy it under the Creative Common Attribution-ShareAlike 3.0 License or the GNU Library General Public License.
\ No newline at end of file
Added: PyWireGate/trunk/logic_editor/icon/align-horizontal-center.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-horizontal-center.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/align-horizontal-left.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-horizontal-left.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/align-horizontal-right.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-horizontal-right.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/align-vertical-bottom.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-vertical-bottom.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/align-vertical-center.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-vertical-center.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/align-vertical-top.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/align-vertical-top.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/application-exit.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/application-exit.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/checkbox.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/checkbox.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/chronometer.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/chronometer.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-block.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-block.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-class.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-class.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-context.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-context.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-function.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-function.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-typedef.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-typedef.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/code-variable.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/code-variable.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/configure.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/configure.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/dialog-cancel.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/dialog-cancel.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-stream
Added: PyWireGate/trunk/logic_editor/icon/dialog-close.png
===================================================================
(Binary files differ)
Property changes on: PyWireGate/trunk/logic_editor/icon/dialog-close.png
___________________________________________________________________
Added: svn:mime-type
+ application/octet-s...
[truncated message content] |
|
From: <ma...@us...> - 2011-05-09 17:11:05
|
Revision: 326
http://openautomation.svn.sourceforge.net/openautomation/?rev=326&view=rev
Author: mayerch
Date: 2011-05-09 17:10:59 +0000 (Mon, 09 May 2011)
Log Message:
-----------
Renamed "log" block to "display" - it'll show the current value in the editor in future and won't log to the screen anymore
Modified Paths:
--------------
PyWireGate/trunk/logic_server/LogicLibrary.py
PyWireGate/trunk/logik.json
PyWireGate/trunk/logik2.json
Modified: PyWireGate/trunk/logic_server/LogicLibrary.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-09 17:09:29 UTC (rev 325)
+++ PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-09 17:10:59 UTC (rev 326)
@@ -27,7 +27,7 @@
_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"
+ _name = "display"
_inPorts = [ 'in' ]
_outPorts = []
_parameters = []
Modified: PyWireGate/trunk/logik.json
===================================================================
--- PyWireGate/trunk/logik.json 2011-05-09 17:09:29 UTC (rev 325)
+++ PyWireGate/trunk/logik.json 2011-05-09 17:10:59 UTC (rev 326)
@@ -10,14 +10,14 @@
"x": 150, "y": 50, "width": 50, "height": 50,
"parameters": { "gain": 5.0 }
},
- "Log1": {
- "type": "log",
- "x": 250, "y": 150, "width": 50, "height": 50,
+ "Display1": {
+ "type": "display",
+ "x": 250, "y": 150, "width": 150, "height": 50,
"parameters": {}
},
- "Log2": {
- "type": "log",
- "x": 250, "y": 50, "width": 50, "height": 50,
+ "Display2": {
+ "type": "display",
+ "x": 250, "y": 50, "width": 150, "height": 50,
"parameters": {}
},
"Integral1": {
@@ -35,19 +35,19 @@
"x": 150, "y": 350, "width": 50, "height": 50,
"parameters": { "gain": -1.0 }
},
- "Log3": {
- "type": "log",
- "x": 250, "y": 250, "width": 50, "height": 50,
+ "Display3": {
+ "type": "display",
+ "x": 250, "y": 250, "width": 150, "height": 50,
"parameters": {}
}
},
"signals": [
- [ "Const1" , 0, "Log1" , 0, {} ],
+ [ "Const1" , 0, "Display1" , 0, {} ],
[ "Const1" , 0, "Gain1" , 0, {} ],
- [ "Gain1" , 0, "Log2" , 0, {} ],
+ [ "Gain1" , 0, "Display2" , 0, {} ],
[ "Integral1", 0, "Integral2" , 0, {} ],
[ "Integral2", 0, "Gain2" , 0, {} ],
[ "Gain2" , 0, "Integral1" , 0, {} ],
- [ "Integral2", 0, "Log3" , 0, {} ]
+ [ "Integral2", 0, "Display3" , 0, {} ]
]
}
\ No newline at end of file
Modified: PyWireGate/trunk/logik2.json
===================================================================
--- PyWireGate/trunk/logik2.json 2011-05-09 17:09:29 UTC (rev 325)
+++ PyWireGate/trunk/logik2.json 2011-05-09 17:10:59 UTC (rev 326)
@@ -15,9 +15,9 @@
"x": 150, "y": 200, "width": 50, "height": 50,
"parameters": {}
},
- "Log22": {
- "type": "log",
- "x": 350, "y": 300, "width": 50, "height": 50,
+ "Display22": {
+ "type": "display",
+ "x": 350, "y": 300, "width": 150, "height": 50,
"parameters": {}
},
"Integral2": {
@@ -38,6 +38,6 @@
[ "Memory1" , 0, "Sum1" , 1, {} ],
[ "Integral2", 0, "Gain2" , 0, {} ],
[ "Gain2" , 0, "Gain1" , 0, {} ],
- [ "Integral2", 0, "Log22" , 0, {} ]
+ [ "Integral2", 0, "Display22" , 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.
|
|
From: <ma...@us...> - 2011-05-10 15:13:59
|
Revision: 327
http://openautomation.svn.sourceforge.net/openautomation/?rev=327&view=rev
Author: mayerch
Date: 2011-05-10 15:13:52 +0000 (Tue, 10 May 2011)
Log Message:
-----------
- [PyWireGate]: Update the logic editor to have a CometVisu Protocol compatible connection between backend and frontend
- [CometVisu client]: add real session handling to the client
Modified Paths:
--------------
CometVisu/trunk/visu/lib/cometvisu-client.js
PyWireGate/trunk/logic_editor/LogicEditor.py
PyWireGate/trunk/logic_editor/backendCommunication.js
PyWireGate/trunk/logic_editor/index.html
PyWireGate/trunk/logic_editor/logicEditor.js
PyWireGate/trunk/logic_server/LogicServer.py
Property Changed:
----------------
PyWireGate/trunk/logic_editor/lib/
Modified: CometVisu/trunk/visu/lib/cometvisu-client.js
===================================================================
--- CometVisu/trunk/visu/lib/cometvisu-client.js 2011-05-09 17:10:59 UTC (rev 326)
+++ CometVisu/trunk/visu/lib/cometvisu-client.js 2011-05-10 15:13:52 UTC (rev 327)
@@ -106,7 +106,7 @@
{
var requestAddresses = (this.addresses.length)?'a=' + this.addresses.join( '&a=' ):'';
var requestFilters = (this.filters.length )?'f=' + this.filters.join( '&f=' ):'';
- return requestAddresses + ( (this.addresses.length&&this.filters.length)?'&':'' ) + requestFilters;
+ return 's=' + this.session + '&' + requestAddresses + ( (this.addresses.length&&this.filters.length)?'&':'' ) + requestFilters;
}
/**
Modified: PyWireGate/trunk/logic_editor/LogicEditor.py
===================================================================
--- PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-09 17:10:59 UTC (rev 326)
+++ PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-10 15:13:52 UTC (rev 327)
@@ -25,6 +25,7 @@
import SocketServer
import threading
+import Queue
import re
from logic_server import LogicLibrary
@@ -119,21 +120,40 @@
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()
+
+
+ # Create the CometVisu interface for the internal variables
+ elif self.path.startswith('/live/l'):
# FIXME: BIG, Big, big memory and CPU leak! A created Queue must be
# removed later, or the LogicServer will continue to fill it, even if
# no page will be listening anymore!
l = LOGIC.createQueue( None, None, None ) # get everything!
+ contentType="text/plain"
+ f.write('{"v":"0.0.1","s":"live%s"}' % l)
+ elif self.path.startswith('/live/r'):
+ try:
+ l = int( re.findall('s=live(\d*)', self.path )[0] )
+ except IndexError:
+ return # FIXME - return sensible error message
+ self.send_response(200)
+ #self.send_header("Content-type", 'text/plain')
+ self.send_header("Content-type", 'application/json')
+ self.send_header("Access-Control-Allow-Origin", "*")
+ self.end_headers()
+ self.wfile.write( '{"d":[' )
+ sep = ''
+ getWait = True # wait for the first result, but not any longer
while True:
#self.wfile.write( "new line\n" )
- m = l.get()
- self.wfile.write( "|%s|%s|%s|%s|\n" % m )
- self.wfile.flush()
- #time.sleep( 1.0 )
+ try:
+ m = LOGIC.queues[l][3].get( getWait )
+ getWait = False
+ self.wfile.write( sep )
+ self.wfile.write( '{"task":"%s","module":"%s","block":"%s","value":%s}' % m )
+ sep = ','
+ except Queue.Empty:
+ self.wfile.write( '],"i":0}')
+ return # Queue is empty, end connection
else:
self.path = "%s%s" % ( thisPath, self.path )
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
Modified: PyWireGate/trunk/logic_editor/backendCommunication.js
===================================================================
--- PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-09 17:10:59 UTC (rev 326)
+++ PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-10 15:13:52 UTC (rev 327)
@@ -278,3 +278,30 @@
logics['logik2'] = data;
updateKnownLogics('logik2');
});
+
+// tweak backend communication, should also be done on demand
+XXX = new CometVisu( '/live/' );
+XXX.update = function( json )
+{
+ console.log( json );
+}
+XXX.subscribe( ['ALL'] );
+
+$(window).unload(function() {
+ XXX.stop();
+});
+/*XXX=$.ajax({
+ url: '/live',
+ cache: false,
+ success: function(html){
+ console.log('success', html);
+ }
+});*/
+/*
+ var ws = new websocket("/live");
+ ws.onopen = function() {
+ ws.send("Hello Mr. Server!");
+ };
+ ws.onmessage = function (e) { console.log(e.data); };
+ ws.onclose = function() { console.log('close'); };
+ */
\ No newline at end of file
Modified: PyWireGate/trunk/logic_editor/index.html
===================================================================
--- PyWireGate/trunk/logic_editor/index.html 2011-05-09 17:10:59 UTC (rev 326)
+++ PyWireGate/trunk/logic_editor/index.html 2011-05-10 15:13:52 UTC (rev 327)
@@ -13,6 +13,7 @@
<script type="text/javascript" src="lib/jquery.layout.js"></script>
<script type="text/javascript" src="lib/jquery.jstree.js"></script>
<script type="text/javascript" src="lib/jquery.hotkeys.js"></script>
+ <script type="text/javascript" src="lib/cometvisu-client.js"></script>
<script type="text/javascript" src="backendCommunication.js"></script>
<script type="text/javascript" src="gle/gle.block.js"></script>
<script type="text/javascript" src="gle/gle.connection.js"></script>
Property changes on: PyWireGate/trunk/logic_editor/lib
___________________________________________________________________
Added: svn:externals
+ ^/CometVisu/trunk/visu/lib/cometvisu-client.js cometvisu-client.js
Modified: PyWireGate/trunk/logic_editor/logicEditor.js
===================================================================
--- PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-09 17:10:59 UTC (rev 326)
+++ PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-10 15:13:52 UTC (rev 327)
@@ -163,16 +163,19 @@
function displayLogic( logicName )
{
- console.log( '"'+logicName+'"' );
logic = logics[ logicName ];
+
+ // clean canvas first
+ $('#editor g').remove();
+
+ // draw all the blocks
$.each( logic.blocks, function( name, def ){
var newBlock = $.extend( true, {}, libJSON['MainLib'][ def.type ], def, {'name':name} );
drawElement( undefined, newBlock, true );
});
- console.log( blockRegistry );
+
+ // and connect them
$.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];
Modified: PyWireGate/trunk/logic_server/LogicServer.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicServer.py 2011-05-09 17:10:59 UTC (rev 326)
+++ PyWireGate/trunk/logic_server/LogicServer.py 2011-05-10 15:13:52 UTC (rev 327)
@@ -21,6 +21,7 @@
import TaskManager
import Queue
import time
+import threading
## Load logik.json
#exec LogicImportJSON.get( 'logik.json' )
@@ -46,7 +47,10 @@
CONNECTOR_NAME = 'Logic Server'
CONNECTOR_VERSION = 0.1
CONNECTOR_LOGNAME = 'logic_server'
- queues = []
+ queues = {}
+ lastQueueId = -1
+ write_mutex = threading.RLock()
+
def __init__(self,parent, instanceName):
self._parent = parent
self.WG = parent.WG
@@ -75,14 +79,15 @@
self.Logik2 = LogikClass
t = TaskManager.TaskManager(self)
- t.addInterval( 'Interval 1 - 75 ms Task', 0.075 )
- t.addInterval( 'Interval 2 - 10 ms Task', 0.010 )
+ t.addInterval( 'Interval 1 - 75 ms Task', 0.75 )
+ t.addInterval( 'Interval 2 - 10 ms Task', 0.910 )
t.addTask( 'Interval 1 - 75 ms Task', 'Logik1', self.Logik1 )
t.addTask( 'Interval 2 - 10 ms Task', 'Logik2', self.Logik2 )
t.start()
while True:
for m in iter( t.getMessage, None ):
for q in self.queues:
+ q = self.queues[q]
if (q[0] == None or q[0] == m[0]) and (q[1] == None or q[1] == m[1]):
for b in m[2]:
if q[2] == None or q[2] == b:
@@ -90,6 +95,11 @@
time.sleep( 0.1 )
def createQueue(self, taskFilter, logicFilter, blockFilter):
- q = Queue.Queue()
- self.queues.append( (taskFilter, logicFilter, blockFilter, q) )
- return q
\ No newline at end of file
+ try:
+ self.write_mutex.acquire()
+ self.lastQueueId += 1
+ thisQueueId = self.lastQueueId # extra variable to be save when the lock is released
+ self.queues[ thisQueueId ] = (taskFilter, logicFilter, blockFilter, Queue.Queue())
+ finally:
+ self.write_mutex.release()
+ return thisQueueId
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ma...@us...> - 2011-05-10 17:49:55
|
Revision: 328
http://openautomation.svn.sourceforge.net/openautomation/?rev=328&view=rev
Author: mayerch
Date: 2011-05-10 17:49:48 +0000 (Tue, 10 May 2011)
Log Message:
-----------
Finish the display the current values of the LogicServer in the current LogicEditor view
(The solution is quite hackish and has to be cleaned up later)
Modified Paths:
--------------
PyWireGate/trunk/logic_editor/LogicEditor.py
PyWireGate/trunk/logic_editor/backendCommunication.js
PyWireGate/trunk/logic_editor/gle/gle.block.js
PyWireGate/trunk/logic_editor/logicEditor.js
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/logik.json
PyWireGate/trunk/logik2.json
Modified: PyWireGate/trunk/logic_editor/LogicEditor.py
===================================================================
--- PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-10 17:49:48 UTC (rev 328)
@@ -81,11 +81,12 @@
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":{' )
+ thisLib = 'MainLib' # FIXME iterate over it...
+ f.write( '{"%s":{' % thisLib )
blockPrefix = ''
- for blockName in lib:
+ for blockName in lib[ thisLib ]:
f.write( '%s"%s":{"name":"%s",' % (blockPrefix, blockName, blockName) )
- block = lib[ blockName ]
+ block = lib[ thisLib ][ blockName ]
f.write( '"inPorts":[' )
prefix = ''
@@ -111,6 +112,21 @@
prefix = ','
f.write( '],' )
+ f.write( '"maskOptions":{' )
+ prefix = ''
+ maskOptions = block.maskOptions()
+ for maskOption in maskOptions:
+ option = maskOptions[maskOption]
+ if type(option) in (int, float):
+ f.write( '%s"%s":%s' % (prefix, maskOption, option) )
+ elif type(option) == bool:
+ option = 'true' if option else 'false'
+ f.write( '%s"%s":%s' % (prefix, maskOption, option) )
+ else:
+ f.write( '%s"%s":"%s"' % (prefix, maskOption, option) )
+ 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( '}' )
Modified: PyWireGate/trunk/logic_editor/backendCommunication.js
===================================================================
--- PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-10 17:49:48 UTC (rev 328)
@@ -280,28 +280,22 @@
});
// tweak backend communication, should also be done on demand
-XXX = new CometVisu( '/live/' );
-XXX.update = function( json )
+live = new CometVisu( '/live/' );
+liveUpdateCalls = [];
+live.update = function( json )
{
- console.log( json );
+ $.each( liveUpdateCalls, function(){
+ for( var i = json.length-1; i >= 0; i-- )
+ {
+ if( json[i].block == this[0] )
+ {
+ this[1]( json[i].value );
+ }
+ }
+ });
}
-XXX.subscribe( ['ALL'] );
+live.subscribe( ['ALL'] );
$(window).unload(function() {
- XXX.stop();
-});
-/*XXX=$.ajax({
- url: '/live',
- cache: false,
- success: function(html){
- console.log('success', html);
- }
-});*/
-/*
- var ws = new websocket("/live");
- ws.onopen = function() {
- ws.send("Hello Mr. Server!");
- };
- ws.onmessage = function (e) { console.log(e.data); };
- ws.onclose = function() { console.log('close'); };
- */
\ No newline at end of file
+ live.stop();
+});
\ No newline at end of file
Modified: PyWireGate/trunk/logic_editor/gle/gle.block.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-10 17:49:48 UTC (rev 328)
@@ -21,11 +21,11 @@
/**
* The block constructor.
- * type: the block (proto)type in JSON notation
+ * prototype: the block (proto)type in JSON notation
* svg: the link to the SVG canvas
* interactive: event handlers will be added, set to false to create picture only
*/
-function Block( type, svg, interactive )
+function Block( prototype, svg, interactive )
{
// setup the private "constants"
var that = this;
@@ -33,21 +33,22 @@
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;
- var height = type.height || 100;
- var rotation = type.rotation || 0;
- var flip = type.flip || false;
- var mask = type.mask || undefined;
- var maskOptions = type.maskOptions || { showLabel: true };
- var color = type.color || [0.0, 0.0, 0.0];
- var background = type.background || [1.0, 1.0, 1.0];
- var inPorts = type.inPorts || [];
- var outPorts = type.outPorts || [];
- var parameters = type.parameters || {};
- var parameter = type.parameter || createParameter( type.parameters );
+ var type = prototype.type || 'UNKNOWN';
+ var name = prototype.name || 'UNKNOWN';
+ var x = prototype.x || 0;
+ var y = prototype.y || 0;
+ var width = prototype.width || 100;
+ var height = prototype.height || 100;
+ var rotation = prototype.rotation || 0;
+ var flip = prototype.flip || false;
+ var mask = prototype.mask || undefined;
+ var maskOptions = prototype.maskOptions || { showLabel: true };
+ var color = prototype.color || [0.0, 0.0, 0.0];
+ var background = prototype.background || [1.0, 1.0, 1.0];
+ var inPorts = prototype.inPorts || [];
+ var outPorts = prototype.outPorts || [];
+ var parameters = prototype.parameters || {};
+ var parameter = prototype.parameter || createParameter( prototype.parameters );
var postParameterUpdateFn = maskOptions.postParameterUpdate;
var canvas = svg || $('#editor').svg('get');
@@ -221,6 +222,18 @@
}
+ // private function for live updating of param = {'text-anchor':'start'}a display
+ this._updateValue = function( value )
+ {
+ if( g )
+ {
+ //console.log( '_updateValue', value.toString(), g, 10, height/2 );
+ $( g ).find( '.valueString').remove();
+ param = {'text-anchor':'start','class':'valueString'};
+ canvas.text( g, 10, height/2, value.toString(), param );
+ }
+ }
+
function createParameter( structure )
{
var retVal = {};
@@ -339,6 +352,8 @@
}
// the public (privileged) methods:
+ this.getType = function() { return type ; }
+ this.getName = function() { return name ; }
this.getWidth = function() { return width ; }
this.setWidth = function( _width ) { width = _width ; draw(); }
this.getHeight = function() { return height; }
Modified: PyWireGate/trunk/logic_editor/logicEditor.js
===================================================================
--- PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-10 17:49:48 UTC (rev 328)
@@ -137,6 +137,7 @@
$.each( this, function( element ){
var entry = $('<div class="libEntry"></div>');
var obj = this;
+ obj.type = libName + '/' + element;
var width = this.width+20;
var height = this.height+35;
entry.prepend(
@@ -165,12 +166,13 @@
{
logic = logics[ logicName ];
- // clean canvas first
- $('#editor g').remove();
+ $('#editor g').remove(); // clean canvas first
+ blockRegistry = {}; // and then the block registry
// draw all the blocks
$.each( logic.blocks, function( name, def ){
- var newBlock = $.extend( true, {}, libJSON['MainLib'][ def.type ], def, {'name':name} );
+ var type = def.type.split('/');
+ var newBlock = $.extend( true, {}, libJSON[ type[0] ][ type[1] ], def, {'name':name} );
drawElement( undefined, newBlock, true );
});
@@ -197,6 +199,14 @@
if( addEvent === undefined ) addEvent = true;
var b = new Block( element, svg, addEvent );
if( addEvent ) blockRegistry[ element.name ] = b;
+ // FIXME this should become more generalized
+ if( 'MainLib/display' == element.type ) // make display interactive
+ {
+ liveUpdateCalls.push( [
+ b.getName(),
+ b._updateValue
+ ] );
+ }
}
function colorByArray( a )
Modified: PyWireGate/trunk/logic_server/LogicImportJSON.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicImportJSON.py 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_server/LogicImportJSON.py 2011-05-10 17:49:48 UTC (rev 328)
@@ -36,7 +36,8 @@
stateupdate = '' # the string containing the update of the states
for name, attribute in loaddict['blocks'].iteritems():
- block = lib[ attribute['type'] ]
+ blockType = attribute['type'].split('/')
+ block = lib[ blockType[0] ][ blockType[1] ]
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,
@@ -49,7 +50,8 @@
for signal in loaddict['signals']:
b = loaddict['blocks']
- if lib[ loaddict['blocks'][ signal[0] ]['type'] ].outPortNumberHasState( signal[1] ):
+ blockType = loaddict['blocks'][ signal[0] ]['type'].split('/')
+ if lib[ blockType[0] ][ blockType[1] ].outPortNumberHasState( 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] } )
@@ -59,12 +61,14 @@
for instruction in intructionOrder:
if not instruction in loaddict['blocks']:
continue # ignore the virtual state nodes
- libBlock = lib[ loaddict['blocks'][ instruction ]['type'] ]
+ blockType = loaddict['blocks'][ instruction ]['type'].split('/')
+ libBlock = lib[ blockType[0] ][ blockType[1] ]
ins = []
for i in range(len(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'] ].outPortNumberHasState( e[2]['ports'][0] ):
+ blockType = loaddict['blocks'][ e[2]['start'] ]['type'].split('/')
+ if lib[ blockType[0] ][ blockType[1] ].outPortNumberHasState( 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] ) )
Modified: PyWireGate/trunk/logic_server/LogicLibrary.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-10 17:49:48 UTC (rev 328)
@@ -24,14 +24,16 @@
_outPorts = [ ( 'out', 'const' ) ]
_parameters = [ 'value' ]
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': True }
_codingInstructions = lambda s, n, i, o, p: ( "%s = %s" % ( o[0], p[0] ), "%s_next = %s" % ( o[0], p[0] ) )
-class LogBlock( LogicModule.LogicModule ):
+class DisplayBlock( LogicModule.LogicModule ):
_name = "display"
_inPorts = [ 'in' ]
_outPorts = []
_parameters = []
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': False }
#_codingInstructions = lambda s, n, i, o, p: ( None, "print __time,',','\"%%s\"' %% globalVariables['__name'],',','%s',',',%s" % ( n, i[0]) )
_codingInstructions = lambda s, n, i, o, p: ( None, "inspector['%s'] = %s" % ( n, i[0]) )
@@ -41,6 +43,7 @@
_outPorts = [ ( 'out', 'signal' ) ]
_parameters = [ 'gain' ]
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': True }
_codingInstructions = lambda s, n, i, o, p: ( None, "%s = %s * %s" % ( o[0], p[0], i[0] ) )
class SumBlock( LogicModule.LogicModule ):
@@ -49,6 +52,7 @@
_outPorts = [ ( 'out', 'signal' ) ]
_parameters = []
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': True }
_codingInstructions = lambda s, n, i, o, p: ( None, "%s = %s + %s" % ( o[0], i[0], i[1] ) )
class MemoryBlock( LogicModule.LogicModule ):
@@ -57,6 +61,7 @@
_outPorts = [ ( 'out', 'state' ) ]
_parameters = [ 'inital_value' ]
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': True }
_codingInstructions = lambda s, n, i, o, p: ( "%s = %s" % (o[0], p[0]), "%s_next = %s" % ( o[0], i[0] ) )
class IntegralBlock( LogicModule.LogicModule ):
@@ -65,23 +70,25 @@
_outPorts = [ ( 'out', 'state' ) ]
_parameters = [ 'initial_value' ]
_drawingInstructions = ""
+ _maskOptions = { 'showLabel': True }
_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 = {}
+ _db = {'MainLib':{}}
def __init__( self ):
self.addBlock( ConstBlock )
- self.addBlock( LogBlock )
+ self.addBlock( DisplayBlock )
self.addBlock( GainBlock )
self.addBlock( SumBlock )
self.addBlock( MemoryBlock )
self.addBlock( IntegralBlock )
def addBlock( self, block ):
+ l = 'MainLib'
b = block()
- self._db[ b.name() ] = b
+ self._db[ l ][ b.name() ] = b
def getLibrary( self ):
return self._db
Modified: PyWireGate/trunk/logic_server/LogicModule.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicModule.py 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_server/LogicModule.py 2011-05-10 17:49:48 UTC (rev 328)
@@ -33,6 +33,9 @@
def drawingIntructions( self ):
return self._drawingInstructions
+ def maskOptions( self ):
+ return self._maskOptions
+
def codingIntructions( self, name, ins, outs, params ):
return self._codingInstructions( name, ins, outs, params )
Modified: PyWireGate/trunk/logic_server/LogicServer.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicServer.py 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logic_server/LogicServer.py 2011-05-10 17:49:48 UTC (rev 328)
@@ -79,8 +79,8 @@
self.Logik2 = LogikClass
t = TaskManager.TaskManager(self)
- t.addInterval( 'Interval 1 - 75 ms Task', 0.75 )
- t.addInterval( 'Interval 2 - 10 ms Task', 0.910 )
+ t.addInterval( 'Interval 1 - 75 ms Task', 0.075 )
+ t.addInterval( 'Interval 2 - 10 ms Task', 0.010 )
t.addTask( 'Interval 1 - 75 ms Task', 'Logik1', self.Logik1 )
t.addTask( 'Interval 2 - 10 ms Task', 'Logik2', self.Logik2 )
t.start()
Modified: PyWireGate/trunk/logik.json
===================================================================
--- PyWireGate/trunk/logik.json 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logik.json 2011-05-10 17:49:48 UTC (rev 328)
@@ -1,42 +1,42 @@
{
"blocks": {
"Const1": {
- "type": "const",
+ "type": "MainLib/const",
"x": 50, "y": 50, "width": 50, "height": 50,
"parameters": { "value": 1.0 }
},
"Gain1": {
- "type": "gain",
+ "type": "MainLib/gain",
"x": 150, "y": 50, "width": 50, "height": 50,
"parameters": { "gain": 5.0 }
},
"Display1": {
- "type": "display",
+ "type": "MainLib/display",
"x": 250, "y": 150, "width": 150, "height": 50,
"parameters": {}
},
"Display2": {
- "type": "display",
+ "type": "MainLib/display",
"x": 250, "y": 50, "width": 150, "height": 50,
"parameters": {}
},
"Integral1": {
- "type": "integral",
+ "type": "MainLib/integral",
"x": 50, "y": 250, "width": 50, "height": 50,
"parameters": { "inital_value": 1.0 }
},
"Integral2": {
- "type": "integral",
+ "type": "MainLib/integral",
"x": 150, "y": 250, "width": 50, "height": 50,
"parameters": { "inital_value": 0.0 }
},
"Gain2": {
- "type": "gain",
+ "type": "MainLib/gain",
"x": 150, "y": 350, "width": 50, "height": 50,
"parameters": { "gain": -1.0 }
},
"Display3": {
- "type": "display",
+ "type": "MainLib/display",
"x": 250, "y": 250, "width": 150, "height": 50,
"parameters": {}
}
Modified: PyWireGate/trunk/logik2.json
===================================================================
--- PyWireGate/trunk/logik2.json 2011-05-10 15:13:52 UTC (rev 327)
+++ PyWireGate/trunk/logik2.json 2011-05-10 17:49:48 UTC (rev 328)
@@ -1,32 +1,32 @@
{
"blocks": {
"Memory1": {
- "type": "memory",
+ "type": "MainLib/memory",
"x": 150, "y": 300, "width": 50, "height": 50,
"parameters": { "initial_value": 1.0 }
},
"Gain1": {
- "type": "gain",
+ "type": "MainLib/gain",
"x": 50, "y": 150, "width": 50, "height": 50,
"parameters": { "gain": "__dt" }
},
"Sum1": {
- "type": "sum",
+ "type": "MainLib/sum",
"x": 150, "y": 200, "width": 50, "height": 50,
"parameters": {}
},
"Display22": {
- "type": "display",
+ "type": "MainLib/display",
"x": 350, "y": 300, "width": 150, "height": 50,
"parameters": {}
},
"Integral2": {
- "type": "integral",
+ "type": "MainLib/integral",
"x": 250, "y": 300, "width": 50, "height": 50,
"parameters": { "inital_value": 0.0 }
},
"Gain2": {
- "type": "gain",
+ "type": "MainLib/gain",
"x": 150, "y": 50, "width": 50, "height": 50,
"parameters": { "gain": -1.0 }
}
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ma...@us...> - 2011-05-10 21:04:16
|
Revision: 329
http://openautomation.svn.sourceforge.net/openautomation/?rev=329&view=rev
Author: mayerch
Date: 2011-05-10 21:04:09 +0000 (Tue, 10 May 2011)
Log Message:
-----------
Added feature to allow to flip blocks
Modified Paths:
--------------
PyWireGate/trunk/logic_editor/LogicEditor.py
PyWireGate/trunk/logic_editor/gle/gle.block.js
PyWireGate/trunk/logic_server/LogicModule.py
PyWireGate/trunk/logik.json
PyWireGate/trunk/logik2.json
Modified: PyWireGate/trunk/logic_editor/LogicEditor.py
===================================================================
--- PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-10 17:49:48 UTC (rev 328)
+++ PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-10 21:04:09 UTC (rev 329)
@@ -112,18 +112,14 @@
prefix = ','
f.write( '],' )
+ f.write( '"flip":%s,' % self._convert2JSON( block.flip() ) )
+
f.write( '"maskOptions":{' )
prefix = ''
maskOptions = block.maskOptions()
for maskOption in maskOptions:
option = maskOptions[maskOption]
- if type(option) in (int, float):
- f.write( '%s"%s":%s' % (prefix, maskOption, option) )
- elif type(option) == bool:
- option = 'true' if option else 'false'
- f.write( '%s"%s":%s' % (prefix, maskOption, option) )
- else:
- f.write( '%s"%s":"%s"' % (prefix, maskOption, option) )
+ f.write( '%s"%s":%s' % (prefix, maskOption, self._convert2JSON( option ) ) )
prefix = ','
f.write( '},' )
@@ -189,4 +185,15 @@
def copyfile(self, source, outputfile):
shutil.copyfileobj(source, outputfile)
-
\ No newline at end of file
+
+ # create a JSON representation out of the Python value
+ def _convert2JSON( self, value ):
+ if type( value ) in ( int, float ):
+ return str( value )
+ elif type( value ) == bool:
+ if value:
+ return 'true'
+ else:
+ return 'false'
+ else:
+ return '"%s"' % value
Modified: PyWireGate/trunk/logic_editor/gle/gle.block.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-10 17:49:48 UTC (rev 328)
+++ PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-10 21:04:09 UTC (rev 329)
@@ -176,7 +176,7 @@
}
if( maskOptions.showLabel )
canvas.text( g, 1.2*p[0].x-0.2*p[1].x, 1.2*p[0].y-0.2*p[1].y, this.name,
- {'dominant-baseline':'middle','text-anchor':'start'} );
+ {'dominant-baseline':'middle','text-anchor': flip?'end':'start'} );
});
// Draw the outports
@@ -198,7 +198,7 @@
}
if( maskOptions.showLabel )
canvas.text( g, 1.2*p[0].x-0.2*p[1].x, 1.2*p[0].y-0.2*p[1].y, this.name,
- {'dominant-baseline':'middle','text-anchor':'end'} );
+ {'dominant-baseline':'middle','text-anchor': flip?'start':'end'} );
});
// Draw the label
@@ -379,15 +379,15 @@
return maskOptions.inPortPos( number, that, maskOptions, parameter );
} else
return [
- { x: x , y: y + height * (0.5 + number) / inPorts.length },
- { x: x - 20, y: y + height * (0.5 + number) / inPorts.length }
+ { x: flip ? x + width : x , y: y + height * (0.5 + number) / inPorts.length },
+ { x: flip ? x + width + 20 : x - 20, y: y + height * (0.5 + number) / inPorts.length }
];
}
this.outPortPos = function( number )
{
return [
- { x: x + width , y: y + height * (0.5 + number) / outPorts.length },
- { x: x + width + 20, y: y + height * (0.5 + number) / outPorts.length }
+ { x: flip ? x : x + width , y: y + height * (0.5 + number) / outPorts.length },
+ { x: flip ? x - 20 : x + width + 20, y: y + height * (0.5 + number) / outPorts.length }
];
}
Modified: PyWireGate/trunk/logic_server/LogicModule.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicModule.py 2011-05-10 17:49:48 UTC (rev 328)
+++ PyWireGate/trunk/logic_server/LogicModule.py 2011-05-10 21:04:09 UTC (rev 329)
@@ -18,6 +18,10 @@
class LogicModule:
"""The base class for a generic logic module"""
+
+ # default values
+ _flip = False
+
def name( self ):
return self._name
@@ -30,6 +34,9 @@
def parameters( self ):
return self._parameters
+ def flip( self ):
+ return self._flip
+
def drawingIntructions( self ):
return self._drawingInstructions
Modified: PyWireGate/trunk/logik.json
===================================================================
--- PyWireGate/trunk/logik.json 2011-05-10 17:49:48 UTC (rev 328)
+++ PyWireGate/trunk/logik.json 2011-05-10 21:04:09 UTC (rev 329)
@@ -33,7 +33,8 @@
"Gain2": {
"type": "MainLib/gain",
"x": 150, "y": 350, "width": 50, "height": 50,
- "parameters": { "gain": -1.0 }
+ "parameters": { "gain": -1.0 },
+ "flip" : true
},
"Display3": {
"type": "MainLib/display",
Modified: PyWireGate/trunk/logik2.json
===================================================================
--- PyWireGate/trunk/logik2.json 2011-05-10 17:49:48 UTC (rev 328)
+++ PyWireGate/trunk/logik2.json 2011-05-10 21:04:09 UTC (rev 329)
@@ -2,8 +2,9 @@
"blocks": {
"Memory1": {
"type": "MainLib/memory",
- "x": 150, "y": 300, "width": 50, "height": 50,
- "parameters": { "initial_value": 1.0 }
+ "x": 150, "y": 250, "width": 50, "height": 50,
+ "parameters": { "initial_value": 1.0 },
+ "flip" : true
},
"Gain1": {
"type": "MainLib/gain",
@@ -12,27 +13,28 @@
},
"Sum1": {
"type": "MainLib/sum",
- "x": 150, "y": 200, "width": 50, "height": 50,
+ "x": 150, "y": 150, "width": 50, "height": 50,
"parameters": {}
},
"Display22": {
"type": "MainLib/display",
- "x": 350, "y": 300, "width": 150, "height": 50,
+ "x": 350, "y": 150, "width": 150, "height": 50,
"parameters": {}
},
"Integral2": {
"type": "MainLib/integral",
- "x": 250, "y": 300, "width": 50, "height": 50,
+ "x": 250, "y": 150, "width": 50, "height": 50,
"parameters": { "inital_value": 0.0 }
},
"Gain2": {
"type": "MainLib/gain",
"x": 150, "y": 50, "width": 50, "height": 50,
- "parameters": { "gain": -1.0 }
+ "parameters": { "gain": -1.0 },
+ "flip" : true
}
},
"signals": [
- [ "Memory1" , 0, "Integral2" , 0, {} ],
+ [ "Sum1" , 0, "Integral2" , 0, {} ],
[ "Gain1" , 0, "Sum1" , 0, {} ],
[ "Sum1" , 0, "Memory1" , 0, {} ],
[ "Memory1" , 0, "Sum1" , 1, {} ],
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ma...@us...> - 2011-05-11 16:04:22
|
Revision: 330
http://openautomation.svn.sourceforge.net/openautomation/?rev=330&view=rev
Author: mayerch
Date: 2011-05-11 16:04:16 +0000 (Wed, 11 May 2011)
Log Message:
-----------
Added a scope block the Logic Editor (this was quite hackish and has to be cleaned up later)
NOTE: The performance in the browser (expecially FireFox) can get real bad, there's a big optimisation needed
Modified Paths:
--------------
PyWireGate/trunk/logic_editor/backendCommunication.js
PyWireGate/trunk/logic_editor/gle/gle.block.js
PyWireGate/trunk/logic_editor/logicEditor.js
PyWireGate/trunk/logic_server/LogicLibrary.py
PyWireGate/trunk/logik.json
PyWireGate/trunk/logik2.json
Modified: PyWireGate/trunk/logic_editor/backendCommunication.js
===================================================================
--- PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logic_editor/backendCommunication.js 2011-05-11 16:04:16 UTC (rev 330)
@@ -282,14 +282,16 @@
// tweak backend communication, should also be done on demand
live = new CometVisu( '/live/' );
liveUpdateCalls = [];
+count = 10;
live.update = function( json )
{
$.each( liveUpdateCalls, function(){
- for( var i = json.length-1; i >= 0; i-- )
+ for( var i = 0; i < json.length; i++ )
{
- if( json[i].block == this[0] )
+ var last = i == json.length-1;
+ if( json[i].block == this[0] && ( last || !this[1] ) )
{
- this[1]( json[i].value );
+ this[2]( json[i].value );
}
}
});
Modified: PyWireGate/trunk/logic_editor/gle/gle.block.js
===================================================================
--- PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logic_editor/gle/gle.block.js 2011-05-11 16:04:16 UTC (rev 330)
@@ -50,6 +50,8 @@
var parameters = prototype.parameters || {};
var parameter = prototype.parameter || createParameter( prototype.parameters );
var postParameterUpdateFn = maskOptions.postParameterUpdate;
+ var cElem = false; // if that block has a <canvas> it's cached here
+ var cCtx = false; // as well as it's context
var canvas = svg || $('#editor').svg('get');
var addEvent = interactive !== undefined ? interactive : true;
@@ -85,8 +87,28 @@
// Draw the body
//var body = canvas.group( g, {'transform':'translate(6,1)'} );
var body = canvas.group( g );
- if( mask )
+ if( 'MainLib/scope' == type )
{
+ gB = body;
+ var xhtmlNS = 'http://www.w3.org/1999/xhtml',
+ svgNS = 'http://www.w3.org/2000/svg',
+ xlinkNS = 'http://www.w3.org/1999/xlink';
+ var f = document.createElementNS( svgNS, 'foreignObject' );
+ f.x.baseVal.value = 0;
+ f.y.baseVal.value = 0;
+ f.width.baseVal.value = width;
+ f.height.baseVal.value = height;
+ var c = document.createElementNS( xhtmlNS, 'canvas' );
+ c.width = width;
+ c.height = height;
+ var foObj = body.appendChild(f);
+ cElem = foObj.appendChild(c);
+ cCtx = cElem.getContext( '2d' );
+ cCtx.fillStyle="rgba(0,0,0,255)";
+ cCtx.fillRect(0,0,width,height);
+ }
+ else if( mask )
+ {
var path = canvas.createPath();
for( var i in mask )
{
@@ -223,14 +245,30 @@
}
// private function for live updating of param = {'text-anchor':'start'}a display
+ var scopeLastX = -1;
this._updateValue = function( value )
{
- if( g )
+ if( 'MainLib/scope' == type )
{
- //console.log( '_updateValue', value.toString(), g, 10, height/2 );
- $( g ).find( '.valueString').remove();
- param = {'text-anchor':'start','class':'valueString'};
- canvas.text( g, 10, height/2, value.toString(), param );
+ scopeLastX = ( scopeLastX + 1 ) % width;
+ var thisY = Math.round( (2.0+value)*(height/4.0) );
+ var imgdA = cCtx.getImageData( 0, 0, width-1, height );
+ cCtx.putImageData( imgdA, 1, 0 );
+ var imgdI = cCtx.createImageData( 1, height );
+ var pix = imgdI.data;
+ for( var i = 0; i < height; i++ )
+ pix[ 4 * i + 3 ] = 255; // set alpha
+ pix[ 4 * thisY + 0 ] = 0 ; // red
+ pix[ 4 * thisY + 1 ] = 255; // green
+ pix[ 4 * thisY + 2 ] = 0 ; // blue
+ cCtx.putImageData( imgdI, 0, 0 );
+ } else {
+ if( g )
+ {
+ $( g ).find( '.valueString').remove();
+ param = {'text-anchor':'start','class':'valueString'};
+ canvas.text( g, 10, height/2, value.toString(), param );
+ }
}
}
Modified: PyWireGate/trunk/logic_editor/logicEditor.js
===================================================================
--- PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logic_editor/logicEditor.js 2011-05-11 16:04:16 UTC (rev 330)
@@ -200,10 +200,11 @@
var b = new Block( element, svg, addEvent );
if( addEvent ) blockRegistry[ element.name ] = b;
// FIXME this should become more generalized
- if( 'MainLib/display' == element.type ) // make display interactive
+ if( 'MainLib/display' == element.type || 'MainLib/scope' == element.type ) // make display and scope interactive
{
liveUpdateCalls.push( [
b.getName(),
+ 'MainLib/display' == element.type,
b._updateValue
] );
}
Modified: PyWireGate/trunk/logic_server/LogicLibrary.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logic_server/LogicLibrary.py 2011-05-11 16:04:16 UTC (rev 330)
@@ -37,6 +37,16 @@
#_codingInstructions = lambda s, n, i, o, p: ( None, "print __time,',','\"%%s\"' %% globalVariables['__name'],',','%s',',',%s" % ( n, i[0]) )
_codingInstructions = lambda s, n, i, o, p: ( None, "inspector['%s'] = %s" % ( n, i[0]) )
+class ScopeBlock( LogicModule.LogicModule ):
+ _name = "scope"
+ _inPorts = [ 'in' ]
+ _outPorts = []
+ _parameters = []
+ _drawingInstructions = ""
+ _maskOptions = { 'showLabel': False }
+ _codingInstructions = lambda s, n, i, o, p: ( None, "inspector['%s'] = %s" % ( n, i[0]) )
+
+
class GainBlock( LogicModule.LogicModule ):
_name = "gain"
_inPorts = [ 'in' ]
@@ -80,6 +90,7 @@
def __init__( self ):
self.addBlock( ConstBlock )
self.addBlock( DisplayBlock )
+ self.addBlock( ScopeBlock )
self.addBlock( GainBlock )
self.addBlock( SumBlock )
self.addBlock( MemoryBlock )
Modified: PyWireGate/trunk/logik.json
===================================================================
--- PyWireGate/trunk/logik.json 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logik.json 2011-05-11 16:04:16 UTC (rev 330)
@@ -38,8 +38,13 @@
},
"Display3": {
"type": "MainLib/display",
- "x": 250, "y": 250, "width": 150, "height": 50,
+ "x": 250, "y": 350, "width": 150, "height": 50,
"parameters": {}
+ },
+ "Scope_1": {
+ "type": "MainLib/scope",
+ "x": 500, "y": 125, "width": 600, "height": 300,
+ "parameters": {}
}
},
"signals": [
@@ -49,6 +54,7 @@
[ "Integral1", 0, "Integral2" , 0, {} ],
[ "Integral2", 0, "Gain2" , 0, {} ],
[ "Gain2" , 0, "Integral1" , 0, {} ],
- [ "Integral2", 0, "Display3" , 0, {} ]
+ [ "Integral2", 0, "Display3" , 0, {} ],
+ [ "Integral2", 0, "Scope_1" , 0, {} ]
]
}
\ No newline at end of file
Modified: PyWireGate/trunk/logik2.json
===================================================================
--- PyWireGate/trunk/logik2.json 2011-05-10 21:04:09 UTC (rev 329)
+++ PyWireGate/trunk/logik2.json 2011-05-11 16:04:16 UTC (rev 330)
@@ -18,7 +18,7 @@
},
"Display22": {
"type": "MainLib/display",
- "x": 350, "y": 150, "width": 150, "height": 50,
+ "x": 350, "y": 50, "width": 150, "height": 50,
"parameters": {}
},
"Integral2": {
@@ -31,6 +31,11 @@
"x": 150, "y": 50, "width": 50, "height": 50,
"parameters": { "gain": -1.0 },
"flip" : true
+ },
+ "Scope_2": {
+ "type": "MainLib/scope",
+ "x": 350, "y": 150, "width": 600, "height": 300,
+ "parameters": {}
}
},
"signals": [
@@ -40,6 +45,7 @@
[ "Memory1" , 0, "Sum1" , 1, {} ],
[ "Integral2", 0, "Gain2" , 0, {} ],
[ "Gain2" , 0, "Gain1" , 0, {} ],
- [ "Integral2", 0, "Display22" , 0, {} ]
+ [ "Integral2", 0, "Display22" , 0, {} ],
+ [ "Integral2", 0, "Scope_2" , 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.
|
|
From: <ni...@us...> - 2010-11-06 23:29:10
|
Revision: 91
http://openautomation.svn.sourceforge.net/openautomation/?rev=91&view=rev
Author: nilss1
Date: 2010-11-06 23:29:03 +0000 (Sat, 06 Nov 2010)
Log Message:
-----------
no longer get WireGateInstance as Argument to new Classes, instead user parent Class and make self.WG = parent.WG.
This way each class can reach all parents using self._parent
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/comet_server/CometServer.py
PyWireGate/trunk/connector.py
PyWireGate/trunk/console_server/consoleserver.py
PyWireGate/trunk/cycler.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/BusMonitor.py
PyWireGate/trunk/knx_connector/DPT_Types.py
PyWireGate/trunk/knx_connector/GroupSocket.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/WireGate.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -31,6 +31,7 @@
class WireGate(daemon.Daemon):
def __init__(self,REDIRECTIO=False):
+ self._parent = self
self.WG = self
self.watchdoglist = {}
self.connectors = {}
Modified: PyWireGate/trunk/comet_server/CometServer.py
===================================================================
--- PyWireGate/trunk/comet_server/CometServer.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/comet_server/CometServer.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -33,8 +33,12 @@
CONNECTOR_NAME = 'Comet Server'
CONNECTOR_VERSION = 0.1
CONNECTOR_LOGNAME = 'comet_server'
- def __init__(self,WireGateInstance, instanceName):
- self.WG = WireGateInstance
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.instanceName = instanceName
defaultconfig = {
'port' : 4498
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/connector.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -7,8 +7,9 @@
CONNECTOR_LOGNAME = __name__
isrunning=False
- def __init__(self,WireGateInstance,instanceName):
- self.WG = WireGateInstance
+ def __init__(self,parent,instanceName):
+ self._parent = parent
+ self.WG = parent.WG
self.instanceName = instanceName
"""Overide"""
def start(self):
@@ -24,7 +25,7 @@
def log(self,msg,severity='info',instance=False):
if not instance:
instance = self.instanceName
- self.WG.log(msg,severity,instance)
+ self._parent.log(msg,severity,instance)
def shutdown(self):
self.log("%s (%s) shutting down" % (self.CONNECTOR_NAME, self.instanceName) ,'info','WireGate')
Modified: PyWireGate/trunk/console_server/consoleserver.py
===================================================================
--- PyWireGate/trunk/console_server/consoleserver.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/console_server/consoleserver.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -35,8 +35,12 @@
CONNECTOR_VERSION = 0.1
CONNECTOR_LOGNAME = 'console_server'
- def __init__(self,WireGateInstance, instanceName):
- self.WG = WireGateInstance
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.instanceName = instanceName
defaultconfig = {
'port' : 4401
Modified: PyWireGate/trunk/cycler.py
===================================================================
--- PyWireGate/trunk/cycler.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/cycler.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -20,101 +20,146 @@
import time
-class cycler:
- def __init__(self,WireGateInstance):
- self.WG = WireGateInstance
-
+class TaskRunner:
+ def __init__(self,parent):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.isrunning = True
- ## Dummy Timer
+
self.waiting = threading.Timer(0,lambda: None)
- self.waiting.setDaemon(1)
+
+
self.mutex = threading.RLock()
+
+ ## function for time based sortingg of tasks
self.getTime = lambda x: x.getTime
- self.timerList = []
+
+ ## all not running tasks goes here
+ self.taskList = []
+
+ ## all started tasks goes here
self.running = {}
def debug(self,msg):
print "DEBUG Cycler: %s" % msg
- def remove(self, obj):
+
+ def remove(self, task):
if not self.isrunning:
- ## dont try to get a mutex
+
+ ## dont try to get a mutex on shutdown
return False
try:
self.mutex.acquire()
- if obj in self.timerList:
+ if task in self.taskList:
try:
- self.timerList.remove(obj)
+ self.taskList.remove(task)
except:
pass
- self.debug("Removed %r" % obj.action)
- if len(self.timerList) == 0:
+ self.debug("Removed %r" % task.action)
+ if len(self.taskList) == 0:
## kill waiting timer
self.debug("Cancel GLobal wait")
self.waiting.cancel()
- if obj in self.running:
+
+ if task in self.running:
try:
- if self.running[obj].isAlive():
- self.running[obj].cancel()
- self.debug("Canceled %r" % obj.args)
+ if self.running[task].isAlive():
+ self.running[task].cancel()
+ self.debug("Canceled %r" % task.args)
finally:
- self.debug("terminated %r" % obj.args)
- del self.running[obj]
+ self.debug("terminated %r" % task.args)
+ del self.running[task]
finally:
self.mutex.release()
+
+
+ def event(self,rtime,function,*args,**kwargs):
+ if not self.isrunning:
+ ## dont try to get a mutex
+ return False
+ self.debug("adding event: %r (%r / %r)" % (function,args,kwargs))
+ ## rtime is a date as unix timestamp
+ rtime = rtime - time.time()
+ if rtime >0:
+ task = Task(self,rtime,function,args=args,kwargs=kwargs)
+ self._Shedule(task)
+ return task
+ else:
+ print "expired %r (%r / %r)" % (function,args,kwargs)
+
def add(self,rtime,function,*args,**kwargs):
if not self.isrunning:
## dont try to get a mutex
return False
self.debug("adding task: %r (%r / %r)" % (function,args,kwargs))
- self.addShedule(sheduleObject(self,self.WG,rtime,function,args=args,kwargs=kwargs))
+ task = Task(self,rtime,function,args=args,kwargs=kwargs)
+ self._Shedule(task)
+ return task
def cycle(self,rtime,function,*args,**kwargs):
if not self.isrunning:
## dont try to get a mutex
return False
self.debug("adding cycliv task: %r (%r / %r)" % (function,args,kwargs))
- self.addShedule(sheduleObject(self,self.WG,rtime,function,cycle=True,args=args,kwargs=kwargs))
+ task = Task(self,rtime,function,cycle=True,args=args,kwargs=kwargs)
+ self._Shedule(task)
+ return task
- def addShedule(self,shed):
- print "ADD _shed %r" % shed
+ def _Shedule(self,task):
+ print "adding task %r" % task
self.mutex.acquire()
- self.timerList.append(shed)
+ self.taskList.append(task)
+
## Try to stop running timer
+ ## Fixme isalive
try:
self.waiting.cancel()
except:
pass
- self.timerList.sort(key=self.getTime)
+
+ self.taskList.sort(key=self.getTime)
self.mutex.release()
## check if any Timer need activation
self._check()
- return shed
-
-
+
def _check(self):
self.debug("Cycle")
try:
self.mutex.acquire()
+ print "acitve tasks %d " % threading.activeCount()
+ atasks = "Active tasks: "
+ for rtask in threading.enumerate():
+ atasks += " %r" % rtask.getName()
+
+
+ print atasks
## all actions that need activation in next 60seconds
- for shedobj in filter(lambda x: x.getTime() < 60, self.timerList):
+ for task in filter(lambda x: x.getTime() < 60, self.taskList):
try:
- self.running[shedobj] = threading.Timer(shedobj.getTime(),shedobj.run)
- self.running[shedobj].start()
- #print "run %s" % t.name
+ exectime = task.getTime()
+ name = "event"
+ if task.cycle:
+ name = "cycle"
+ self.running[task] = threading.Timer(exectime,task.run)
+ self.running[task].setName("%s_%r" % (name,time.asctime(time.localtime(task.timer))))
+ self.running[task].start()
except:
print "Failed"
raise
- ## remove from List because its now in the past
- self.timerList.remove(shedobj)
+ ## remove from List because its now active
+ self.taskList.remove(task)
finally:
- if len(self.timerList) >0:
- print "Wait for later timer %r" % (self.timerList[0].getTime()-5)
- self.waiting = threading.Timer(self.timerList[0].getTime()-5 ,self._check)
+ if len(self.taskList) >0:
+ print "Wait for later timer %r" % (self.taskList[0].getTime()-5)
+ self.waiting = threading.Timer(self.taskList[0].getTime()-5 ,self._check)
self.waiting.start()
self.mutex.release()
@@ -125,35 +170,36 @@
try:
## stop all new timer
self.mutex.acquire()
+ self.taskList = []
+ for task in self.running.keys():
+ print "acitve tasks %d " % threading.activeCount()
+ print "cancel task %r" % task.args
+ try:
+ rtask = self.running.pop(task)
+ rtask.cancel()
+ rtask.join()
+ except:
+ pass
+
+ print self.waiting
+
print "Have Mutex"
- self.waiting.cancel()
try:
- self.waiting.join(2)
+ self.waiting.cancel()
+ self.waiting.join()
except:
- ## maybe not even running
pass
print "Thread canceld"
- self.timerList = []
- for obj in self.running.keys():
- print "cancel task %r" % obj.args
- try:
- tobecanceled = self.running.pop(obj)
-
- except:
- pass
- tobecanceled.cancel()
- tobecanceled.is
- tobecanceled.join(2)
-
-
+
+
except:
self.debug("SHUTDOWN FAILED")
-class sheduleObject:
- def __init__(self,parent,WireGateInstance,rtime,function,cycle=False,args = [],kwargs={}):
+class Task:
+ def __init__(self,parent,rtime,function,cycle=False,args = [],kwargs={}):
self.Parent = parent
- self.WG = WireGateInstance
+ self.WG = parent.WG
self.delay = rtime
self.cycle = cycle
self._set()
@@ -171,7 +217,7 @@
self.Parent.remove(self)
if self.cycle:
self._set()
- self.Parent.addShedule(self)
+ self.Parent._Shedule(self)
def getTime(self):
@@ -181,23 +227,37 @@
if __name__ == '__main__':
try:
- cycle = cycler(False)
+ cycle = TaskRunner(False)
import sys
import atexit
- atexit.register(cycle.shutdown)
+ #atexit.register(cycle.shutdown)
def write_time(text=''):
print "running %s: %f" % (text,time.time())
write_time('Main')
- cycle.cycle(4,write_time,"Cycletask1!")
- #longtask=cycle.add(80,write_time,"task2!")
- #f=cycle.add(7,write_time,"task3!")
+ cycle1 = cycle.cycle(4,write_time,"Cycletask1!")
+ cycle2 = cycle.cycle(8,write_time,"Cycletask2!")
+
+ longtask=cycle.add(80,write_time,"Longtask 80 secs!")
+
+ f=cycle.add(7,write_time,"task3!")
+
+ cycle.event(time.mktime((2010,11,6,21,54,00,0,0,0)),write_time,"event 21:54")
time.sleep(2)
- #cycle.remove(f)
- #time.sleep(5)
- #cycle.remove(longtask)
+ cycle.remove(f)
+ time.sleep(5)
+ print "##################remove longtask %r" % longtask
+ cycle.remove(longtask)
+
+ #cycle.cycle(4,write_time,"Cycletask6!")
+ print "KILL CYCLE"
+ cycle.remove(cycle1)
+ cycle.remove(cycle2)
#cycle.shutdown()
#cycle.add(6,write_time,"task4!")
+ while threading.activeCount() > 1:
+ time.sleep(1)
except KeyboardInterrupt:
- #cycle.shutdown()
+ cycle.shutdown()
+ cycle.waiting.join(5)
sys.exit(0)
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/datastore.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -15,7 +15,7 @@
"""
Datastore Instance
"""
- def __init__(self,WireGateInstance):
+ def __init__(self,parent):
####################################################
## Function: __init__
## Parameter:
@@ -24,7 +24,8 @@
## Contructor for the DATASTORE instance
##
####################################################
- self.WG = WireGateInstance
+ self._parent = parent
+ self.WG = parent.WG
self.log("DATASTORE starting up")
self.DBLOADED = False
self.dataobjects = {}
@@ -82,7 +83,7 @@
type(self.dataobjects[id])
except KeyError:
## create a new one if it don't exist
- self.dataobjects[id] = dataObject(self.WG,id)
+ self.dataobjects[id] = dataObject(self,id)
## return it
self.locked.release()
return self.dataobjects[id]
@@ -95,7 +96,7 @@
loaddict = json.load(db)
db.close()
for name, obj in loaddict.items():
- self.dataobjects[name] = dataObject(self.WG,obj['id'],obj['name'])
+ self.dataobjects[name] = dataObject(self,obj['id'],obj['name'])
self.dataobjects[name].lastupdate = obj['lastupdate']
self.dataobjects[name].config = obj['config']
self.dataobjects[name].connected = obj['connected']
@@ -154,8 +155,9 @@
class dataObject:
- def __init__(self,WireGateInstance,id,name=False):
- self.WG = WireGateInstance
+ def __init__(self,parent,id,name=False):
+ self._parent = parent
+ self.WG = parent.WG
## Threadlocking
self.write_mutex = threading.RLock()
Modified: PyWireGate/trunk/knx_connector/BusMonitor.py
===================================================================
--- PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -20,12 +20,15 @@
import time
class busmonitor:
- def __init__(self, WireGateInstance,connectorInstance):
- self.WG = WireGateInstance
- self.KNX = connectorInstance
+ def __init__(self, parent):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type(WireGateInstance)
+ self.dpt = DPT_Types.dpt_type(self)
## FIXME: Not fully implemented
self.apcicodes = {
@@ -101,7 +104,7 @@
if msg['ctrl2']['DestAddrType'] == 0 and msg['apdu']['tpdu'] == "T_DATA_XXX_REQ":
msg['dstaddr'] = self._decodeGrpAddr(buf[3:5])
- id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
+ id = "%s:%s" % (self._parent.instanceName, msg['dstaddr'])
## search Datastoreobject
dsobj = self.WG.DATASTORE.get(id)
@@ -265,10 +268,15 @@
except KeyError:
pass
return apci
+
+ def log(self,msg,severity='info',instance=False):
+ if not instance:
+ instance = self.instanceName
+ self._parent.log(msg,severity,instance)
+
def debug(self,msg):
- #print "DEBUG: BUSMON: "+ repr(msg)
- pass
+ self.log("DEBUG: BUSMON: "+ repr(msg),'debug')
if __name__ == "__main__":
Modified: PyWireGate/trunk/knx_connector/DPT_Types.py
===================================================================
--- PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -23,8 +23,12 @@
import struct
class dpt_type:
- def __init__(self,WireGateInstance):
- self.WG = WireGateInstance
+ def __init__(self,parent):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.DECODER = {
1:self.decodeDPT1, # EIS 1/7 / 1 bit 0=Aus/1=Ein
2:self.decodeDPT2, # EIS 8 / 2 bit 0,1=Frei/2=Prio_Aus/3=Prio_Ein
@@ -133,8 +137,8 @@
def log(self,msg,severity='info',instance=False):
if not instance:
instance = "dpt-types"
- if self.WG:
- self.WG.log(msg,severity,instance)
+ if self._parent:
+ self._parent.log(msg,severity,instance)
def toByteArray(self,val,length):
## Set ByteArray
Modified: PyWireGate/trunk/knx_connector/GroupSocket.py
===================================================================
--- PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -20,12 +20,15 @@
import time
class groupsocket:
- def __init__(self, WireGateInstance, connectorInstance):
- self.WG = WireGateInstance
- self.KNX = connectorInstance
+ def __init__(self, parent):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.nicehex=lambda x: " ".join(map(lambda y:"%.2x" % y,x))
self.tobinstr=lambda n,b=8: "".join([str((n >> y) & 1) for y in range(b-1, -1, -1)])
- self.dpt = DPT_Types.dpt_type(WireGateInstance)
+ self.dpt = DPT_Types.dpt_type(self)
def decode(self,buf,src,dst):
## Accept List Hex or Binary Data
@@ -49,7 +52,7 @@
msg['srcaddr'] = self._decodePhysicalAddr(src)
try:
msg['dstaddr'] = self._decodeGrpAddr(dst)
- id = "%s:%s" % (self.KNX.instanceName, msg['dstaddr'])
+ id = "%s:%s" % (self._parent.instanceName, msg['dstaddr'])
if (buf[0] & 0x3 or (buf[1] & 0xC0) == 0xC0):
##FIXME: unknown APDU
self.debug("unknown APDU from "+msg['srcaddr']+" to "+msg['dstaddr']+ " raw:"+buf)
@@ -88,9 +91,14 @@
def _decodeGrpAddr(self,raw):
return "%d/%d/%d" % ((raw >> 11) & 0x1f, (raw >> 8) & 0x07, (raw) & 0xff)
+
+ def log(self,msg,severity='info',instance=False):
+ if not instance:
+ instance = self.instanceName
+ self._parent.log(msg,severity,instance)
def debug(self,msg):
- #print "DEBUG: GROUPSOCKET: "+ repr(msg)
+ self.log("DEBUG: GROUPSOCKET: "+ repr(msg),'debug')
pass
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -33,17 +33,18 @@
CONNECTOR_NAME = 'KNX Connector'
CONNECTOR_VERSION = 0.2
CONNECTOR_LOGNAME = 'knx_connector'
- def __init__(self,WireGateInstance, instanceName):
- self.WG = WireGateInstance
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ self.WG = parent.WG
self.instanceName = instanceName
self.KNX = EIBConnection.EIBConnection()
self.KNXBuffer = EIBConnection.EIBBuffer()
self.KNXSrc = EIBConnection.EIBAddr()
self.KNXDst = EIBConnection.EIBAddr()
- self.busmon = BusMonitor.busmonitor(WireGateInstance,self)
- self.groupsocket = GroupSocket.groupsocket(WireGateInstance,self)
- self.dpt = DPT_Types.dpt_type(WireGateInstance)
+ self.busmon = BusMonitor.busmonitor(self)
+ self.groupsocket = GroupSocket.groupsocket(self)
+ self.dpt = DPT_Types.dpt_type(self)
self.GrpAddrRegex = re.compile(r"(?:|(\d+)\x2F)(\d+)\x2F(\d+)$",re.MULTILINE)
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-06 22:51:09 UTC (rev 90)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-06 23:29:03 UTC (rev 91)
@@ -26,8 +26,12 @@
CONNECTOR_NAME = 'OWFS Connector'
CONNECTOR_VERSION = 0.1
CONNECTOR_LOGNAME = 'owfs_connector'
- def __init__(self,WireGateInstance, instanceName):
- self.WG = WireGateInstance
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ if parent:
+ self.WG = parent.WG
+ else:
+ self.WG = False
self.instanceName = instanceName
defaultconfig = {
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-09 09:48:17
|
Revision: 93
http://openautomation.svn.sourceforge.net/openautomation/?rev=93&view=rev
Author: nilss1
Date: 2010-11-09 09:48:10 +0000 (Tue, 09 Nov 2010)
Log Message:
-----------
OWFS Threads use mutex * get default configs for unknown datastore objects * except errors in knx_connector _setValue Function
Modified Paths:
--------------
PyWireGate/trunk/connector.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-07 09:51:00 UTC (rev 92)
+++ PyWireGate/trunk/connector.py 2010-11-09 09:48:10 UTC (rev 93)
@@ -52,6 +52,12 @@
self.log("unconfigured setValue in %r called for %s" % (self,dsobj.name) ,'warn','WireGate')
pass
+ def get_ds_defaults(self,id):
+ ## the defualt config for new Datasotre Items
+ config = {
+ }
+ return config
+
import SocketServer
import socket
class ConnectorServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer,Connector):
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-07 09:51:00 UTC (rev 92)
+++ PyWireGate/trunk/datastore.py 2010-11-09 09:48:10 UTC (rev 93)
@@ -8,7 +8,11 @@
## use included json in > Python 2.6
import json
except ImportError:
- import simplejson as json
+ try:
+ import simplejson as json
+ except ImportError:
+ print >>sys.stderr, "apt-get install python-simplejson"
+ sys.exit(1)
class datastore:
@@ -35,7 +39,7 @@
self.load()
- def update(self,id,val):
+ def update(self,id,val,connector=False):
## Update the communication Object with value
####################################################
## Function: update
@@ -48,7 +52,7 @@
####################################################
##
## get the Datastore object
- obj = self.get(id)
+ obj = self.get(id,connector=connector)
self.debug("Updating %s (%s): %r" % (obj.name,id,val))
## Set the value of the object
@@ -68,7 +72,7 @@
## return the object for additional updates
return obj
- def get(self,id):
+ def get(self,id,connector=False):
####################################################
## Function: get
## Parameter:
@@ -84,6 +88,8 @@
except KeyError:
## create a new one if it don't exist
self.dataobjects[id] = dataObject(self,id)
+ if connector:
+ self.dataobjects[id].config = connector.get_ds_defaults(id)
## return it
self.locked.release()
return self.dataobjects[id]
@@ -133,7 +139,6 @@
dbfile = codecs.open(self.WG.config['WireGate']['datastore'],"wb",encoding='utf-8')
utfdb = json.dumps(savedict,dbfile,ensure_ascii=False,sort_keys=True,indent=3)
dbfile.write(utfdb)
- #json.dump(savedict,dbfile,sort_keys=True,indent=3)
dbfile.close()
@@ -199,8 +204,12 @@
## self override
## override with connector send function
if self.namespace:
- self._setValue = self.WG.connectors[self.namespace].setValue
- self.WG.connectors[self.namespace].setValue(refered_self)
+ try:
+ self.write_mutex.acquire()
+ self._setValue = self.WG.connectors[self.namespace].setValue
+ self.WG.connectors[self.namespace].setValue(refered_self)
+ finally:
+ self.write_mutex.release()
def setValue(self,val,send=False):
try:
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-07 09:51:00 UTC (rev 92)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-09 09:48:10 UTC (rev 93)
@@ -150,8 +150,10 @@
self.errormsg("Failed send %r to %r" % (msg,dstaddr))
def setValue(self,dsobj,msg=False):
- if not msg:
- msg = dsobj.getValue()
- self.debug("SEND %r to %s (%s)" % (msg,dsobj.name,dsobj.id))
- self.send(self.dpt.encode(msg,dsobj=dsobj),dsobj.id)
-
\ No newline at end of file
+ try:
+ if not msg:
+ msg = dsobj.getValue()
+ self.debug("SEND %r to %s (%s)" % (msg,dsobj.name,dsobj.id))
+ self.send(self.dpt.encode(msg,dsobj=dsobj),dsobj.id)
+ except:
+ print "----------- ERROR IN KNX_CONNECTOR.setValue ----------------"
\ No newline at end of file
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-07 09:51:00 UTC (rev 92)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-09 09:48:10 UTC (rev 93)
@@ -34,6 +34,8 @@
self.WG = False
self.instanceName = instanceName
+ self.mutex = threading.RLock()
+
defaultconfig = {
'cycletime' : 15,
'server' : '127.0.0.1',
@@ -69,6 +71,13 @@
self.sensors = {}
self.start()
+ def get_ds_defaults(self,id):
+ ## the defualt config for new Datasotre Items
+ config = {}
+ if id[-11:] == 'temperature':
+ config['resolution'] = 10
+ return config
+
def run(self):
cnt = 10
while self.isrunning:
@@ -113,15 +122,19 @@
if self.findbusmaster(bus):
## if this has no subbuses add it to the list
try:
- ## check if bus already in list and set time
- self.busmaster[bus]['lastseen'] = time.time()
- except KeyError:
- ## add to list
- self.busmaster[bus] = {
- 'sensors' : {},
- 'lastseen' : time.time(),
- 'readthread' : None
- }
+ self.mutex.acquire()
+ try:
+ ## check if bus already in list and set time
+ self.busmaster[bus]['lastseen'] = time.time()
+ except KeyError:
+ ## add to list
+ self.busmaster[bus] = {
+ 'sensors' : {},
+ 'lastseen' : time.time(),
+ 'readthread' : None
+ }
+ finally:
+ self.mutex.release()
self.findsensors(bus)
except:
## ignore all OWFS Errors
@@ -151,11 +164,15 @@
interfaces = self.supportedsensors[sensortype]
### add it to the list of active sensors
## FIXME: check for old sensor no longer active and remove
- self.busmaster[path]['sensors'][sensor] = {
- 'type':sensortype,
- 'interfaces':interfaces,
- 'resolution':'10' ## Resolution schould be read from Datastore
- }
+ try:
+ self.mutex.acquire()
+ self.busmaster[path]['sensors'][sensor] = {
+ 'type':sensortype,
+ 'interfaces':interfaces,
+ 'resolution':'10' ## Resolution schould be read from Datastore
+ }
+ finally:
+ self.mutex.release()
except KeyError:
self.debug("unsupported Type: %r" % sensortype)
@@ -181,12 +198,17 @@
## get the Datastore Object and look for config
obj = self.WG.DATASTORE.get(id)
if "resolution" in obj.config:
- resolution = obj.config['resolution']
+ resolution = str(obj.config['resolution'])
owfspath = "/uncached/%s/%s%s" % (sensor,get,resolution)
+ self.debug("Reading from path %s" % owfspath)
try:
## read uncached and put into local-list
- self.busmaster[busname]['sensors'][sensor][get] = self.owfs.read(owfspath)
+ try:
+ self.mutex.acquire()
+ self.busmaster[busname]['sensors'][sensor][get] = self.owfs.read(owfspath)
+ finally:
+ self.mutex.release()
except:
## ignore all OWFS Errors
self.WG.errorlog("Reading from path %s failed" % owfspath)
@@ -199,7 +221,7 @@
except:
self.WG.errorlog()
self.busmaster[busname]['readthread'] = None
- self.debug("Thread for %s finshed reading %d sensors in % f secs " % (busname,len(self.busmaster[busname]['sensors']), time.time() - readtime))
+ self.debug("Thread for %s finshed reading %d sensors in %f secs " % (busname,len(self.busmaster[busname]['sensors']), time.time() - readtime))
def read(self):
for busname in self.busmaster.keys():
@@ -207,5 +229,9 @@
if not self.busmaster[busname]['readthread']:
self.debug("Start read Thread for %s" % busname)
threadname = "OWFS-Reader_%s" % busname
- self.busmaster[busname]['readthread'] = threading.Thread(target=self._read,args=[busname],name=threadname)
- self.busmaster[busname]['readthread'].start()
+ try:
+ self.mutex.acquire()
+ self.busmaster[busname]['readthread'] = threading.Thread(target=self._read,args=[busname],name=threadname)
+ self.busmaster[busname]['readthread'].start()
+ finally:
+ self.mutex.release()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-10 09:40:40
|
Revision: 96
http://openautomation.svn.sourceforge.net/openautomation/?rev=96&view=rev
Author: nilss1
Date: 2010-11-10 09:40:34 +0000 (Wed, 10 Nov 2010)
Log Message:
-----------
use priority based queue for knx messages, add an optional per connector method _shutdown to join local threads on exit
Modified Paths:
--------------
PyWireGate/trunk/connector.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-09 13:42:57 UTC (rev 95)
+++ PyWireGate/trunk/connector.py 2010-11-10 09:40:34 UTC (rev 96)
@@ -30,6 +30,8 @@
def shutdown(self):
self.log("%s (%s) shutting down" % (self.CONNECTOR_NAME, self.instanceName) ,'info','WireGate')
self.isrunning=False
+ if hasattr(self,'_shutdown'):
+ self._shutdown()
self._thread.join(2)
if self._thread.isAlive():
self.log("Shutdown Failed",'critical')
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-09 13:42:57 UTC (rev 95)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-10 09:40:34 UTC (rev 96)
@@ -24,6 +24,9 @@
import BusMonitor
import GroupSocket
import DPT_Types
+from Queue import Empty,Full,Queue
+import heapq
+import threading
KNXREADFLAG = 0x00
KNXRESPONSEFLAG = 0x40
@@ -42,10 +45,16 @@
self.KNXBuffer = EIBConnection.EIBBuffer()
self.KNXSrc = EIBConnection.EIBAddr()
self.KNXDst = EIBConnection.EIBAddr()
+
+ #self.sendQueue = Queue.PriorityQueue(maxsize=5000)
+ self.sendQueue = KNXSendQueue(maxsize=5000)
+
+
self.busmon = BusMonitor.busmonitor(self)
self.groupsocket = GroupSocket.groupsocket(self)
self.dpt = DPT_Types.dpt_type(self)
+
self.GrpAddrRegex = re.compile(r"(?:|(\d+)\x2F)(\d+)\x2F(\d+)$",re.MULTILINE)
## Deafaultconfig
@@ -64,6 +73,9 @@
self.start()
def run(self):
+ self._sendThread = threading.Thread(target=self._sendloop)
+ self._sendThread.setDaemon(True)
+ self._sendThread.start()
while self.isrunning:
## Create Socket
try:
@@ -89,6 +101,12 @@
self.debug("Socket %r Closed waiting 5 sec" % self.config['url'])
self.idle(5)
+ def _shutdown(self):
+ try:
+ self._sendThread.join()
+ except:
+ pass
+
def _run(self):
while self.isrunning:
## Check if we are alive and responde until 10 secs
@@ -140,14 +158,29 @@
return addr
+ def _sendloop(self):
+ addr = 0
+ msg = []
+ while self.isrunning:
+ try:
+ (addr,msg) = self.sendQueue.get(timeout=1)
+ self.KNX.EIBSendGroup(addr,msg)
+ except Empty:
+ pass
+ except:
+ self.WG.errorlog("Failed send %r %r" % (addr,msg))
+
+
+
def send(self,msg,dstaddr):
try:
addr = self.str2grpaddr(dstaddr)
if addr:
msg = [0,KNXWRITEFLAG] +msg
- self.KNX.EIBSendGroup(addr,msg)
+ self.sendQueue.put((addr,msg))
+ #self.KNX.EIBSendGroup(addr,msg)
except:
- self.errormsg("Failed send %r to %r" % (msg,dstaddr))
+ self.WG.errorlog("Failed send %r to %r" % (msg,dstaddr))
def setValue(self,dsobj,msg=False):
try:
@@ -156,4 +189,38 @@
self.debug("SEND %r to %s (%s)" % (msg,dsobj.name,dsobj.id))
self.send(self.dpt.encode(msg,dsobj=dsobj),dsobj.id)
except:
- print "----------- ERROR IN KNX_CONNECTOR.setValue ----------------"
\ No newline at end of file
+ print "----------- ERROR IN KNX_CONNECTOR.setValue ----------------"
+
+
+class KNXSendQueue(Queue):
+ def _init(self, maxsize):
+ self.maxsize = maxsize
+ self.queue = []
+ self.activeaddr = []
+
+ def _qsize(self):
+ return len(self.queue)
+
+ # Check whether the queue is empty
+ def _empty(self):
+ return not self.queue
+
+ # Check whether the queue is full
+ def _full(self):
+ return self.maxsize > 0 and len(self.queue) == self.maxsize
+
+ # Put a new item in the queue
+ def _put(self, item):
+ ## add addr to active addr
+ addr = item[0]
+ prio = int(self.activeaddr.count(addr) > 5)
+ self.activeaddr.append(addr)
+ heapq.heappush(self.queue,(prio,item))
+
+ # Get an item from the queue
+ def _get(self):
+ prio,item = heapq.heappop(self.queue)
+ addr = item[0]
+ self.activeaddr.remove(addr)
+ return item
+
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-10 14:34:34
|
Revision: 99
http://openautomation.svn.sourceforge.net/openautomation/?rev=99&view=rev
Author: nilss1
Date: 2010-11-10 14:34:28 +0000 (Wed, 10 Nov 2010)
Log Message:
-----------
Changed datastore save to shutdown
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/datastore.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-10 13:46:13 UTC (rev 98)
+++ PyWireGate/trunk/WireGate.py 2010-11-10 14:34:28 UTC (rev 99)
@@ -191,18 +191,20 @@
pass
## now save Datastore
- self.DATASTORE.save()
+ self.DATASTORE.shutdown()
## Handle Errors
def errorlog(self,msg=False):
- exc_type, exc_value, exc_traceback = sys.exc_info()
- tback = traceback.extract_tb(exc_traceback)
- #type(self.ErrorLOGGER)
- #print tback
- #print exc_type, exc_value
+ try:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ tback = traceback.extract_tb(exc_traceback)
+ except:
+ exc_value = ""
+ exc_type = ""
+ tback = ""
+ pass
if msg:
- #print repr(msg)
self.ErrorLOGGER.error(repr(msg))
errmsg = "%r %r %r" % (exc_type, exc_value,tback)
self.ErrorLOGGER.error(errmsg)
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-10 13:46:13 UTC (rev 98)
+++ PyWireGate/trunk/datastore.py 2010-11-10 14:34:28 UTC (rev 99)
@@ -141,7 +141,8 @@
dbfile.write(utfdb)
dbfile.close()
-
+ def shutdown(self):
+ self.save()
def debug(self,msg):
####################################################
@@ -240,4 +241,4 @@
## release lock
self.read_mutex.release()
-
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-11 15:56:08
|
Revision: 109
http://openautomation.svn.sourceforge.net/openautomation/?rev=109&view=rev
Author: nilss1
Date: 2010-11-11 15:56:02 +0000 (Thu, 11 Nov 2010)
Log Message:
-----------
Fix date in DPT_Types.py * Fix parent error for DSupdate in datastore.py * change print to debug in scheduler.py
Modified Paths:
--------------
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/DPT_Types.py
PyWireGate/trunk/scheduler.py
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-11 14:49:01 UTC (rev 108)
+++ PyWireGate/trunk/datastore.py 2010-11-11 15:56:02 UTC (rev 109)
@@ -193,7 +193,8 @@
class dataObject:
def __init__(self,parent,id,name=False):
self._parent = parent
- self.WG = parent.WG
+ if parent:
+ self.WG = parent.WG
## Threadlocking
self.write_mutex = threading.RLock()
Modified: PyWireGate/trunk/knx_connector/DPT_Types.py
===================================================================
--- PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-11 14:49:01 UTC (rev 108)
+++ PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-11 15:56:02 UTC (rev 109)
@@ -361,9 +361,11 @@
def encodeDPT11(self,val):
## make time struct accesible
+ utime=[]
if type(val) in [float, int]:
- utime = [v for v in time.localtime(tval)]
- else:
+ if val > 0:
+ utime = [v for v in time.localtime(val)]
+ if utime == []:
utime = [v for v in time.localtime()]
if type(val) == str:
Modified: PyWireGate/trunk/scheduler.py
===================================================================
--- PyWireGate/trunk/scheduler.py 2010-11-11 14:49:01 UTC (rev 108)
+++ PyWireGate/trunk/scheduler.py 2010-11-11 15:56:02 UTC (rev 109)
@@ -47,12 +47,12 @@
for uoption in obj.config['cron'].keys():
kwargs[str(uoption)] = str(obj.config['cron'][uoption])
- print "Adding %s - %r" % (shed,obj)
+ self.debug("Adding %s - %r" % (shed,obj))
setattr(obj.sendConnected.im_func,'__name__',"%s" % shed.encode('UTF-8'))
self.SCHEDULER.add_cron_job(self.WG.DATASTORE.dataobjects[shed].sendConnected,**kwargs)
def shutdown(self):
- print self.SCHEDULER.dump_jobs()
+ self.debug("shutdown Scheduler\n%s" % self.SCHEDULER.dump_jobs())
self.SCHEDULER.shutdown()
def debug(self,msg):
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-18 16:01:15
|
Revision: 137
http://openautomation.svn.sourceforge.net/openautomation/?rev=137&view=rev
Author: nilss1
Date: 2010-11-18 16:01:07 +0000 (Thu, 18 Nov 2010)
Log Message:
-----------
lirc-connector
Added Paths:
-----------
PyWireGate/trunk/lirc_connector/
PyWireGate/trunk/lirc_connector/LIRC_Connector.py
PyWireGate/trunk/lirc_connector/__init__.py
Added: PyWireGate/trunk/lirc_connector/LIRC_Connector.py
===================================================================
--- PyWireGate/trunk/lirc_connector/LIRC_Connector.py (rev 0)
+++ PyWireGate/trunk/lirc_connector/LIRC_Connector.py 2010-11-18 16:01:07 UTC (rev 137)
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+# -*- coding: iso8859-1 -*-
+## -----------------------------------------------------
+## WireGate.py
+## -----------------------------------------------------
+## Copyright (c) 2010, knx-user-forum e.V, 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 socket
+import select
+import re
+
+class lirc_connector(Connector):
+
+
+ CONNECTOR_NAME = 'LIRC Connector'
+ CONNECTOR_VERSION = 0.1
+ CONNECTOR_LOGNAME = 'lirc_connector'
+ def __init__(self,parent, instanceName):
+ self._parent = parent
+ self.WG = parent.WG
+ self.instanceName = instanceName
+
+ defaultconfig = {
+ 'server' : '127.0.0.1',
+ 'port' : 8765
+ }
+ self.WG.checkconfig(self.instanceName,defaultconfig)
+ self.config = self.WG.config[instanceName]
+
+ self.start()
+
+
+ def run(self):
+ while self.isrunning:
+ ## Create Socket
+ try:
+ self._socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
+ try:
+ self._socket.connect((self.config['server'],self.config['port']))
+ self._sockfile = self._socket.makefile()
+ self._run()
+ except socket.error ,e:
+ if e[0] == 111:
+ print "NO Connection"
+
+ finally:
+ try:
+ self._socket.close()
+ except:
+ pass
+ if self.isrunning:
+ self.debug("Socket to %s:%d Closed waiting 5 sec" % (self.config['server'],self.config['port']))
+ self.idle(5)
+
+ def _run(self):
+ while self.isrunning:
+ ##00000014de890000 00 BTN_VOLUP X10_CHAN9
+ r,w,e = select.select([self._socket],[],[],1)
+ if not r:
+ continue
+ rawmsg = self._sockfile.readline()
+ try:
+ raw, counter, button, channel = rawmsg.split()
+ ## default "LIRC:channel_button
+ id = "%s:%s_%s" % (self.instanceName,channel,button)
+ self.WG.DATASTORE.update(id,counter)
+
+ id = "%s:%s" % (self.instanceName,button)
+ ## dont't create it "LIRC:Button"
+ if id in self.WG.DATASTORE.dataobjects:
+ self.WG.DATASTORE.update(id,channel)
+
+ except ValueError:
+ self.debug("invalid Data %r" % rawmsg)
+
+
Added: PyWireGate/trunk/lirc_connector/__init__.py
===================================================================
--- PyWireGate/trunk/lirc_connector/__init__.py (rev 0)
+++ PyWireGate/trunk/lirc_connector/__init__.py 2010-11-18 16:01:07 UTC (rev 137)
@@ -0,0 +1 @@
+from LIRC_Connector import lirc_connector
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-11-25 12:25:40
|
Revision: 163
http://openautomation.svn.sourceforge.net/openautomation/?rev=163&view=rev
Author: nilss1
Date: 2010-11-25 12:25:33 +0000 (Thu, 25 Nov 2010)
Log Message:
-----------
scan group addresses load physical addresses on startup for healthcheck * some fixes
Modified Paths:
--------------
PyWireGate/trunk/WireGate.py
PyWireGate/trunk/connector.py
PyWireGate/trunk/daemon.py
PyWireGate/trunk/datastore.py
PyWireGate/trunk/knx_connector/BusMonitor.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
Modified: PyWireGate/trunk/WireGate.py
===================================================================
--- PyWireGate/trunk/WireGate.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/WireGate.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -183,6 +183,10 @@
for obj in self.watchdoglist.keys():
if time.time() > self.watchdoglist[obj]:
self.log("\n\nInstanz %s reagiert nicht\n\n" % obj,'error')
+ try:
+ self.connectors[obj].shutdown()
+ except:
+ pass
del self.watchdoglist[obj]
## set Watchdog
Modified: PyWireGate/trunk/connector.py
===================================================================
--- PyWireGate/trunk/connector.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/connector.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -15,7 +15,7 @@
def start(self):
self.log("%s (%s) starting up" % (self.CONNECTOR_NAME, self.instanceName) ,'info','WireGate')
self.isrunning=True
- self._thread = threading.Thread(target=self.run,name=__name__)
+ self._thread = threading.Thread(target=self.run,name="%s_main" % self.instanceName)
self._thread.setDaemon(1)
self._thread.start()
@@ -32,7 +32,8 @@
self.isrunning=False
if hasattr(self,'_shutdown'):
self._shutdown()
- self._thread.join(2)
+ if self._thread.isALive():
+ self._thread.join(2)
if self._thread.isAlive():
self.log("Shutdown Failed",'critical')
Modified: PyWireGate/trunk/daemon.py
===================================================================
--- PyWireGate/trunk/daemon.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/daemon.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -13,7 +13,7 @@
print e
sys.exit()
-class Daemon:
+class Daemon(object):
"""
A generic daemon class.
Modified: PyWireGate/trunk/datastore.py
===================================================================
--- PyWireGate/trunk/datastore.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/datastore.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -100,6 +100,8 @@
self.locked.release()
return self.dataobjects[id]
+ def namespaceRead(self,namespace):
+ return filter(lambda x,y=namespace: x.namespace == y,self.dataobjects.values())
def load(self):
self.debug("load DATASTORE")
@@ -200,7 +202,7 @@
namespace = namespace[0]
else:
## Fixme: maybe default Namespace
- namespace = ""
+ namespace = "UNKNOWN"
self.namespace = namespace
if not name:
@@ -249,7 +251,7 @@
if self.namespace:
try:
self.write_mutex.acquire()
- self._setValue = self.WG.connectors[self.namespace].setValue
+ #self._setValue = self.WG.connectors[self.namespace].setValue
self.WG.connectors[self.namespace].setValue(refered_self)
finally:
self.write_mutex.release()
Modified: PyWireGate/trunk/knx_connector/BusMonitor.py
===================================================================
--- PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/knx_connector/BusMonitor.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -271,7 +271,7 @@
def log(self,msg,severity='info',instance=False):
if not instance:
- instance = self.instanceName
+ instance = 'KNX'
self._parent.log(msg,severity,instance)
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-24 11:27:22 UTC (rev 162)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-25 12:25:33 UTC (rev 163)
@@ -55,6 +55,7 @@
self.eibmutex = threading.RLock()
self.DeviceList = {}
+ self.DeviceListLock = threading.RLock()
self.sendQueue = KNXSendQueue(maxsize=5000)
self.QueueWaitTime = 0.0
@@ -64,7 +65,7 @@
self.dpt = DPT_Types.dpt_type(self)
- self.GrpAddrRegex = re.compile(r"(?:|(\d+)\x2F)(\d+)\x2F(\d+)$",re.MULTILINE)
+ self.AddrRegex = re.compile(r"(?:|(\d+)[\x2F|\x2E])(\d+)[\x2F|\x2E](\d+)$",re.MULTILINE)
## Deafaultconfig
defaultconfig = {
@@ -83,6 +84,7 @@
self._sendThread = threading.Thread()
self._checkThread = threading.Thread()
+
## Start the Thread
self.start()
@@ -94,17 +96,18 @@
self.statistics()
try:
## wait a second for the Busmon to activate
+ if not self._readThread.isAlive():
+ self._readThread = threading.Thread(target=self._sendloop,name="%s_read" % self.instanceName)
+ self._readThread.setDaemon(0)
+ self._readThread.start()
if not self._sendThread.isAlive():
- self._sendThread = threading.Thread(target=self._run)
- self._sendThread.setDaemon(True)
+ self._sendThread = threading.Thread(target=self._run,name="%s_send" % self.instanceName)
+ self._sendThread.setDaemon(0)
self._sendThread.start()
- if not self._readThread.isAlive():
- self._readThread = threading.Thread(target=self._sendloop)
- self._readThread.setDaemon(True)
- self._readThread.start()
+
if not self._checkThread.isAlive():
- self._checkThread = threading.Thread(target=self._healthCheck)
- self._checkThread.setDaemon(True)
+ self._checkThread = threading.Thread(target=self._healthCheck,name="%s_check" % self.instanceName)
+ self._checkThread.setDaemon(0)
self._checkThread.start()
@@ -120,12 +123,13 @@
self.idle(5)
def _shutdown(self):
+ ##self.statistics()
for rthread in [self._checkThread,self._sendThread,self._readThread]:
try:
- rthread.join()
+ if rthread.isAlive():
+ rthread.join(2)
except:
pass
- self.statistics()
def _run(self):
try:
@@ -133,32 +137,39 @@
self.KNX.EIB_Cache_Enable()
if self.config['parser'] == "groupsocket":
self.debug("Using Groupsocket parser")
- self.KNX.EIBOpen_GroupSocket_async(0)
+ #self.KNX.EIBOpen_GroupSocket_async(0)
+ self.KNX.EIBOpen_GroupSocket(0)
else:
self.debug("Using Busmonitor Parser")
+ #self.KNX.EIBOpenVBusmonitor()
self.KNX.EIBOpenVBusmonitor()
while self.isrunning:
## Check if we are alive and responde until 10 secs
self.WG.watchdog(self.instanceName,10)
- if self.config['parser'] == "busmonior":
+ if self.config['parser'] == "groupsocket":
+ self.KNX.EIBGetGroup_Src(self.KNXBuffer,self.KNXSrc,self.KNXDst)
+ ## Only decode packets larger than 1 octet
+ try:
+ self.DeviceListLock.acquire()
+ if self.KNXSrc.data not in self.DeviceList:
+ self.DeviceList[self.KNXSrc.data] = self.groupsocket._decodePhysicalAddr(self.KNXSrc.data)
+ finally:
+ self.DeviceListLock.release()
+ if len(self.KNXBuffer.buffer) > 1 :
+ self.groupsocket.decode(self.KNXBuffer.buffer,self.KNXSrc.data,self.KNXDst.data)
+ else:
self.KNX.EIBGetBusmonitorPacket(self.KNXBuffer)
## Only decode packets larger than 7 octets
if len(self.KNXBuffer.buffer) > 7 :
self.busmon.decode(self.KNXBuffer.buffer)
- else:
- self.KNX.EIBGetGroup_Src(self.KNXBuffer,self.KNXSrc,self.KNXDst)
- ## Only decode packets larger than 1 octet
- if self.KNXSrc.data not in self.DeviceList:
- self.DeviceList[self.KNXSrc.data] = self.groupsocket._decodePhysicalAddr(self.KNXSrc.data)
- if len(self.KNXBuffer.buffer) > 1 :
- self.groupsocket.decode(self.KNXBuffer.buffer,self.KNXSrc.data,self.KNXDst.data)
+
finally:
self.KNX.EIBClose()
- def str2grpaddr(self,addrstr):
- grpaddr = self.GrpAddrRegex.findall(addrstr)
+ def str2addr(self,addrstr):
+ grpaddr = self.AddrRegex.findall(addrstr)
if not grpaddr:
return False
## regex result 1
@@ -166,15 +177,20 @@
addr = 0
## if GROUP3 Addr
if grpaddr[0]:
- addr = int(grpaddr[0]) << 11
+ if addrstr.find(".") < 1:
+ addr = int(grpaddr[0]) << 11
+ else:
+ addr = int(grpaddr[0]) << 12
addr = addr | (int(grpaddr[1]) << 8)
addr = addr | int(grpaddr[2])
return addr
+
def _sendloop(self):
addr = 0
msg = []
+ self.readconfig()
try:
while self.isrunning:
try:
@@ -183,6 +199,7 @@
try:
self.eibmutex.acquire()
self.QueueWaitTime += wtime
+ print "ADDR %r -- MSG %r" % (addr,msg)
self.KNX.EIBSendGroup(addr,msg)
finally:
self.eibmutex.release()
@@ -197,7 +214,7 @@
def send(self,msg,dstaddr,flag=KNXWRITEFLAG):
try:
- addr = self.str2grpaddr(dstaddr)
+ addr = self.str2addr(dstaddr)
if addr:
apdu = [0]
if type(msg) == int:
@@ -229,7 +246,14 @@
self.idle(10)
while self.isrunning:
if self.config['checktime'] > 0:
- for physaddr, device in self.DeviceList.items():
+ ## wait 5 Minutes
+ self.idle(self.config['checktime'])
+ try:
+ self.DeviceListLock.acquire()
+ devices = self.DeviceList.items()
+ finally:
+ self.DeviceListLock.release()
+ for physaddr, device in devices:
while self.sendQueue.qsize() > 5 and self.isrunning:
## no voltage check on higher busload
self.debug("SendQueue to busy wait check Voltage")
@@ -244,7 +268,10 @@
if 'ignorecheck' in obj.config:
continue
try:
- self.cKNX.EIB_MC_Connect(physaddr)
+ ret = self.cKNX.EIB_MC_Connect(physaddr)
+ if ret == -1:
+ self.cKNX.EIBReset()
+ continue
## read voltage
ret = self.cKNX.EIB_MC_ReadADC(1,1,ebuf)
try:
@@ -261,8 +288,6 @@
pass
## wait 1000ms between checks
self.idle(1)
- ## wait 5 Minutes
- self.idle(self.config['checktime'])
else:
self.idle(60)
finally:
@@ -301,13 +326,32 @@
try:
self.eibmutex.acquire()
+ waittime = self.QueueWaitTime / stime
self.debug("QueueWait: %r in %r sec" % (self.QueueWaitTime , stime))
- waittime = self.QueueWaitTime / stime
self.QueueWaitTime = 0.0
finally:
self.eibmutex.release()
+
+ #print "THREADS %r" % threading.enumerate()
id = "%s:STATS-QueueWaitTime" % (self.instanceName)
self.WG.DATASTORE.update(id,waittime)
+
+
+ def readconfig(self):
+ getPhysical = re.compile(":PHY_((?:1[0-5]|[0-9])\x2E(?:1[0-5]|[0-9])\x2E(?:[0-9]{1,3}))")
+ instLength = len(self.instanceName)
+ for obj in self.WG.DATASTORE.namespaceRead(self.instanceName):
+ physaddr = getPhysical.findall(obj.id.encode('iso8859-15'))
+ if physaddr:
+ try:
+ self.DeviceListLock.acquire()
+ self.DeviceList[self.str2addr(physaddr[0])] = physaddr[0]
+ finally:
+ self.DeviceListLock.release()
+ elif 'scan' in obj.config:
+ ## read all objects marked for scan
+ self.send(0,obj.id.encode('iso8859-15'),flag=KNXREADFLAG)
+
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
From: <ni...@us...> - 2010-12-02 13:22:56
|
Revision: 179
http://openautomation.svn.sourceforge.net/openautomation/?rev=179&view=rev
Author: nilss1
Date: 2010-12-02 12:19:36 +0000 (Thu, 02 Dec 2010)
Log Message:
-----------
some fixes ** lots of debugging prints have to be removed later
Modified Paths:
--------------
PyWireGate/trunk/knx_connector/DPT_Types.py
PyWireGate/trunk/knx_connector/GroupSocket.py
PyWireGate/trunk/knx_connector/KNX_Connector.py
PyWireGate/trunk/owfs_connector/OWFS_Connector.py
PyWireGate/trunk/owfs_connector/connection.py
PyWireGate/trunk/scheduler.py
Modified: PyWireGate/trunk/knx_connector/DPT_Types.py
===================================================================
--- PyWireGate/trunk/knx_connector/DPT_Types.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/knx_connector/DPT_Types.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -211,14 +211,14 @@
val = val.encode('iso-8859-15')
if type(val) <> str:
val = "%r" % val
- return ord(val[0]) & 0xff
+ return [ord(val[0]) & 0xff]
def decodeDPT5(self,raw):
## 1 Byte unsigned
return int(raw[0]) & 0xff
def encodeDPT5(self,val):
- return int(val) & 0xff
+ return [int(val) & 0xff]
def decodeDPT501(self,raw):
## 1 Byte unsigned percent
@@ -226,7 +226,9 @@
return (int(raw[0]) & 0xff) * 100 / 255
def encodeDPT501(self,val):
- return (int(val) * 255 / 100 ) & 0xff
+ if val > 100:
+ val = 100
+ return [(int(val) * 255 / 100 ) & 0xff]
def decodeDPT6(self,raw):
## 1 Byte signed
@@ -237,7 +239,7 @@
if val > 127:
## Max
val = 127
- return int(val) & 0xff
+ return [int(val) & 0xff]
def decodeDPT7(self,raw):
## 2 byte unsigned
Modified: PyWireGate/trunk/knx_connector/GroupSocket.py
===================================================================
--- PyWireGate/trunk/knx_connector/GroupSocket.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/knx_connector/GroupSocket.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -55,7 +55,7 @@
id = "%s:%s" % (self._parent.instanceName, msg['dstaddr'])
if (buf[0] & 0x3 or (buf[1] & 0xC0) == 0xC0):
##FIXME: unknown APDU
- self.debug("unknown APDU from "+msg['srcaddr']+" to "+msg['dstaddr']+ " raw:"+buf)
+ self.debug("unknown APDU from %r to %r raw: %r" %(msg['srcaddr'] ,msg['dstaddr'],buf))
else:
dsobj = self.WG.DATASTORE.get(id)
if (buf[1] & 0xC0 == 0x00):
Modified: PyWireGate/trunk/knx_connector/KNX_Connector.py
===================================================================
--- PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/knx_connector/KNX_Connector.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -71,7 +71,7 @@
defaultconfig = {
'url':'ip:127.0.0.1',
'parser' : 'groupsocket',
- 'checktime' : 300
+ 'checktime' : 0
}
## check Defaultconfig Options in main configfile
Modified: PyWireGate/trunk/owfs_connector/OWFS_Connector.py
===================================================================
--- PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/owfs_connector/OWFS_Connector.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -27,8 +27,6 @@
class owfs_connector(Connector):
-
-
CONNECTOR_NAME = 'OWFS Connector'
CONNECTOR_VERSION = 0.2
CONNECTOR_LOGNAME = 'owfs_connector'
@@ -40,10 +38,11 @@
self.mutex = threading.RLock()
defaultconfig = {
- 'cycletime' : 600,
+ 'cycletime' : 60,
'server' : '127.0.0.1',
'port' : 4304
}
+
self.WG.checkconfig(self.instanceName,defaultconfig)
self.config = self.WG.config[instanceName]
@@ -52,7 +51,7 @@
## some regex for identifying Sensors and busses
self.issensor = re.compile(r"[0-9][0-9]\x2E[0-9a-fA-F]+")
- self.isbus = re.compile(r"\x2Fbus\x2E([0-9])+$", re.MULTILINE)
+ self.isbus = re.compile(r"\x2Fbus\x2E([0-9]+)$", re.MULTILINE)
owfsdir = re.findall("from \x27(.*)\x2F",str(connection))[0]
## Sensors and their interfaces
@@ -100,6 +99,7 @@
self.sensors = {}
self.start()
+
def checkConfigDefaults(self,obj,default):
try:
for cfg in default['config'].keys():
@@ -136,14 +136,15 @@
## IDLE for cycletime seconds (default 15sec)
## Fixme: maybe optimize cycletime dynamic based on busload
- self.idle(.1)
+ self.idle(5)
+
+ def _shutdown(self):
for busname in self.busmaster.keys():
if self.busmaster[busname]['readthread'] <> None:
- self.busmaster[busname]['readthread'].join()
+ if self.busmaster[busname]['readthread'].isAlive():
+ self.busmaster[busname]['readthread'].join()
-
-
def findbusmaster(self,path=""):
## search for active busses
childs = False
@@ -208,7 +209,11 @@
pass
if sensor[:2] == "81":
## this must be the Busmaster .. threre should only be one
- self.busmaster[path]['busmaster'] = sensor
+ try:
+ self.mutex.acquire()
+ self.busmaster[path]['busmaster'] = sensor.decode('ISO-8859-15')
+ finally:
+ self.mutex.release()
if sensortype not in self.supportedsensors:
self.debug("unsupported Type: %r" % sensortype)
@@ -230,7 +235,7 @@
'type':sensortype,
'cycle':cycle,
'nextrun':0,
- 'present': self.busmaster[path].get('busmaster',True),
+ 'present': self.busmaster[path].get('busmaster',u'unknown'),
'interfaces': self.supportedsensors[sensortype]['interfaces']
}
finally:
@@ -240,22 +245,29 @@
def read(self):
for busname in self.busmaster.keys():
- if not self.busmaster[busname]['readQueue'].empty():
- if not self.busmaster[busname]['readthread']:
- self.debug("Start read Thread for %s" % busname)
- threadname = "OWFS-Reader_%s" % busname
- try:
- self.mutex.acquire()
- self.busmaster[busname]['readthread'] = threading.Thread(target=self._readThread,args=[busname],name=threadname)
- self.busmaster[busname]['readthread'].start()
- finally:
- self.mutex.release()
+ if not self.isrunning:
+ break
+ if not self.busmaster[busname]['readQueue'].empty():
+ if self.busmaster[busname]['readthread'] == None:
+ self.debug("Start read Thread for %s" % busname)
+ threadname = "OWFS-Reader_%s" % busname
+ try:
+ self.mutex.acquire()
+ self.busmaster[busname]['readthread'] = threading.Thread(target=self._readThread,args=[busname],name=threadname)
+ self.busmaster[busname]['readthread'].start()
+ finally:
+ self.mutex.release()
+ else:
+ self.debug("Bus %r has empty Queue %r" % (busname,self.busmaster[busname]))
def _read(self,busname,sensor):
for iface in self.sensors[sensor]['interfaces'].keys():
+ if not self.isrunning:
+ break
if not self.sensors[sensor]['present'] and iface <> "present":
## if not present check only for present
+ self.debug("Ignore not present sensor %s on bus %s" % (sensor,busname))
continue
## make an id for the sensor (OW:28.043242a32_temperature
id = "%s:%s_%s" % (self.instanceName,sensor,iface)
@@ -281,9 +293,27 @@
if iface == "present":
if str(data) <> "1":
- self.sensors[sensor]['present'] = False
+ try:
+ self.mutex.acquire()
+ self.sensors[sensor]['present'] = False
+ finally:
+ self.mutex.release()
+ data = u""
else:
- data = self.busmaster[busname].get('busmaster',True)
+ try:
+ self.mutex.acquire()
+ self.sensors[sensor]['present'] = busname
+ data = self.busmaster[busname]['busmaster']
+ finally:
+ self.mutex.release()
+
+ nowval = self.WG.DATASTORE.get(id).getValue()
+ if nowval == data:
+ self.debug("DONT UPDATE")
+ ## dont update
+ continue
+ else:
+ print "DATA %r == %r" % (data,nowval)
if data:
self.debug("%s: %r" % (id,data))
@@ -292,18 +322,20 @@
self._addQueue(busname,sensor)
def _addQueue(self,busname,sensor):
+ if not self.isrunning:
+ return
cycletime = time.time() +self.sensors[sensor]['cycle']
self.debug("ADDED %s on %s with %s (%d)s" % (sensor,busname, time.asctime(time.localtime(cycletime)),self.sensors[sensor]['cycle']))
- ## FIXME: not present iButtons should be added to all Busmaster Queues
- #if self.sensors[sensor]['']
if self.sensors[sensor]['present']:
self.busmaster[busname]['readQueue'].put((cycletime,sensor))
else:
if 'present' not in self.sensors[sensor]['interfaces']:
+ self.debug("RETURN no present interface %s" % sensor)
return
for busmaster in self.busmaster.keys():
## add to all busmaster queues
self.busmaster[busmaster]['readQueue'].put((cycletime,sensor))
+ print "QUEUES %r: %r" % (busname,self.busmaster[busname]['readQueue'])
def _readThread(self,busname):
@@ -311,7 +343,7 @@
while self.isrunning:
while not self.busmaster[busname]['readQueue'].check():
if not self.isrunning:
- break
+ return
time.sleep(.1)
self.debug("Queue for bus %s : %r" % (busname, self.busmaster[busname]['readQueue']))
rtime, sensor = self.busmaster[busname]['readQueue'].get()
@@ -349,9 +381,11 @@
return heapq.heappop(self.queue)
def check(self):
+ self.mutex.acquire()
if len(self.queue) == 0:
return False
next = min(self.queue)
+ self.mutex.release()
if len(next)==2:
next = next[0]
else:
Modified: PyWireGate/trunk/owfs_connector/connection.py
===================================================================
--- PyWireGate/trunk/owfs_connector/connection.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/owfs_connector/connection.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -26,8 +26,6 @@
"""
-import sys
-import os
import socket
import struct
import re
Modified: PyWireGate/trunk/scheduler.py
===================================================================
--- PyWireGate/trunk/scheduler.py 2010-11-29 21:49:00 UTC (rev 178)
+++ PyWireGate/trunk/scheduler.py 2010-12-02 12:19:36 UTC (rev 179)
@@ -26,7 +26,7 @@
-class scheduler:
+class scheduler(object):
def __init__(self,parent):
self._parent = parent
if parent:
@@ -67,8 +67,15 @@
if __name__ == '__main__':
- s = scheduler(False)
- time.sleep(155)
+ s = apscheduler()
+ s.start()
+ import time
+ def test():
+ print "TIME: %s" % time.asctime()
+ test()
+ s.add_cron_job(test,minute='*/3',second='0')
+ while True:
+ pass
s.shutdown()
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|
|
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...
[truncated message content] |
|
From: <ma...@us...> - 2011-05-09 17:09:35
|
Revision: 325
http://openautomation.svn.sourceforge.net/openautomation/?rev=325&view=rev
Author: mayerch
Date: 2011-05-09 17:09:29 +0000 (Mon, 09 May 2011)
Log Message:
-----------
Route inspected values from the Logic Server to the Logic Editor
Modified Paths:
--------------
PyWireGate/trunk/logic_editor/LogicEditor.py
PyWireGate/trunk/logic_server/LogicServer.py
Modified: PyWireGate/trunk/logic_editor/LogicEditor.py
===================================================================
--- PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-09 15:19:30 UTC (rev 324)
+++ PyWireGate/trunk/logic_editor/LogicEditor.py 2011-05-09 17:09:29 UTC (rev 325)
@@ -33,6 +33,7 @@
import time
thisPath = '/'
+LOGIC = None
class logic_editor(ConnectorServer):
CONNECTOR_NAME = 'Logic Editor'
@@ -42,6 +43,8 @@
self._parent = parent
if parent:
self.WG = parent.WG
+ global LOGIC
+ LOGIC = self._parent.connectors['LogicServer']
global thisPath
thisPath = parent.scriptpath + '/logic_editor'
else:
@@ -121,10 +124,16 @@
self.send_header("Content-type", 'text/plain')
self.send_header("Access-Control-Allow-Origin", "*")
self.end_headers()
+ # FIXME: BIG, Big, big memory and CPU leak! A created Queue must be
+ # removed later, or the LogicServer will continue to fill it, even if
+ # no page will be listening anymore!
+ l = LOGIC.createQueue( None, None, None ) # get everything!
while True:
- self.wfile.write( "new line\n" )
+ #self.wfile.write( "new line\n" )
+ m = l.get()
+ self.wfile.write( "|%s|%s|%s|%s|\n" % m )
self.wfile.flush()
- time.sleep( 1.0 )
+ #time.sleep( 1.0 )
else:
self.path = "%s%s" % ( thisPath, self.path )
return SimpleHTTPServer.SimpleHTTPRequestHandler.do_GET(self)
Modified: PyWireGate/trunk/logic_server/LogicServer.py
===================================================================
--- PyWireGate/trunk/logic_server/LogicServer.py 2011-05-09 15:19:30 UTC (rev 324)
+++ PyWireGate/trunk/logic_server/LogicServer.py 2011-05-09 17:09:29 UTC (rev 325)
@@ -19,7 +19,7 @@
from connector import Connector
import LogicImportJSON
import TaskManager
-
+import Queue
import time
## Load logik.json
@@ -46,6 +46,7 @@
CONNECTOR_NAME = 'Logic Server'
CONNECTOR_VERSION = 0.1
CONNECTOR_LOGNAME = 'logic_server'
+ queues = []
def __init__(self,parent, instanceName):
self._parent = parent
self.WG = parent.WG
@@ -81,5 +82,14 @@
t.start()
while True:
for m in iter( t.getMessage, None ):
- print m
- time.sleep( 0.1 )
\ No newline at end of file
+ for q in self.queues:
+ if (q[0] == None or q[0] == m[0]) and (q[1] == None or q[1] == m[1]):
+ for b in m[2]:
+ if q[2] == None or q[2] == b:
+ q[3].put( (m[0], m[1], b, m[2][b]) )
+ time.sleep( 0.1 )
+
+ def createQueue(self, taskFilter, logicFilter, blockFilter):
+ q = Queue.Queue()
+ self.queues.append( (taskFilter, logicFilter, blockFilter, q) )
+ return q
\ No newline at end of file
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|