• You've been granted Beta access to this site, allowing you to explore some of the new features while they're still under construction. More information can be found in the Beta forum.

EventGhost script works, but freezes EG if deleted or if EG is closed?!?

etc6849

Senior Member
I'm new to EventGhost (EG), but I thought I'd start with a simple python script (aka plugin).

To start the project, since I'd never used Python, I thought I would use a tcp listener that would wait until Premise connected, then echo back anything Premise sent. This test script works and gives no errors! However, it crashes EG if I try to delete the plugin or try to close EG!?! Even if there are no connections, EG crashes when I delete the plugin or try to close.

What am I doing wrong? I'm hesitant to go any further on the plugin until I understand what's causing EG to crash. EG gives no errors either, just freezes.

I know for sure Premise acts as a tcp socket and have written a perl script before to listen for a tcp connection and then send data. The perl script worked just fine. The eventual goal was full two-way tcp communications with Premise so that EG or Premise events could be triggered. EG must be the TCP listener waiting for the connection.

Code:
import eg
from socket import *
eg.RegisterPlugin(
    name = "Premise",
    author = "etc6849",
    version = "1.0",
    kind = "other",
    description = "Sends events to Premise by listening on a TCP socket for Premise to connect."
)
class MyNewPlugin(eg.PluginBase):
    def __init__(self):
	    print "Premise plug-in initialized..."
	    #self.AddAction(SendPacket)
	   
    def __start__(self):
	    print "Premise plug-in started..."
	    myHost = ''
	    myPort = 5005
	   
	    s = socket(AF_INET, SOCK_STREAM)    # create a TCP socket
	    s.bind((myHost, myPort))		    # bind it to the server port
	    s.listen(1)						 # allow 1 connection
	    while 1:
		    # wait for next client to connect
		    connection, address = s.accept() # connection is a new socket
		    print "SYS server at ", address, " connected."
		    while 1:
			    data = connection.recv(1024) # receive up to 1K bytes
			    if data:
				    connection.send('echo -> ' + data)
			    else:
				    break
		    connection.close()			  # close socket
    def __stop__(self):
	    connection.close()
	    print "SYS connection is closed."
    def __close__(self):
	    connection.close()
	    print "SYS connection is closed."
 

etc6849

Senior Member
Ok, so this xmlSocket plugin stolen from here works. It starts the socket connection in it's own thread. I'll probably steal the structure from it as I've never needed to use threads before.


Code:
eg.RegisterPlugin(
    name = "xmlSocket",
    author = "krambriw",
    version = "0.0.2",
    guid = '{DA3F5444-F359-4FEC-AF59-876BB152CC29}',
    canMultiLoad = False,
    description = "send and receive xml messages.",
)
import eg
import select, time
import asynchat
import xml.dom.minidom as xmldom
from socket import *
from threading import Event, Thread
class xmlSocket(eg.PluginBase):
    def __init__(self):
	    print "Init..."
	   
    def __start__(self, host, port):
	    self.theSock = socket(AF_INET, SOCK_STREAM)
	    self.host = host
	    self.port = port
	    self.data = ''
	    bound = 0
	    while bound == 0 :
		    bound = 1
		    try :
			    addr = (self.host, self.port)
			    self.theSock.bind(addr)
		    except :
			    bound = 0
			    print "Socket error"
	    self.theSock.listen(5)
	    print "xmlSocket plugin, bound to port " + str(self.port)
	    print "xmlSocket is started"
	    self.input = [self.theSock]
	    self.output = []
	    self.errored = []
	    self.mainThreadEvent = Event()
	    mainThread = Thread(target=self.main, args=(self.mainThreadEvent,))
	    mainThread.start()

    def __stop__(self):
	    print "Stopping...please wait..."
	    self.mainThreadEvent.set()
			   
    def collect_incoming_data(self, data):
	    """
		    Everytime we collect data we add the data to the string self.data
		    (Untill we encounter a terminator (\0)
	    """
	    self.data = self.data + data #.decode("utf-8")
	    self.found_terminator()

    def found_terminator(self):
	    """
		    Terminator Character has been found !
		    So the Xml string should be ok, we start parsing datas
	    """
	    # The complete XML string
	    line = self.data
	    # Reseting data for more data to come ...
	    self.data = ''
	    # Trying to parse
	    self.doParse = 1
	    # If string is not really XML this crash :
	    line = "<?xml version='1.0' encoding='utf-8' ?>"+line
	    #print line
	    #line = unicode(line,'utf-8') #.encode('utf-8')
	    #print line
	    try:
		    # Trying to parse data
		    self.doc = xmldom.parseString(line)
	    except:
		    # Sending error message to inform user
		    print "This is not a valid XML string"
		    #Stop parsing
		    self.doParse = 0
	    if self.doParse:
		    # really parsing Data
		    self.parseData (data=self.doc)
		    self.doc.unlink()

    def parseData(self,data):
	    """
		    OK terminator was found, and @data is parsed XML !
		    We look for the node name and dispatch information to other methods
	    """
	    # Data must have child nodes
	    if len(data.childNodes):
		    # The only node
		    n = data.childNodes[0]
		    # And the name of the node !
		    # The name defines the function
		    node = str(n.nodeName)
		    # All atributes of the node
		    attrs = {}
		    # Looping the attributes
		    for p in n.attributes.items():
			    attrs[p[0]] = p[1].encode("utf-8")
		    # if there is data inside (like CDATA ...)
		    texte = ""
		    # Getting inside text
		    if len(n.childNodes):
			    if n.nodeType == n.TEXT_NODE:
				    texte = n.childNodes[0].nodeValue				   
			    else:
				    for p in n.childNodes:
					    texte += p.toxml()
				  
			    texte = texte.encode("utf-8")
		    # Right now, just print the content
		    print "The node is: ", node

# Main Loop
    def main(self,mainThreadEvent):
	    self.client = None
	    while not self.mainThreadEvent.isSet():
		    inputready,outputready,errored = select.select(
											    self.input,
											    self.output,
											    self.errored,
											    1
											 )
		    for s in inputready:
			    if s == self.theSock:
				    self.client, address = self.theSock.accept()
				    print "Client added: ", self.client, address
				    if not self.input.count(self.client)>0:
					    self.input.append(self.client)
			    else:
				    data = s.recv(4096)
				    tempConn = self.input[1:len(self.input)]
				    if data:
					    print "Data: ", data
					    self.collect_incoming_data(data)
					    for i in tempConn:
						    i.send(str(i.getsockname()[0]) + ": " + data)
					    eg.TriggerEvent(str(s.getpeername()) + ": " + data)
				    else:
					    if self.input.count(s)>0:
						    self.input.remove(s)
						    print "Client removed: ", s
	    self.theSock.close()
	    print "Main thread has ended"

    def Configure(
	    self,
	    host = '0.0.0.0',
	    port = 1024
	 ):
	    panel = eg.ConfigPanel(self)
	    mySizer = wx.GridBagSizer(5, 5)
	    hostControl = wx.TextCtrl(panel, -1, host)
	    mySizer.Add(
		    wx.StaticText(
			    panel,
			    -1,
			    "Host ip or blank: "
		    ),
		   (2,0)
	    )
	    mySizer.Add(hostControl,(2,1))
	    portControl = panel.SpinIntCtrl(port, 1024, 1024)
	    portControl.SetInitialSize((60,-1))
	    mySizer.Add(
		    wx.StaticText(
			    panel,
			    -1,
			    "Port number: "
		    ),
		   (3,0)
	    )
	    mySizer.Add(portControl,(3,1))
	    panel.sizer.Add(mySizer, 0, flag = wx.EXPAND)
	    while panel.Affirmed():
		    panel.SetResult(
			    hostControl.GetValue(),
			    portControl.GetValue()
			    )
 
Top