HTTP LIstner plugin stransformed to HTTPS Listner

Python and python framework

Moderator: leecollings

Post Reply
pipiche
Posts: 2016
Joined: Monday 02 April 2018 20:33
Target OS: Raspberry Pi / ODroid
Domoticz version: beta
Location: France
Contact:

HTTP LIstner plugin stransformed to HTTPS Listner

Post by pipiche »

I'm trying to develop a plugin listening on an HTTPS connection.

In such I took the plugin example in plugins/examples/HTTP Listner.py

And I did change HTTP by HTTPS on line 40 and line 95.

Basically the plugin crashes after the first try of establishing a connection


Few questions:
(1) Is HTTPS is supported on the Python Framework ?
(2) If so are you using the same SSL certificate as Domoticz to establish the SSL connection ?
(3) What should I do to make it work ?

I would really appreciate your support
May 21 00:39:20 rasp domoticz[2047]: Status: (Listner on HTTPS) Entering work loop.
May 21 00:39:20 rasp domoticz[2047]: Status: (Listner on HTTPS) Initialized version 1.0.0, author 'dnpwwo'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Debug logging mask set to: PYTHON PLUGIN QUEUE IMAGE DEVICE CONNECTION MESSAGE ALL
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'HardwareID':'15'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'HomeFolder':'/var/lib/domoticz/plugins/HTTPListener/'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'StartupFolder':'/usr/share/domoticz/beta-domoticz/'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'UserDataFolder':'/var/lib/domoticz/'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Database':'/var/lib/domoticz/domoticz.db'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Language':'en'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Version':'1.0.0'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Author':'dnpwwo'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Name':'Listner on HTTPS'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Port':'8008'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Key':'HTTPListen'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'Mode6':'File'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'DomoticzVersion':'2020.2 (build 12017)'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'DomoticzHash':'d66b49520'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) 'DomoticzBuildTime':'2020-05-04 15:41:20'
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Device count: 0
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Pushing 'ProtocolDirective' on to queue
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Pushing 'ListenDirective' on to queue
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Leaving on start
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Processing 'ProtocolDirective' message
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Protocol set to: 'HTTPS'.
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Processing 'ListenDirective' message
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Transport set to: 'TCP/IP', :8008.
May 21 00:39:20 rasp domoticz[2047]: (Listner on HTTPS) Listen directive received, action initiated successfully.


May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Pushing 'onHeartbeatCallback' on to queue
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Processing 'onHeartbeatCallback' message
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Calling message handler 'onHeartbeat'.
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Pushing 'ProtocolDirective' on to queue
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Pushing 'ConnectDirective' on to queue
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Processing 'ProtocolDirective' message
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Protocol set to: 'HTTPS'.
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Processing 'ConnectDirective' message
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Transport set to: 'TCP/IP', 127.0.0.1:8008.
May 21 00:39:30 rasp domoticz[2047]: (Listner on HTTPS) Connect directive received, action initiated successfully.
May 21 00:40:41 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:40:55 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:41:09 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:41:23 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:41:37 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:41:51 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:42:05 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly
May 21 00:42:19 rasp domoticz[2047]: Error: Listner on HTTPS hardware (15) thread seems to have ended unexpectedly



here is the modified code:

Code: Select all

# Basic Python Listener Example
#
# Author: Dnpwwo, 2017
#
# Example creates and listens on an HTTP socket. During heartbeats the code then
# creates client connections to the listening sockets
# and sends either GET or POST requests to it
#
#
"""
<plugin key="HTTPListen" name="Listener Sample Plugin" author="dnpwwo" version="1.0.0">
    <params>
        <param field="Port" label="Port" width="30px" required="true" default="8008"/>
        <param field="Mode6" label="Debug" width="100px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal"  default="true" />
                <option label="Logging" value="File"/>
            </options>
        </param>
    </params>
</plugin>
"""
import Domoticz

class BasePlugin:
    enabled = False
    httpServerConn = None
    httpServerConns = {}
    httpClientConn = None
    heartbeats = 0

    def __init__(self):
        return

    def onStart(self):
        if Parameters["Mode6"] != "Normal":
            Domoticz.Debugging(1)
        DumpConfigToLog()
        self.httpServerConn = Domoticz.Connection(Name="Server Connection", Transport="TCP/IP", Protocol="HTTPS", Port=Parameters["Port"])
        self.httpServerConn.Listen()
        Domoticz.Log("Leaving on start")

    def onConnect(self, Connection, Status, Description):
        if (Status == 0):
            Domoticz.Log("Connected successfully to: "+Connection.Address+":"+Connection.Port)
        else:
            Domoticz.Log("Failed to connect ("+str(Status)+") to: "+Connection.Address+":"+Connection.Port+" with error: "+Description)
        Domoticz.Log(str(Connection))
        if (Connection != self.httpClientConn):
            self.httpServerConns[Connection.Name] = Connection

    def onMessage(self, Connection, Data):
        Domoticz.Log("onMessage called for connection: "+Connection.Address+":"+Connection.Port)
        DumpHTTPResponseToLog(Data)
        
        # Incoming Requests
        if "Verb" in Data:
            strVerb = Data["Verb"]
            #strData = Data["Data"].decode("utf-8", "ignore")
            LogMessage(strVerb+" request received.")
            data = "<!doctype html><html><head></head><body><h1>Successful GET!!!</h1><body></html>"
            if (strVerb == "GET"):
                self.httpClientConn.Send({"Status":"200 OK", "Headers": {"Connection": "keep-alive", "Accept": "Content-Type: text/html; charset=UTF-8"}, "Data": data})
            elif (strVerb == "POST"):
                self.httpClientConn.Send({"Status":"200 OK", "Headers": {"Connection": "keep-alive", "Accept": "Content-Type: text/html; charset=UTF-8"}, "Data": data})
            else:
                Domoticz.Error("Unknown verb in request: "+strVerb)
        
        #Domoticz.Log("Headers ("+str(len(Extra))+"):")
        #for x in Extra:
        #    Domoticz.Log("    '" + x + "':'" + str(Extra[x]) + "'")
        #Connection.Send()

        #HTTP/1.1 200 OK
        #Date: Mon, 12 Jun 2017 02:28:46 GMT
        #Expires: -1
        #Cache-Control: private, max-age=0
        #Content-Type: text/html; charset=ISO-8859-1
        #Server: Domoticz
        #Accept-Ranges: none

        #<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage" lang="en-AU"><head></head><body>Response OK</body>

    def onDisconnect(self, Connection):
        Domoticz.Log("onDisconnect called for connection '"+Connection.Name+"'.")
        Domoticz.Log("Server Connections:")
        for x in self.httpServerConns:
            Domoticz.Log("--> "+str(x)+"'.")
        if Connection.Name in self.httpServerConns:
            del self.httpServerConns[Connection.Name]

    def onHeartbeat(self):
        if (self.httpClientConn == None or self.httpClientConn.Connected() != True):
            self.httpClientConn = Domoticz.Connection(Name="Client Connection", Transport="TCP/IP", Protocol="HTTPS", Address="127.0.0.1", Port=Parameters["Port"])
            self.httpClientConn.Connect()
            self.heartbeats = 0
        else:
            if (self.heartbeats == 1):
                self.httpClientConn.Send({"Verb":"GET", "URL":"/page.html", "Headers": {"Connection": "keep-alive", "Accept": "Content-Type: text/html; charset=UTF-8"}})
            elif (self.heartbeats == 2):
                postData = "param1=value&param2=other+value"
                self.httpClientConn.Send({'Verb':'POST', 'URL':'/MediaRenderer/AVTransport/Control', 'Data': postData})
            elif (self.heartbeats == 3) and (Parameters["Mode6"] != "File"):
                self.httpClientConn.Disconnect()
        self.heartbeats += 1

global _plugin
_plugin = BasePlugin()

def onStart():
    global _plugin
    _plugin.onStart()

def onConnect(Connection, Status, Description):
    global _plugin
    _plugin.onConnect(Connection, Status, Description)

def onMessage(Connection, Data):
    global _plugin
    _plugin.onMessage(Connection, Data)

def onDisconnect(Connection):
    global _plugin
    _plugin.onDisconnect(Connection)

def onHeartbeat():
    global _plugin
    _plugin.onHeartbeat()

# Generic helper functions
def LogMessage(Message):
    if Parameters["Mode6"] != "Normal":
        Domoticz.Log(Message)
    elif Parameters["Mode6"] != "Debug":
        Domoticz.Debug(Message)
    else:
        f = open("http.html","w")
        f.write(Message)
        f.close()   

def DumpConfigToLog():
    for x in Parameters:
        if Parameters[x] != "":
            Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
    Domoticz.Debug("Device count: " + str(len(Devices)))
    for x in Devices:
        Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
        Domoticz.Debug("Device ID:       '" + str(Devices[x].ID) + "'")
        Domoticz.Debug("Device Name:     '" + Devices[x].Name + "'")
        Domoticz.Debug("Device nValue:    " + str(Devices[x].nValue))
        Domoticz.Debug("Device sValue:   '" + Devices[x].sValue + "'")
        Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
    return

def DumpHTTPResponseToLog(httpDict):
    if isinstance(httpDict, dict):
        Domoticz.Log("HTTP Details ("+str(len(httpDict))+"):")
        for x in httpDict:
            if isinstance(httpDict[x], dict):
                Domoticz.Log("--->'"+x+" ("+str(len(httpDict[x]))+"):")
                for y in httpDict[x]:
                    Domoticz.Log("------->'" + y + "':'" + str(httpDict[x][y]) + "'")
            else:
                Domoticz.Log("--->'" + x + "':'" + str(httpDict[x]) + "'")


Zigbee for Domoticz plugin / RPI3B+ / Electrolama ZZH-P / 45 devices

If the plugin provides you value, you can support me with a donation Paypal.

Wiki is available here.

Zigbee for Domoticz FAQ
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest