Page 1 of 1

Help to build a python plugin

Posted: Sunday 24 September 2017 14:28
by TiXav
hello everybody,

I try to migrate a 2.7 python script to a 3.x python plugin
Today my script make a connection every X second to a dlink camera (2 dlink cams in fact DCS2210 & DCS2230) to retrieve the PIR state of each cam
My code is the following in the python script :

Code: Select all

import urllib
	opener = urllib.FancyURLopener({})
	f = opener.open("http://user:pwd@ipaddress/config/io.cgi")
	aa=f.read()
	................
I am looking for the same approach to do this in python 3.x. I found a lot of thing with google but it does not work

it would be great if someone coud give a boost

After testing, I will share it

thanks

TiXav

Re: Help to build a python plugin

Posted: Sunday 24 September 2017 15:09
by febalci
Will it be a plugin or script? Because you can use Domoticz Connection() method in Plugin.

If it's a script, use:

Code: Select all

import urllib.request

response = urllib.request.urlopen("http://user:pwd@ipaddress/config/io.cgi")
and work on "response" variable.

Re: Help to build a python plugin

Posted: Sunday 24 September 2017 15:41
by TiXav
It will be a plugin

thank you for the clue 'Domoticz Connection()', I am going to search in this direction

Re: Help to build a python plugin

Posted: Thursday 28 September 2017 12:40
by zak45
or you can also

Code: Select all

import urllib.request
try:
        webURL=urllib.request.urlopen(Parameters["Mode4"], timeout=5)
        data=webURL.read()
        encoding = webURL.info().get_content_charset('utf-8')    
        dataIP = json.loads(data.decode(encoding))
    except:
        Domoticz.Error ('Error to get public IP information')

Re: Help to build a python plugin

Posted: Sunday 01 October 2017 21:21
by TiXav
All, thanks

I propose now the plugin. I tested it and I had no problem with
Capture.PNG
Capture.PNG (50 KiB) Viewed 1462 times
The plugin is usefull to retrieve data from url. depending of the result of the response (String to find for On update / String to find for Off update:), the plugin set a switch on or off in domoticz

I use it to retreive the state of the output of two cameras (DCS 2210 & DCS2230) :
I set up event in each cam to put the output to ON during 8 second when a movement is detected.
So the plugin is set up to retrieve the state of the cams each 4 seconds by retrieving the output state of cam with the following url http://IPADRESS/config/io.cgi

Code: Select all


# PirCamChecker
#
# Author: TiXav, Sept 2017
#
# For My DLINK DCS2210 or DCS 2230
# I set the outpout of the camera On during 8 seconds when the cam detects someone 
# So I set the Mode1 to 4 seconds to be sure the plugin catch all the detections
#
"""
<plugin key="PirCamChecker" name="PirCamChecker" author="TiXav" version="1.0.0" externallink="">
    <params>
        <param field="Address" label="IP Address" width="200px" required="true" default=""/>
        <param field="Username" label="Username" width="200px" required="true" default=""/>
        <param field="Password" label="Password" width="200px" required="true" default=""/>
        <param field="Mode2" label="String to find for On update" width="200px" required="true" default=""/>
        <param field="Mode3" label="String to find for Off update" width="200px" required="true" default=""/>
        <param field="Mode1" label="Check Interval(seconds)" width="75px" required="true" default="4"/>
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal"  default="true" />
            </options>
        </param>
    </params>
</plugin>
"""

import Domoticz
import hmac
import hashlib
import time
import urllib
import urllib.request
import urllib.error


#from urllib2 import urlopen
from datetime import datetime, timedelta

class BasePlugin:
    enabled = False
    pluginState = "Not Ready"
    sessionCookie = ""
    privateKey = b""
    socketOn = "FALSE"

    def __init__(self):
        self.debug = False
        self.error = False
        self.nextpoll = datetime.now()
        self.pollinterval = 60  #Time in seconds between two polls
        return

    def onStart(self):

        Domoticz.Debug("onStart called")
        self.pollinterval = int(Parameters["Mode1"])  #Time in seconds between two polls

        if Parameters["Mode6"] == 'Debug':
            self.debug = True
            Domoticz.Debugging(1)
            DumpConfigToLog()
        else:
            Domoticz.Debugging(0)

        # create the mandatory child device if it does not yet exist
        if 1 not in Devices:
            Domoticz.Device(Name="PIR_CAM", Unit=1, TypeName="Switch").Create()
            Domoticz.Log("Device created.")
        
        url = Parameters["Address"]
        ToFindOn=Parameters["Mode2"]
        ToFindOff=Parameters["Mode3"]
        
        #Create a password manager to connect to the camera
        password_mgr = urllib.request.HTTPPasswordMgrWithDefaultRealm()
        # Add the username and password.
        password_mgr.add_password(None, url, Parameters["Username"], Parameters["Password"])
        handler = urllib.request.HTTPBasicAuthHandler(password_mgr)

        # create "opener" (OpenerDirector instance)
        opener = urllib.request.build_opener(handler)

        # use the opener to fetch a URL
        f=opener.open(url)
        aa=f.read()
        
        VV = str(aa,'utf-8')
        VV.join(VV.splitlines())
        Domoticz.Debug(""+VV)
        PosOn=VV.find(ToFindOn)
        PosOff=VV.find(ToFindOn)
        Domoticz.Debug("PosOn="+str(PosOn)+"/PosOff="+str(PosOff))
        
        if PosOn>-1:
            UpdateDevice(1,1,"On")
        if PosOff>-1:
            UpdateDevice(1,0,"Off")
        
        # Install the opener. Now all calls to urllib.request.urlopen use our opener.
        urllib.request.install_opener(opener)
        aa = urllib.request.urlopen(url).read()
        
        Domoticz.Heartbeat(int(Parameters["Mode1"]))

    def onStop(self):
        Domoticz.Log("Plugin is stopping.")
        Domoticz.Debugging(0)

    def onCommand(self, Unit, Command, Level, Hue):
        if Command=="On":
            Devices[1].Update(1, "1")
        if Command=="Off":
            Devices[1].Update(0,"0")
        Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
        for x in Devices:
                Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
        return
        

    def onHeartbeat(self):

        Domoticz.Debug("onHeartbeat called")

        url = Parameters["Address"]
        ToFindOn=Parameters["Mode2"]
        ToFindOff=Parameters["Mode3"]

        now = datetime.now()
        if now >= self.nextpoll:
          self.nextpoll = now + timedelta(seconds=self.pollinterval)
          try:
            response = urllib.request.urlopen(url, timeout = 30).read()
          except urllib.error.HTTPError as err1:
            Domoticz.Error("HTTP Request error: " + str(err1) + " URL: " + url)
            return
          else:
            VV = str(response,'utf-8')
            PosOn=VV.find(ToFindOn)
            PosOff=VV.find(ToFindOff)
            Domoticz.Debug("PosOn="+str(PosOn)+"/PosOff="+str(PosOff))
        
            if PosOn>-1:
                UpdateDevice(1,1,"On")
            if PosOff>-1:
                UpdateDevice(1,0,"Off")
                

global _plugin
_plugin = BasePlugin()

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

def onStop():
    global _plugin
    _plugin.onStop()

def onCommand(Unit, Command, Level, Hue):
    global _plugin
    _plugin.onCommand(Unit, Command, Level, Hue)

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


# Generic helper functions
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 + "'")
    return


def UpdateDevice(Unit, nValue, sValue):
    # Make sure that the Domoticz device still exists (they can be deleted) before updating it 
    if (Unit in Devices):
        if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
            Devices[Unit].Update(nValue, str(sValue))
            Domoticz.Log("Update "+"' ("+Devices[Unit].Name+") "+":'"+str(sValue))
    return

#
# Parse an int and return None if no int is given
#

def parseIntValue(s):

        try:
            return int(s)
        except:
            return None