У меня есть этот файл Python:
light.py:
#!/usr/bin/python
import sys
import smbus
import time
from Adafruit_I2C import Adafruit_I2Cclass 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 devicedef 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 -1def 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 luxoLuxmeter=Luxmeter()
i=0
while True:
light = oLuxmeter.getLux(1)
if (light != 0):
print light
break
else:
i+=1
if (i == 10):
print light
break
Теперь я хочу запустить его в PHP на моем Raspberry Pi с
echo system("/var/www/light.py")
но ответ с сайта ничего не дает.
Я даю всем файлам разрешения с помощью chmod + x, но это ничего не изменило.
Если я наберу
python /var/www/light.py
в консоль это работает.
Проблема в том, что вы запускаете веб-сервер под каким-либо пользователем, который не имеет прав на использование smbus
функции, которые вы используете.
Вы можете проверить это, запустив что-то вроде su www-data /usr/bin/python /var/www/light.py
(хотя детали будут меняться в зависимости от ваших настроек, конечно). Если это не помогает, вы знаете, что это ваша проблема. (Кроме того, вы увидите трассировку, которая может быть полезна.)
Запуск веб-сервера от имени пользователя с наименьшим количеством привилегий — отличная идея, но запуск его с меньше привилегий, чем это возможно, очевидно, нет. 🙂
Большинство привилегий в системах * nix контролируются правами доступа к файлам пользователей / групп, поэтому ответ, вероятно, заключается в добавлении пользователя веб-сервера в группу, которой принадлежит smbus
, Как и подразумевается в сообщении на форуме, которое вы нашли, PHP exec и python-smbus, эта группа обычно называется i2c
, так что если ваш пользователь веб-сервера называется www-data
вы бы запустили:
sudo adduser www-data i2c
Как примечание, в будущем не игнорируйте возвращаемое значение от вызова другой программы. Если он возвращает 1 или что-либо, кроме 0, это означает, что программа завершилась неудачно, и поэтому вы не получаете никакого полезного вывода. (За пределами 0 или не 0 фактическое значение не стандартизировано, хотя 2 часто означает неверные аргументы.)
Между тем, у вас также есть вторая проблема.
Как документы для system
объяснить, system
не возвращает вывод выполненной команды.
Документы подразумевают, что вы хотите посмотреть на passthru
, но это, вероятно, не то, что вы хотите. Как system
, passthru
выводит вывод на ваш стандартный вывод, а не возвращает его; единственное отличие состоит в том, что он сбрасывает его без фильтрации перевода строки.
Если вы хотите получить вывод, а затем повторить его, то, что вы, вероятно, хотите здесь exec
, с output
аргумент:
Если
output
аргумент присутствует, тогда указанный массив будет заполнен каждой строкой вывода команды.
Других решений пока нет …