我正在尝试在运行最新Rasbian Wheezy发行版的Raspberry Pi B+上使用OWN(开放天气网络)设置滚动天气提要,但在使用Python LIRC(Linux Infrared Remote Control)添加 IR 支持时遇到问题。
我正在尝试做的事情: 有四个天气变量:条件、温度、湿度和风速。它们将出现在我的 16x2 LCD 屏幕上,其标题位于第一行,数值位于第二行。它们将在屏幕上停留五秒钟,然后被下一个替换。一旦到达终点,它将再次循环。在它循环 180 次(大约一小时)后,它将更新天气。我想使用 IR 遥控器的按钮 1-4 跳转到特定的磁贴,然后继续返回它的循环。
它在做什么: 当没有按下任何按钮时,它不会像在LIRC阻塞的情况下那样跳过空队列,而是挂在lirc.nextcode()上等待按下按钮,直到我用KeyboardInterrupt退出。
一切都很好,直到我添加了 IR。现在它显示第一个天气变量,然后当它尝试拉下一个天气变量时,如果队列中没有 IR 代码,而不是跳过并转到下一个图块,lirc.nextcode()会暂停代码,直到它收到一个 IR 代码,这不应该在关闭LIRC阻塞的情况下发生。
我拥有所有东西的最新版本(Python LIRC 1.2.1),我知道Python LIRC的先前版本存在阻塞参数的错误。我花了两天时间研究和尝试所有可能的事情。这是我发现的一种可能的解决方法,但它受到与此相同的问题的影响:“ Python LIRC blocking Signal workaround not working ”
我知道很多代码是不正确的,即全局变量,东西需要在函数中,OWN 每三个小时更新一次,我每小时更新一次,但这是暂时的让它工作。稍后我将对其进行整理并使其面向对象。如果这使某些人难以阅读,请提前道歉。
import pyowm
from sys import exit
import time
import RPi.GPIO as GPIO
from RPLCD import CharLCD, cleared, cursor
import lirc
# initialize lirc and turn of blocking
sockid = lirc.init("weather", blocking=False)
lirc.set_blocking(False, sockid)
# initialize weather network
owm = pyowm.OWM('API #')
# initialize LCD
lcd = CharLCD(pin_rs=26, pin_rw=None, pin_e=24, pins_data=[22, 18, 16, 12],
cols=16, rows=2)
# weather data
w = None # wind m/s
wind = None # wind km/h
windkm = None
humidity = None
temper = None
COUNTER = 0 #number of cycles before update
NEXT = 1
# switches to next tile
def next_tile():
global NEXT
这就是问题所在。Lirc.nextcode()应该从LIRC队列中提取下一个 IR 代码并将其作为列表添加到codeIR,但如果没有按下任何按钮,并且阻塞关闭,它应该跳过代码。相反,它就像阻塞是打开的一样,并挂起直到按下按钮。然后它仍然不会继续我的主循环。它只是打印NEXT并挂起,直到 I KeyboardInterrupt出来。
codeIR = lirc.nextcode() # pulls IR code from LIRC queue.
# checks if there's a code in codeIR and goes to that tile. If not, it
# goes to the next tile instead.
if not codeIR:
if NEXT != 4: # if it's the last tile, cycle to the first
NEXT += 1
print NEXT
return NEXT
else: # if not last tile, go to next
NEXT -= 3
print NEXT
return NEXT
else:
NEXT = codeIR[0]
print NEXT
return NEXT
我已经添加了我的其余代码,一切正常,但我相信它会帮助你理解我想要完成的事情。
while True:
try:
if COUNTER == 0:
COUNTER = 180
# Search for current weather in London (UK)
observation = owm.weather_at_place('City, State')
w = observation.get_weather()
# Weather details
wind = w.get_wind() # {'speed': 4.6, 'deg': 330}
windkm = (wind['speed'] * 3600) / 1000 #convet to km/h
humidity = w.get_humidity()
# {'temp_max': 10.5, 'temp': 9.7, 'temp_min': 9.0}
temper = w.get_temperature('celsius')
else:
while NEXT == 1:
# prints condition to lcd
lcd.cursor_pos = (0, 4) #adjust cursor position
lcd.write_string('Weather') # write to lcd
lcd.cursor_pos = (1, 5) # adjust cursor position
lcd.write_string(w.get_status()) # write to lcd
time.sleep(5) # leave on lcd for 5 seconds
lcd.clear() # clear lcd
next_tile() # switches to next tile
while NEXT == 2:
# prints temp to lcd
lcd.cursor_pos = (0, 2)
lcd.write_string('Temperature')
lcd.cursor_pos = (1, 6)
lcd.write_string(str(temper['temp']))
lcd.write_string(' C')
time.sleep(5)
lcd.clear()
next_tile()
while NEXT == 3:
# prints temp to lcd
lcd.cursor_pos = (0, 4)
lcd.write_string('Humidity')
lcd.cursor_pos = (1, 6)
lcd.write_string(str(humidity))
lcd.write_string(' %')
time.sleep(5)
lcd.clear()
next_tile()
while NEXT == 4:
# prints wind speed to lcd
lcd.cursor_pos = (0, 3)
lcd.write_string('Wind Speed')
lcd.cursor_pos = (1, 6)
lcd.write_string(str(int(windkm)))
lcd.write_string('km')
time.sleep(5)
lcd.clear()
COUNTER -= 1
codeIR = lirc.nextcode()
next_tile()
# quit with ctrl+C
except(KeyboardInterrupt, SystemExit):
print 'quitting'
lcd.close(clear=True)
lirc.deinit()
exit()
当我KeyboardInterrupt退出时,Traceback总是导致lirc.nextcode(),我会发布错误,但我稍微更改了代码,现在它只追踪到包含lirc.nextcode()的函数。
我花了两天时间试图解决这个问题,我几乎要拔掉我的头发,所以我会采取你们能给我的任何解决方案或解决方法。预先感谢,我非常感谢我能找到的任何帮助。我找到了使用信号模块 AlarmException的解决方法,但是当我从 raw_input() 切换到 lirc.nextcode() 时,它也以相同的方式挂起(即使它在 raw_input() 上设置了一个计时器也没问题)并阻止警报工作正确的。这是链接:“ Python LIRC blocking Signal workaround not working ”