Notice: This forum has been recovered from an old backup, so some content, links, and dates may be outdated. The forum is currently read-only while we restore sign-in and registration functionality. Details

If you find this forum valuable and would like to help keep it online, donations to help cover hosting and domain costs are greatly appreciated, but never expected. You can support the forum through Buy Me a Coffee or Ko-fi. Thank you for helping preserve the EventGhost community.

Network Event Receiver

Questions and comments specific to a particular plugin should go here.
Post Reply
User avatar
Melloware
Plugin Developer
Posts: 86
Joined: Mon May 12, 2008 6:18 pm

Network Event Receiver

Post by Melloware »

I have been stumped trying to figure this out and I have done tons of TCP socket programming. I am trying to use the Network Event receiver. I have tried just using Putty over Telnet and connecting to EventGhost on 127.0.0.1 port 1024 and sending it the proper initialization command of "quintessence" and i cannot get it to send me back the cookie. I have tried the following combination using both Putty and a .NET TCP socket and nothing is returned and i get a read timeout.

quintessence
quintessence\n
quintessence\n\r

Using EG 0.3.6 latest build but also tried it with 0.3.5.

Any help would be appreciated, i am tearing my hair out.

To verify try it with Putty or any other Telnet client you prefer.
Last edited by Melloware on Thu Sep 04, 2008 8:15 pm, edited 2 times in total.
-----------------------------------
Melloware Inc.
EventPhone iPhone Application
Intelliremote - HTPC Remote Application
-----------------------------------
User avatar
Melloware
Plugin Developer
Posts: 86
Joined: Mon May 12, 2008 6:18 pm

Re: Network Event Receiver

Post by Melloware »

OK I figured out the problem and I think this has to be a bug. The only way I can get it to work from Putty Telnet or .NET TCP Socket is to change the Network Event Receiver init.py script to the following...

Code: Select all

line = line.strip()
if line == "quintessence":
without the line = line.strip() the code NEVER works. As soon as that strip() is in there it works. I don't know if this is a bug or not but without this line of code i cannot get any other TCP socket to actually correctly send the quintessence word. So I have no idea how the NetRemote or Girder socket connection actually works.

Can anyone else verify?
-----------------------------------
Melloware Inc.
EventPhone iPhone Application
Intelliremote - HTPC Remote Application
-----------------------------------
User avatar
jinxdone
Plugin Developer
Posts: 443
Joined: Tue Jan 02, 2007 4:08 pm

Re: Network Event Receiver

Post by jinxdone »

I have written a little standalone network event sender, but I wrote it in python and I simply copied over the sender code piece from eventghost, it works without any problems.


I think if there is anything in there besides what asyncore is using as a "command terminator" (in this case it is "\n" == LF == 0x0A), it wont work because it tries to compare "quintessence" with "quintessence"+0x0D for example (if you try to feed it quintessence + CR + LF). Telnet may not work since it may be sending something like quintessence + CR + NUL.


Have you looked with a packet sniffer what actually goes across the network?



Either way you are right, using the strip() function in EG to clear any crud on either side of the magic string might not be a bad idea if it eases interfacing with programs written in other languages and/or running on other os.


-jinxdone
User avatar
Melloware
Plugin Developer
Posts: 86
Joined: Mon May 12, 2008 6:18 pm

Re: Network Event Receiver

Post by Melloware »

Hey thanks for commenting! For a while there i thought i was crazy.

You are exactly correct. I have looked at it with a packet sniffer and when you send TCP commands from any other connection like Putty, Telnet, .NET, Java it will not work without the strip because of extra characters like NULL terminator etc. So the only client that works for Network Receiver is a client that uses the asyncore package. What is funny is if you look at stage 2 and stage 3 in Network Event Receiver is does the line.strip() which is what gave me the idea in the first place. The only place it is not in the stage1 method at the very first handshake.

I guess to still make it work with current and new clients the line could become

Code: Select all

if (line == "quintessence") or (line.strip() == "quintessence"):
Or something like that. I don't know the exact Python syntax.
-----------------------------------
Melloware Inc.
EventPhone iPhone Application
Intelliremote - HTPC Remote Application
-----------------------------------
User avatar
Melloware
Plugin Developer
Posts: 86
Joined: Mon May 12, 2008 6:18 pm

Re: Network Event Receiver

Post by Melloware »

Well it turns out i needed more mods than just that one line so I am just copying that plugin as a starting point and modding it for my own needs. So I guess its NOT a bug since the Network Receiver works for Girder and NetRemote.

Thanks,
-----------------------------------
Melloware Inc.
EventPhone iPhone Application
Intelliremote - HTPC Remote Application
-----------------------------------
User avatar
Bitmonster
Site Admin
Posts: 2239
Joined: Mon Feb 06, 2006 10:28 pm

Network Event Receiver

Post by Bitmonster »

Yes, the plugin emulates all bugs of Girder, therefore we should not change it.
Please post software-related questions in the forum - PMs will only be answered, if really private, thanks!
colicab
Posts: 1
Joined: Tue Feb 26, 2013 1:14 pm

Re: Network Event Receiver

Post by colicab »

I have written a little standalone network event sender, but I wrote it in python and I simply copied over the sender code piece from eventghost, it works without any problems.
I was browsing for a solution to my problem and I came across this post. Would it be possible to share this script? I could very much appreciate it
I'm trying to fully automate the downloading/renaming/moving of my series.

My current setup:

QNAP NAS: downloads series automatically with Transmission/FlexGet wit RSS feed

HPTC: Win 7 w/ EventGhost
EG 1) First trigger (Directory Watcher 1): triggers when new episodes are completed on NAS --> download subtitles with Auto-Sub
QNAP 2) Custom python script to move files when subtitles are downloaded --> moves files to input folder of second trigger
EG 3) Second trigger: activates theRenamer to rename and move episode to my multimediafolder on QNAP
EG 4) Update XBMC Library


For the moment this works until I restart or when (for some reason) the mapped network drive that both event triggers watch becomes unactive.
That's why I would like to have my QNAP act as a Network Event Sender to triggers parts 1) and 3) so I don't rely on my Win7 PC to properly watch these folders

I looked at the init.py script for the Network Sender Plugin but this one will only work with non-standard module installed. Also, I'm just a novice when it comes down to Python scripting and network stuff. That's why this standalone script really sounds great.

Jinxdone, would you want to share it?


Thnx!
miljbee
Experienced User
Posts: 146
Joined: Fri Mar 27, 2009 1:29 pm
Location: Orl├®ans, France

Re: Network Event Receiver

Post by miljbee »

This might not be the solution you would expect, but this should meet your needs :

you can add to eventghost the WebServer plugin. Once done, EG will be able to receive events using standard http GET requests.

Sending HTTP requests from python is easy. You can find an exemple here :

viewtopic.php?f=2&t=3226&hilit=urllib

From what I remember, the url would be something like :

Code: Select all

http://egHost:webserverPort/index.html?eventSuffix&payloadItem1&payloadItem2...
I think you can use a blank html file for the index
miljbee
TCP Events : A Better Network Event Sender/Receiver Plugin.
The Network Event Sender/Receiver in C#
Get events in EG from Google Calendar.
neorules
Posts: 15
Joined: Sun Jan 10, 2010 4:05 pm

Re: Network Event Receiver

Post by neorules »

How do I get this to work on a Raspberry Pi?

Code: Select all

# -*- coding: utf-8 -*-
#
# This file is a plugin for EventGhost.
# Copyright (C) 2005-2009 Lars-Peter Voss <[email protected]>
#
# EventGhost is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License version 2 as published by the
# Free Software Foundation;
#
# EventGhost 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.org/licenses/>.

import eg

eg.RegisterPlugin(
    name = "Network Event Sender",
    version = "1.0",
    author = "Bitmonster",
    guid = "{B4F0DAFE-2E0B-47F3-A155-ED72C7A4E270}",
    description = (
        "Sends events to an Network Event Receiver plugin through TCP/IP."
    ),
    canMultiLoad = True,
    icon = (
        "iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/"
        "AAAACXBIWXMAAAsSAAALEgHS3X78AAAAB3RJTUUH1gIQFgQOuRVmrAAAAVRJREFUOMud"
        "kjFLw2AQhp+kMQ7+jJpCF+ni1lFEwUXq5g+wgiCCgoNUrG5Oltb2DygGYwUXwbmbg+Li"
        "IhSHhobaora2MZTGoQb5aBLFd/u4u/fuufskApQ92DWAFOEqKSHB1OzMHJoW8w1aloVR"
        "1tNhBmhajPnlQ9/Yzdk2AKEGkiQBkExOAS4wfFcqDwwGg6FBGGv++IiF5DiOZPHcnKDb"
        "+6T9YQs5iscajSd8p2jUqhhlnZfXYfeIMgaA67o/CNF4gsW1C1RVJHKcPlfFJQCaZt23"
        "geKxqqpCYnpSYL2/feIbleuTrZErjCwxEpGpNzp0ew7tjshaKOb8BsgIBnePdXAlz05g"
        "XV1ZEyplWaZQzGUVL8lx+qhv7yM78NRqtYJ30KhVucynAq8AoJ+fBhqUjLKe/uXPZzI7"
        "e/tBBumN9U1s2/at9FiBQANM0+S/UsL4/qIvHUp+5VOP+PAAAAAASUVORK5CYII="
    ),
)

import wx
import socket
from hashlib import md5


class Text:
    host = "Host:"
    port = "Port:"
    password = "Password:"
    tcpBox = "TCP/IP Settings"
    securityBox = "Security"
    class Map:
        parameterDescription = "Event name to send:"



class NetworkSender(eg.PluginBase):
    text = Text

    def __init__(self):
        self.AddAction(Map)


    def __start__(self, host, port, password):
        self.host = host
        self.port = port
        self.password = password


    def Configure(self, host="127.0.0.1", port=1024, password=""):
        text = self.text
        panel = eg.ConfigPanel()
        hostCtrl = panel.TextCtrl(host)
        portCtrl = panel.SpinIntCtrl(port, max=65535)
        passwordCtrl = panel.TextCtrl(password, style=wx.TE_PASSWORD)

        st1 = panel.StaticText(text.host)
        st2 = panel.StaticText(text.port)
        st3 = panel.StaticText(text.password)
        eg.EqualizeWidths((st1, st2, st3))
        tcpBox = panel.BoxedGroup(
            text.tcpBox,
            (st1, hostCtrl),
            (st2, portCtrl),
        )
        securityBox = panel.BoxedGroup(
            text.securityBox,
            (st3, passwordCtrl),
        )

        panel.sizer.Add(tcpBox, 0, wx.EXPAND)
        panel.sizer.Add(securityBox, 0, wx.TOP|wx.EXPAND, 10)

        while panel.Affirmed():
            panel.SetResult(
                hostCtrl.GetValue(),
                portCtrl.GetValue(),
                passwordCtrl.GetValue()
            )


    def Send(self, eventString, payload=None):
        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        #self.socket = sock
        sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        sock.settimeout(2.0)
        try:
            sock.connect((self.host, self.port))
            sock.settimeout(1.0)
            # First wake up the server, for security reasons it does not
            # respond by it self it needs this string, why this odd word ?
            # well if someone is scanning ports "connect" would be very
            # obvious this one you'd never guess :-)

            sock.sendall("quintessence\n\r")

            # The server now returns a cookie, the protocol works like the
            # APOP protocol. The server gives you a cookie you add :<password>
            # calculate the md5 digest out of this and send it back
            # if the digests match you are in.
            # We do this so that no one can listen in on our password exchange
            # much safer then plain text.

            cookie = sock.recv(128)

            # Trim all enters and whitespaces off
            cookie = cookie.strip()

            # Combine the token <cookie>:<password>
            token = cookie + ":" + self.password

            # Calculate the digest
            digest = md5(token).hexdigest()

            # add the enters
            digest = digest + "\n"

            # Send it to the server
            sock.sendall(digest)

            # Get the answer
            answer = sock.recv(512)

            # If the password was correct and you are allowed to connect
            # to the server, you'll get "accept"
            if (answer.strip() != "accept"):
                sock.close()
                return False

            # now just pipe those commands to the server
            if (payload is not None) and (len(payload) > 0):
                for pld in payload:
                    sock.sendall(
                        "payload %s\n" % pld.encode(eg.systemEncoding)
                    )

            sock.sendall("payload withoutRelease\n")
            sock.sendall(eventString.encode(eg.systemEncoding) + "\n")

            return sock

        except:
            if eg.debugLevel:
                eg.PrintTraceback()
            sock.close()
            self.PrintError("NetworkSender failed")
            return None


    def MapUp(self, sock):
        # tell the server that we are done nicely.
        sock.sendall("close\n")
        sock.close()



class Map(eg.ActionWithStringParameter):

    def __call__(self, mesg):
        res = self.plugin.Send(eg.ParseString(mesg))
        if res:
            eg.event.AddUpFunc(self.plugin.MapUp, res)
        return res

This code is from EventGhost Plugin
It would be great if we had this function in the Raspberry Pi to speak with EventGhost

But I'm not good at Pyhton

/Jens
krambriw
Plugin Developer
Posts: 2570
Joined: Sat Jun 30, 2007 2:51 pm
Location: Stockholm, Sweden
Contact:

Re: Network Event Receiver

Post by krambriw »

It is not too complicated actually. In the RaspBerry, you can add a python script that captures the data of interest and sends it out on your network via UDP. I configured a cronjob in the Raspberrys to read some OneWire sensors as the example below shows. In EG you then simply add the 'Broadcaster' plugin and you will recieve the events.

I have my two Raspberry's talking to EG using python scripts (one as mentioned for reading OneWire sensors, the other script in the other Pi for Z-Wave events).

This is the script used for OneWire readings (simplified):

Code: Select all

#!/usr/bin/env python

# ow_read.py
# This script sends the measured light and temperature.
# To edit the list of cronjobs: sudo crontab -e

import time
import os
import sys
import socket

zone = '192.168.10.255'
port = 33334
addr = (zone, port)

sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) # Create socket
sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
sock.settimeout(2.0)

eventString = 'Measurements: '
payload = []

for i in range(5):
    try:
        if i > 0:
            time.sleep(1.0) 
        p = os.popen('/opt/owfs/bin/owread -s localhost:4304 28.AC2A95040000/temperature')
        res = p.read()
        payload.append(float(str(res).strip()))
        break
    except IOError:
        if (i == 4):
            payload.append('IOError')
            time.sleep(1.0) 
            break

for i in range(5):
    try:
        if i > 0:
            time.sleep(1.0) 
        p = os.popen('/opt/owfs/bin/owread -s localhost:4304 20.5FDC0C000000/volt.A')
        res = p.read()
        payload.append(float(str(res).strip()))
        break
    except IOError:
        if (i == 4):
            payload.append('IOError')
            time.sleep(1.0) 
            break

sock.sendto(eventString + '&&' + str(payload), addr)
sock.close()


The key points are
- you have to feed the script with your data of interest
- you have to trigger the script execution either on event, on time (as I did with a cronjob) or you could simply make a loop doing some polling
- you should eventually put your data in the payload and then in EG, extract that and evaluate further

But please, if you like to continue the discussion, start a new topic in a more appropriate part of the forum, like in the 'Coding Corner'.

Best regards, Walter
Post Reply