Help to build a python plugin

Python and python framework

Moderator: leecollings

Post Reply
User avatar
TiXav
Posts: 41
Joined: Saturday 28 November 2015 22:25
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: France
Contact:

Help to build a python plugin

Post 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
febalci
Posts: 331
Joined: Monday 03 July 2017 19:58
Target OS: NAS (Synology & others)
Domoticz version:
Contact:

Re: Help to build a python plugin

Post 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.
User avatar
TiXav
Posts: 41
Joined: Saturday 28 November 2015 22:25
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: France
Contact:

Re: Help to build a python plugin

Post by TiXav »

It will be a plugin

thank you for the clue 'Domoticz Connection()', I am going to search in this direction
zak45
Posts: 953
Joined: Sunday 22 January 2017 11:37
Target OS: Windows
Domoticz version: V2024.4
Contact:

Re: Help to build a python plugin

Post 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')
User avatar
TiXav
Posts: 41
Joined: Saturday 28 November 2015 22:25
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: France
Contact:

Re: Help to build a python plugin

Post 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 1458 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

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest