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
smbus
functions 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
system
explain,system
doesn'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
,passthru
dumps 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 anoutput
argument: