nodo-domotica.nl

KAKU bedienen via python

Alles over gebruiks van een wbeserver met de Nodo

KAKU bedienen via python

Berichtdoor hades123 » 31 okt 2011, 20:12

Hoi,

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 :D .
hades123
 
Berichten: 2
Geregistreerd: 31 okt 2011, 09:14

Re: KAKU bedienen via python

Berichtdoor Paul » 16 dec 2011, 08:56

Goed werk. Graag wil ik een klein verzamelingetje aanleggen van snippets code voor diverse handige taken. Kijk nog eens naar je code als de nieuwe release uit is, daar heb je de mogelijkheid in om al je commando's over IP te verzenden.
Groeten Paul
Paul
 
Berichten: 1152
Geregistreerd: 31 aug 2011, 20:33


Keer terug naar Webserver

Wie is er online?

Gebruikers in dit forum: Geen geregistreerde gebruikers. en 1 gast