Ik ben dit weekend eens bezig geweest een python script in elkaar te zetten om mijn KAKU apparatuur te kunnen aansturen/uitlezen zonder eventghost. Dit is de eerste keer dat ik met python iets script dus op of aanmerkingen/verbeteringen zijn welkom

Mijn python script werkt met sockets, dus vrij universeel aan te sturen. Ik gebruik zelf PHP. Als de nodo controller zelf iets detecteerd op de compoort (afstandsbediening of inbouw zender oid), stuurt het script zelf een request naar een bepaalde url met het bericht geencodeerd in de GET string.
Ik werk zelf met een Debian installatie
Benodigdheden:
python-serial (http://pyserial.sourceforge.net/)
- Code: Selecteer alles
apt-get install python-serial
ser.py
- Code: Selecteer alles
import time
import serial
import threading
import socket
import base64
import urllib
import urllib2
# IP socket thread
class ClientThread ( threading.Thread ):
# Override Thread's __init__ method to accept the parameters needed:
def __init__ ( self ):
self.data = 'No Data'
threading.Thread.__init__ ( self )
def run ( self ):
self.accept()
def retdata ( self ):
return self.data
def setdata ( self, text ):
self.data = text
def accept ( self ):
while True:
self.channel, self.details = server.accept()
self.receive()
def receive ( self ):
print 'Received connection:', self.details [ 0 ]
self.data = self.channel.recv ( 1024 )
self.channel.close()
print 'receive: ', self.data
print 'Closed connection:', self.details [ 0 ]
# Serial listen thread
class SerialThread ( threading.Thread ):
def __init__ ( self ):
self.ser = serial.Serial(port='/dev/ttyUSB3',baudrate=19200)
self.ser.open()
self.text = 'No Data'
self.url = 'http://127.0.0.1/sock.php'
self.out = ''
self.pollserial = True
threading.Thread.__init__ ( self )
def run ( self ):
print 'Serial init'
self.read()
def write ( self ):
print 'WRITE ' + self.text
self.ser.write( self.text )
def settext ( self, text ):
self.text = text
print 'text set to: ',self.text
def read ( self ):
while self.pollserial & self.ser.isOpen():
while self.ser.inWaiting() > 0:
self.out += self.ser.read(1)
if self.out != '':
values = { 'str' : base64.b64encode(self.out) }
data = urllib.urlencode(values)
fullurl = self.url + '?' + data
filehandle = urllib2.urlopen(fullurl)
filehandle.close()
print 'READ ' + self.out
self.out = ''
time.sleep(1)
def close ( self ):
self.ser.close()
input = ''
server = socket.socket ( socket.AF_INET, socket.SOCK_STREAM )
server.bind ( ( '', 50007 ) )
server.listen ( 5 )
#channel, details = server.accept()
ser=SerialThread()
ser.start()
ip=ClientThread()
ip.start()
while True:
#x=0;
if ip.retdata() != 'No Data':
ser.settext(ip.retdata())
ser.write()
ip.setdata('No Data')
#print x
time.sleep(1)
om deze te starten (als root):
- Code: Selecteer alles
python2.6 ser.py &
Zoals in de code te zien is luistert het script op poort 50007 naar verbindingen en stuurt het zelf opdrachten naar http://127.0.0.1/sock.php
sock.php
- Code: Selecteer alles
<?php
#Stuur commando naar de NODO controller op basis van _GET string "a1"
if (isset($_GET["a1"])){
$fp = fsockopen("localhost", 50007, $errno, $errstr, 10);
if (!$fp){
echo $errstr." (".$errno.") <br>\n";
} else {
if($_GET["a1"] == "on"){
$out = "sendnewkaku a1,16;";
}
if($_GET["a1"] == "off"){
$out = "sendnewkaku a1,off;";
}
fwrite($fp, $out);
fclose($fp);
}
}
#Het python script stuurt een get request met daarin de base64 encoded string van het ontvangen
commando.
if (isset($_GET["str"])) {
#Schrijf ontvangen string in logfile (even aanmaken en chmod 777)
$logfile = "/var/www/log.txt";
$fh = fopen($logfile, 'a+') or die("Kan logfile niet openen");
$strdata = base64_decode($_GET["str"]);
fwrite($fh,$strdata);
fclose($fh);
#Op basis van het ontvangen commando iets terug sturen naar de NODO
$strdata = str_replace(", ",";",$strdata);
$arr = explode(";",$strdata);
$fp = fsockopen("localhost", 50007, $errno, $errstr, 10);
if (!$fp){
echo $errstr." (".$errno.") <br>\n";
} else {
switch (trim($arr[2])){
case "Event=(NewKAKU 0x1FDCB80,Off)":
$out = "sendnewkaku a1,Off;";
break;
case "Event=(NewKAKU 0x1FDCB80,On)":
$out = "sendnewkaku a1,16;";
break;
default:
$out = 'No Data';
}
fwrite($fp, $out);
fclose($fp);
}
}
?>
<html>
<head>
<title>test</title>
</head>
<body>
<a href="?a1=on">on</a><br><a href="?a1=off">Off</a>
</body>
</html>
nog even een logfiletje aanmaken tbv de verstuurde data. Handig bij debuggen.
- Code: Selecteer alles
touch /var/www/log.txt
chmod 777 /var/www/log.txt
Zoals te zien is valt er nog een hoop te verbeteren aan de netheid van de code en ook de frontend van het php script, maar ik heb er maar voor gekozen dit alvast met jullie te delen
