Python path problem

Python and python framework

Moderator: leecollings

Post Reply
ubee
Posts: 66
Joined: Tuesday 10 February 2015 20:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Sweden
Contact:

Python path problem

Post by ubee »

I thought it would be an easy pick to create a plugin as a workaround for the GPIO input problem I and @OldPensionado have reported in another thread.

However, it wasn't... RPi.GPIO wasn't found by the plugin-system, and the reason is /usr/lib/python3/dist-packages is not present in the path used by the plugin system. It works fine if I run python3 interactively from the console. So I added this directory to the path right in the beginning of the plugin module by means of the following two lines of code:

Code: Select all

import sys
sys.path.append('/usr/lib/python3/dist-packages')
By that the reference to RPi.GPIO is Ok, but other problems show up. The first thing you notice it takes a long time to restart the Domoticz service. Normally that takes only one or two seconds on my Rasp 3. However, when I add this library to the path in the plugin module, it takes more than 10s! The plugin seems to load. I found the following in the log file:

2017-03-13 08:32:52.825 PluginSystem: Entering work loop.
2017-03-13 08:32:52.932 (X) Initialized version 1.0.0, author 'ubee'
2017-03-13 08:32:55.425 Hardware Monitor: Fetching data (System sensors)

(X is the name of the HW).

However, no switch device is created and I can't find anything in the log file until a few minutes later when I see:

2017-03-13 08:35:30.517 Error: X hardware (4) thread seems to have ended unexpectedly

So none of the callback functions was called, not even onStart. My conclusion is adding /usr/lib/python3/dist-packages to the path hurts the plugin system for some reason. I've noticed that before when I tried to use another library in a different plugin. Discovering that, I changed my code to not depend on certain libraries. However, I have seen another post about appending libraries to the path so I thought I could give it a try again.

I include the source code below. As you can see it is more or less as simple as a plugin can get.

Code: Select all

"""
<plugin key="GPIn" name="GPIn" author="ubee" version="1.0.0" wikilink="http://www.domoticz.com/wiki/plugins/plugin.html" externallink="https://www.google.com/">
    <params>
    <param field="Pin" label="Pin" width="30px" required="true" default=""/>
    <param field="Mode1" label="Debug" width="75px">
			<options>
				<option label="True" value="Debug"/>
				<option label="False" value="Normal"  default="true" />
			</options>
		</param>
    </params>
</plugin>
"""


import sys
sys.path.append('/usr/lib/python3/dist-packages')
import RPi.GPIO as GPIO
import Domoticz


gpioPin=""


def onStart():
#
#   
#	Create one switch contact corresponding to the specified pin
#
#   
#
    global gpioPin
	
    Domoticz.Log("onStart called")
    if Parameters["Mode1"] == "Debug":
        Domoticz.Debugging(1)	
    gpioPin=Parameters["Pin"]
    GPIO.setmode(GPIO.BCM)
    GPIO.setup(gpioPin, GPIO.IN)

    Domoticz.Device(Name="Switch Contact BCM pin "+ str(gpioPin), Unit=1, TypeName="Switch").Create()	
    Domoticz.Log("Switch contact created.")
 
    DumpConfigToLog()
    return True

	

def onStop():
    Domoticz.Log("onStop called")
    return Tr
 

def onConnect(Status, Description):
    Domoticz.Log("onConnect called")
    return True


def onMessage(Data, Status, Extra):
    Domoticz.Log("onMessage called")
    return True


def onCommand(Unit, Command, Level, Hue):
    
   
    Domoticz.Log("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))

    return True

def onNotification(Data):
    Domoticz.Log("onNotification: " + str(Data))
    return True

def onDisconnect():
    Domoticz.Log("onDisconnect called")
    return True

def onHeartbeat():

#
#   Called periodically
#
#   Read digital input
#

 
    
    Domoticz.Log("onHeartbeat called")
    data=GPIO.input(gpioPin)
    UpdateDevice(1,data,str(data))
 
   
    return True

 # 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 + "'")
        Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
    for item in OneWireIds:
        Domoticz.Debug("1-wire sensor "+ item)
    return
	
def UpdateDevice(Unit, nValue, sValue):
 
# Make sure that the Domoticz device still exists (they can be deleted) before updating it
    Domoticz.Debug("Update unit no: "+str(Unit)+" value: "+ str(nValue)+" "+ str(sValue))
    if (Unit in Devices):
        if (Devices[Unit].nValue != nValue) or (Devices[Unit].sValue != sValue):
            Devices[Unit].Update(nValue, str(sValue))
            Domoticz.Log("Update "+str(nValue)+":'"+str(sValue)+"' ("+Devices[Unit].Name+")")
    return
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Python path problem

Post by Dnpwwo »

@ubee,

I can't comment on some issues but there are some things I can:
  • <param field="Pin" label="Pin" width="30px" required="true" default=""/> won't work. The field name needs to be one of the known fields listed here: http://www.domoticz.com/wiki/Developing ... Parameters
  • if onStart is not being called, move all your code that can executed prior into onStart so you can time it
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
zak45
Posts: 953
Joined: Sunday 22 January 2017 11:37
Target OS: Windows
Domoticz version: V2024.4
Contact:

Re: Python path problem

Post by zak45 »

Hi, I could not provide feedback for linux, but on my windows system, I can confirm that this work. I'm in process to finalize my second Plugin and no trouble on sys.path.append.
ubee
Posts: 66
Joined: Tuesday 10 February 2015 20:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Sweden
Contact:

Re: Python path problem

Post by ubee »

I fixed the parameter name noted by @Dnwppo, but my problem remains. Then I (temporarily) copied the RPI library to a location included in the orginal path and removed the append statement. Still nothing works. Then I commented out all calls to GPIO functions and removed the import statement. By that the plugin started to work and I get printouts in the log file! A switch device is also created in line with my intention.

So my conclusion is the python plugin system goes bananas when I use functions from RPI.GPIO library. The question is why? The library supports two threads and asynchrounous reading of input ports, but I don't use that option.

It is obvious you are on thin ice using python library functions from the plugin. You never know if this will work, and you get really strange errors.
User avatar
Dnpwwo
Posts: 820
Joined: Sunday 23 March 2014 9:00
Target OS: Raspberry Pi / ODroid
Domoticz version: Beta
Location: Melbourne, Australia
Contact:

Re: Python path problem

Post by Dnpwwo »

@ubee,

No idea what other threads or aysnc will do, the library might be creating threads even if you don't use them.

If you post your script and some log I can have a look to see if I can see anything or make some suggestions.
The reasonable man adapts himself to the world; the unreasonable one persists to adapt the world to himself. Therefore all progress depends on the unreasonable man. George Bernard Shaw
ubee
Posts: 66
Joined: Tuesday 10 February 2015 20:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Sweden
Contact:

Re: Python path problem

Post by ubee »

You find the plugin in one of my posts above. And the log does not give any help. You find some lines from that as well in the same post. But don't spend too much time on this right now. I have two options to solve the GPIO input issue:

A) Look into the Domoticz native GPIO support source code and try to figure out why it doesn't work.
B) Make python script that reads GPIO Input pins and update virtual Domoticz switch devices by JSON.

Alternative B is straight forward. I have already code that I can modify.
gerardvs
Posts: 81
Joined: Sunday 04 January 2015 0:01
Target OS: Raspberry Pi / ODroid
Domoticz version: latest-1
Location: /dev/null
Contact:

Re: Python path problem

Post by gerardvs »

@ubee,
Maybe it is a language problem but I think you should openup your mind about what's happening. You might be right that something is going wrong, maybe it isn't, but at least it is not working as you might expect.

Before blaming "the python plugin system" and/or Domoticz you could consider the following approach:
- Does GPIO work directly?
- If so, does it work as root or non-root user? Note that running Domoticz or any other (web)server process never (ever) should run as root.
- If so, does it work in a 'standalone' Python program (again also as a non-root user)
- If so, try to embed the code into a python-plugin but first read the wiki as the code you provided will never work as Dnpwwo already commented.
- Post all your code and (debug)logs so that others can (free of charge) try to help you

I hope you don't feel patronised by this post, I mean it well :-)

--Gerard
ubee
Posts: 66
Joined: Tuesday 10 February 2015 20:38
Target OS: Raspberry Pi / ODroid
Domoticz version: 2021.1
Location: Sweden
Contact:

Re: Python path problem

Post by ubee »

@gerardvs,

No, I don't feel patronised! Instead very grateful for all help! I think @Dnpwwo gave me a hint that made me abandon the idea to continue with a plugin using GPIO. RPi.GPIO seems to be a lot more complex than you think based on what you can figure out from the API. Probably it breaks some of the documented requirements for a plugin module, like no threading or asynchronous calls. So I think it is a waste of time trying to solve this.

Some facts:

As soon as you reference any RPi.GPIO function the plugin fails severely. Not even the OnStart callback function is called.
If you comment out the RPI.GPIO references, the plugin executes as you expect it should do. Of course, it doesn't do what you want it do do, but it executes and you get log printouts.
The GPIO library works in user mode. I have written quite a few scripts using those functions so I'm quite familiar with the library. And I run those scripts in user mode....

So again. Don't spend time on this problem any more. It´s not worth the effort! And again, I have learned that I must be very careful using python library functions. They might break some plugin requirements, and, as @Dnpwwo states, strange things might happen then!
morgancooper
Posts: 1
Joined: Saturday 06 May 2017 11:47
Target OS: -
Domoticz version:
Contact:

Re: Python path problem

Post by morgancooper »

Some time before I had the same problem For the solution of this problem try "Long Path Tool"
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest