即使阻塞closures,Python Lirc也会阻止代码

我正在使用运行最新的Rasbian Wheezy发行版的Raspberry Pi B +上的OWN(露天天气networking )设置滚动的天气信息,并且在使用Python LIRC(Linux红外遥控)添加IR支持时遇到了问题。

我想要做的是:有四个天气variables: 条件,温度,湿度和风速 。 它们会出现在我的16×2液晶显示屏上,以第一行的标题和第二行的标题为中心。 他们将在屏幕上停留五秒钟,然后被replace下一个。 一旦达到最后,它会再次循环。 经过180次(大约一个小时)后,它会更新天气。 我想用我的红外遥控器的button1-4跳到一个特定的瓷砖,然后继续它的循环。

它在做什么:当没有button被按下,而不是像LIRC阻塞应该跳过空队列,它挂在lirc.nextcode()等待button按下,直到我退出KeyboardInterrupt

一切都很好,直到我joinIR。 现在它显示第一个天气variables,然后当它试图拉下一个天气variables时,如果队列中没有IR代码,而不是跳过下一个天气, lirc.nextcode()停止代码,直到收到一个IR代码,这在LIRC阻塞closures时不应该发生。

我有最新版本的东西( Python LIRC 1.2.1 ),我知道以前的版本的Python LIRC有一个阻塞参数的错误。 我花了两天的时间研究和尝试一切可能的事情。 以下是我find的一种可能的解决方法,但是它受到了同样的问题: “ Python LIRC阻止信号解决方法无效 ”

我知道很多代码是不正确的, 即全局variables,东西需要在函数中,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中,但是如果没有button被按下,并且阻塞被closures,那么它应该跳过代码。 相反,它的行为就像阻塞一样,并挂起,直到按下button。 然后它仍然不会继续我的主循环。 它只是打印下一个,并挂起,直到我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()的函数。

我已经花了两天的时间来解决这个问题,而且我几乎要拔掉头发,所以我会采取任何解决方法或者解决方法,你们可以给我。 非常感谢,我真的很感谢任何帮助,我可以find。 我发现一个使用Signal Module AlarmException的解决方法,但是当我从raw_input()切换到lirc.nextcode()时,它也以同样的方式挂起(即使它在raw_input()上放一个定时器也没有问题),并阻止警报工作对。 以下是链接: “ Python LIRC阻止信号解决方法不工作 ”

发现这个错误还在1.2.1我想。 我切换到Pylirc2 ,它关闭阻塞pylirc.blocking(0)没有问题。 我也不得不从我的next_tile()函数中删除return

如果有人感兴趣,我最终使用的代码如下:它肯定会为我节省一些时间:

 import pyowm from sys import exit import time import RPi.GPIO as GPIO, feedparser, time from RPLCD import CharLCD, cleared, cursor import pylirc sockid = pylirc.init('weather') allow = pylirc.blocking(0) owm = pyowm.OWM('API Key') lcd = CharLCD(pin_rs=26, pin_rw=None, pin_e=24, pins_data=[22, 18, 16, 12], cols=16, rows=2) class mail(object): def __init__(self): self.username = "email address" self.password = "password" self.newmail_offset = 0 self.current = 0 GPIO.setmode(GPIO.BOARD) GPIO.setup(15, GPIO.OUT) GPIO.setup(13, GPIO.OUT) GPIO.setup(11, GPIO.OUT) def buzz(self): self.period = 1.0 / 250 self.delay = self.period / 2 self.cycles = 250 for i in range(self.cycles): GPIO.output(11, True) time.sleep(self.delay) GPIO.output(11, False) time.sleep(self.delay) def check(self): self.newmails = int(feedparser.parse("https://" + self.username + ":" + self.password +"@mail.google.com/gmail/feed/atom") ["feed"]["fullcount"]) if self.newmails > self.newmail_offset: GPIO.output(15, True) GPIO.output(13, False) if self.newmails > self.current: self.buzz() self.current += 1 else: GPIO.output(15, False) GPIO.output(13, True) self.current = 0 ### will be a class class weather(object): def __init__(self): self.w = None self.wind = None self.windkm = None self.humidity = None self.temper = None self.counter = 0 self.next = 1 def update(self): if self.counter == 0: self.counter = 180 self.observation = owm.weather_at_place('City, Country') self.w = self.observation.get_weather() self.wind = self.w.get_wind() self.windkm = (self.wind['speed'] * 3600) / 1000 self.humidity = self.w.get_humidity() self.temper = self.w.get_temperature('celsius') else: pass def display_weather(self): lcd.cursor_pos = (0, 4) lcd.write_string('Weather') lcd.cursor_pos = (1, 5) lcd.write_string(self.w.get_status()) time.sleep(3) lcd.clear() def display_temp(self): lcd.cursor_pos = (0, 2) lcd.write_string('Temperature') lcd.cursor_pos = (1, 6) lcd.write_string(str(self.temper['temp'])) lcd.write_string(' C') time.sleep(3) lcd.clear() def display_hum(self): lcd.cursor_pos = (0, 4) lcd.write_string('Humidity') lcd.cursor_pos = (1, 6) lcd.write_string(str(self.humidity)) lcd.write_string(' %') time.sleep(3) lcd.clear() def display_wind(self): lcd.cursor_pos = (0, 3) lcd.write_string('Wind Speed') lcd.cursor_pos = (1, 4) lcd.write_string(str(int(self.windkm))) lcd.write_string('km/h') time.sleep(3) lcd.clear() def next_tile(self): self.counter -= 1 self.codeIR = pylirc.nextcode() if not self.codeIR or self.codeIR[0] == self.next: if self.next != 4: self.next += 1 else: self.next -= 3 else: self.next = int(self.codeIR[0]) email = mail() weather = weather() weather.update() def up_next(): weather.update() weather.next_tile() while True: try: while weather.next == 1: weather.display_weather() up_next() while weather.next == 2: weather.display_temp() up_next() while weather.next == 3: weather.display_hum() up_next() while weather.next == 4: weather.display_wind() email.check() up_next() except(KeyboardInterrupt, SystemExit): print 'quitting' lcd.close(clear=True) exit()