我有这个python文件:
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
现在我想在我的Raspberry Pi上使用
在PHP中运行它echo system("/var/www/light.py")
但该网站的回复没什么。 我用chmod + x赋予所有文件权限,但它没有改变任何东西。 如果我输入
python /var/www/light.py
进入控制台就可以了。
答案 0 :(得分:2)
问题是您在某个用户下运行网络服务器,该用户没有权限使用您正在使用的smbus
功能。
您可以通过运行类似su www-data /usr/bin/python /var/www/light.py
的内容对此进行测试(当然,细节会因您的设置而异)。如果失败,你知道这是你的问题。 (另外,你会看到追溯,这可能会有所帮助。)
以尽可能少的权限运行Web服务器是一个好主意 - 但使用更少的权限运行它显然不是可能的。 :)
* nix系统上的大多数权限由用户/组文件权限控制,因此答案可能是将Web服务器用户添加到拥有smbus
的组。正如您在PHP exec and python-smbus发现的论坛帖子中暗示的那样,该群组通常被命名为i2c
,因此,如果您的网络服务器用户名为www-data
,则您可以运行:
sudo adduser www-data i2c
作为旁注,将来不要忽略调用另一个程序的返回值。如果它返回1,或者除0以外的任何内容,则表示程序已失败,这就是您没有获得任何有用输出的原因。 (超过0或者不是0,实际值不是标准化的,尽管2通常意味着不好的论点。)
与此同时,你也遇到了第二个问题。
正如system
的文档所解释的那样,system
不会返回已执行命令的输出。
文档暗示您要查看passthru
,但这可能不是您想要的。就像system
一样,passthru
将输出转储到stdout而不是返回它;唯一的区别是它没有通过换行符转换它。
如果你想检索输出然后回显它,你可能想要的是exec
,output
参数:
如果存在
output
参数,则指定的数组将填充该命令的每一行输出。