I have this python file:
light.py:
#!/usr/bin/python
import sys
import smbus
import time
from Adafruit_I2C import Adafruit_I2C
class Luxmeter:
i2c = None
def __init__(self, address=0x39, debug=0, pause=0.8):
    self.i2c = Adafruit_I2C(address)
    self.address = address
    self.pause = pause
    self.debug = debug
    self.gain = 0 # no gain preselected
    self.i2c.write8(0x80, 0x03)     # enable the device
def setGain(self,gain=1):
    """ Set the gain """
    if (gain != self.gain):
        if (gain==1):
            self.i2c.write8(0x81, 0x02)     # set gain = 1X and timing = 402 mSec
            if (self.debug):
                print "Setting low gain"
        else:
            self.i2c.write8(0x81, 0x12)     # set gain = 16X and timing = 402 mSec
            if (self.debug):
                print "Setting high gain"
        self.gain=gain;                     # safe gain for calculation
        time.sleep(self.pause)              # pause for integration (self.pause must be bigger than integration time)
def readWord(self, reg):
    """Reads a word from the I2C device"""
    try:
        wordval = self.i2c.readU16(reg)
        newval = self.i2c.reverseByteOrder(wordval)
        if (self.debug):
            print("I2C: Device 0x%02X returned 0x%04X from reg 0x%02X" % (self.address, wordval & 0xFFFF, reg))
        return newval
    except IOError:
        print("Error accessing 0x%02X: Check your I2C address" % self.address)
        return -1
def readFull(self, reg=0x8C):
    """Reads visible+IR diode from the I2C device"""
    return self.readWord(reg);
def readIR(self, reg=0x8E):
    """Reads IR only diode from the I2C device"""
    return self.readWord(reg);
def getLux(self, gain = 0):
    """Grabs a lux reading either with autoranging (gain=0) or with a specified gain (1, 16)"""
    if (gain == 1 or gain == 16):
        self.setGain(gain) # low/highGain
        ambient = self.readFull()
        IR = self.readIR()
    elif (gain==0): # auto gain
        self.setGain(16) # first try highGain
        ambient = self.readFull()
        if (ambient < 65535):
            IR = self.readIR()
        if (ambient >= 65535 or IR >= 65535): # value(s) exeed(s) datarange
            self.setGain(1) # set lowGain
            ambient = self.readFull()
            IR = self.readIR()
    if (self.gain==1):
       ambient *= 16    # scale 1x to 16x
       IR *= 16         # scale 1x to 16x
    if (float(ambient) != 0):
        ratio = (IR / float(ambient)) # changed to make it run under python 2
    else: ratio = 0
    if (self.debug):
        print "IR Result", IR
        print "Ambient Result", ambient
    if ((ratio >= 0) & (ratio <= 0.52)):
        lux = (0.0315 * ambient) - (0.0593 * ambient * (ratio**1.4))
    elif (ratio <= 0.65):
        lux = (0.0229 * ambient) - (0.0291 * IR)
    elif (ratio <= 0.80):
        lux = (0.0157 * ambient) - (0.018 * IR)
    elif (ratio <= 1.3):
        lux = (0.00338 * ambient) - (0.0026 * IR)
    elif (ratio > 1.3):
        lux = 0
    return lux
oLuxmeter=Luxmeter()
i=0
while True:
    light = oLuxmeter.getLux(1)
    if (light != 0):
        print light
        break
    else:
        i+=1
        if (i == 10):
            print light
            break
Now I want to run it in PHP on my Raspberry Pi with
echo system("/var/www/light.py")
but the response from the website ist nothing. I give all files permissions with chmod+x, but it did not change anything. If I type
python /var/www/light.py
into the console it works.
                        
The problem is that you're running the web server under some user that doesn't have privileges to use the
smbusfunctions you're using.You can test this by running something like
su www-data /usr/bin/python /var/www/light.py(although the details will vary based on your settings, of course). If that fails, you know this is your problem. (Plus, you'll get to see the traceback, which can be helpful.)Running the web server as a user with as few privileges as possible is a great idea—but running it with fewer privileges than possible obviously isn't. :)
Most privileges on *nix systems are controlled by user/group file permissions, so the answer is probably to add the web server user to the group that owns
smbus. As implied in the forum post you found, PHP exec and python-smbus, that group is usually namedi2c, so if your web server user is namedwww-data, you'd run:As a side note, in the future, don't ignore the return value from calling another program. If it returns 1, or anything besides 0, that means the program has failed, and that's why you're not getting any useful output. (Beyond 0 or not 0, the actual value isn't standardized, although 2 often means bad arguments.)
Meanwhile, you've also got a second problem.
As the docs for
systemexplain,systemdoesn't return the output of the executed command.The docs imply that you want to look at
passthru, but that's probably not what you want either. Just likesystem,passthrudumps the output to your stdout rather than returning it; the only difference is that it dumps it unfiltered by newline translation.If you want to retrieve the output and then echo it, what you probably want here is
exec, with anoutputargument: