mqttWebServer.py 2.89 KB
Newer Older
Peter-Bernd Otte's avatar
Peter-Bernd Otte committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
#!/usr/bin/python3

import json
import time
#from datetime import datetime
import paho.mqtt.client as paho
#import os
#import numbers
import parse
from http.server import HTTPServer, BaseHTTPRequestHandler

broker="localhost"
HTTPport = 8000
HTTPhost = '' # possible: '', 'localhost', DNS-Name or IP address


mlast = {}

def on_connect(client, userdata, flags, rc):
  if rc==0:
    print("MQTT connected OK. Return code", rc)
    client.subscribe("#")
    print("MQTT: Subscribed to all topics")
  else:
    print("Bad connection. Return code=",rc)

def on_disconnect(client, userdata, rc):
  if rc != 0:
    print ("Unexpected MQTT disconnection. Will auto-reconnect")

def on_message(client, userdata, message):
    global mlast
    t = time.time()
    m = message.payload.decode("utf-8")
#    print("received:",str(m), message.topic)

    # the lambda in loads is for converting the object name into a int, if appropiate
    j = json.loads(m, object_hook=lambda d: {int(k) if k.lstrip('-').isdigit() else k: v for k, v in d.items()})
#    print ("Topic:",message.topic,"JSON",j)
    if type(j) is not dict: #anpassen, falls es keine Zeitinfo hat
      j={'v':j,'time':t}
    if t-j['time'] > 10: # corrects the time of too much in the future
      j['time'] = t

    mlast[message.topic] = j

client= paho.Client("actor")
client.on_message=on_message
client.on_connect = on_connect
client.on_disconnect = on_disconnect

print("connecting to broker ",broker)
client.connect(broker)
client.loop_start() #start loop to process received messages in separate thread
print ("MQTT Loop started.")


class SimpleHTTPRequestHandler(BaseHTTPRequestHandler):
    def do_GET(self):
        self.send_response(200)
        self.send_header("Content-type", "text/json")
        self.end_headers()
        # self.path equals GET Parameter: "/foo/bar/".
        erg = parse.parse("/{topic}/set?{value:d}", self.path)
        if not erg: erg = parse.parse("/{topic}", self.path)
        #print(erg)
        if erg and erg['topic'] in mlast:
          if 'value' in erg:
            print("publish: ",erg['topic'],"value",erg['value'])
            client.publish(erg['topic']+"/set", erg['value'], qos=1, retain=False)  # send command to Relais
            self.wfile.write(str.encode('{"result":"sucess", "topic":"'+erg['topic']+'", "value":'+str(erg['value'])+'}'))
          else:
            self.wfile.write(str.encode("/*You accessed path: {}*/\n{}".format(erg['topic'],
                                        json.dumps(mlast[erg['topic']]) )) )
        else:
          self.wfile.write(str.encode("\n{}".format(json.dumps(mlast) )) )

try:
  httpd = HTTPServer((HTTPhost, HTTPport), SimpleHTTPRequestHandler)
  print("Server started on port {} and host {}".format(HTTPport, HTTPhost))
  httpd.serve_forever()

except KeyboardInterrupt:
    print ('^C received, shutting down the web server')
    httpd.server_close()
    client.disconnect()
    client.loop_stop()