async def run(self): self.tasks = [ asyncio.create_task(self._ensure_web_socket()), ] await self._ws_connected.wait() self.tasks.extend([ asyncio.create_task(self._receive_commands_from_web_srv_task()), asyncio.create_task(self._send_temperature_to_web_srv_task()), asyncio.create_task( self._send_temperatures_to_telegram()), # telegram ]) threads = [] self.read_opc_task_running = True # for c_item in self.opc.coolers_arr: # t = Thread(target=self._read_opc_task, args=(c_item,)) # threads.append(t) # t.start() t = Thread(target=self.read_all_sensors) t.start() await asyncio.wait(self.tasks) for t in self.tasks: t.cancel()
class Mark1DemoSkill(MycroftSkill): def __init__(self): super(Mark1DemoSkill, self).__init__("Mark1DemoSkill") self.animations = [] self.playing = True self.thread = None def initialize(self): self.emitter.on("mycroft.mark1.demo", self.demo) def animate(self, t, often, func, *args): t = time.time() + t self.animations.append({ "time": t, "often": often, "func": func, "args": args }) def __get_time(self, often, t): return often - t % often def run(self): while self.playing: for animation in self.animations: if animation["time"] <= time.time(): animation["func"](*animation["args"]) if type(animation["often"]) is int: animation["time"] = time.time() + animation["often"] else: often = int(animation["often"]) t = animation["time"] animation["time"] = time.time() + self.__get_time( often, t) time.sleep(0.1) def demo(self, message): self.animate(0, 8, self.enclosure.eyes_look, "r") self.animate(2, 8, self.enclosure.eyes_look, "l") self.animate(4, 8, self.enclosure.eyes_look, "d") self.animate(6, 8, self.enclosure.eyes_look, "u") self.animate(self.__get_time(120, time.time()), "120", self.emitter.emit, Message("mycroft.sing")) self.thread = Thread(None, self.run) self.thread.daemon = True self.thread.start() def stop(self): self.playing = False if self.thread: self.thread.cancel() self.enclosure.eyes_reset()
def start_compilation(project_id, verilog_sources, components): # only one build per project at a time if project_id in running_threads: if not running_threads[project_id].is_alive(): running_threads.pop(project_id) else: raise CompileError("A build is already running for this project") log_queue = Queue() log_queue.progress = 1 cancel_event = Event() running_logs[project_id] = log_queue t = Thread(target=compile, args=(project_id, verilog_sources, components, log_queue, cancel_event), daemon=True) t.cancel = cancel_event running_threads[project_id] = t t.start()
def delayed(): logging.debug("worker runing") t1 = threading.Timer(5,delayed) # 5秒之后 再去执行线程 t1.setName("t1") t2 = threading.Timer(5,delayed) t2.setName("t2") logging.debug("starting timers") t1.start() t2.start() logging.debug("waiting before canceling %s", t2.getName()) time.sleep(2) logging.debug("canceling %s",t2.getName()) t2.cancel() # 关闭定时器。 logging.debug("done") # Timer类 继承于 Thread 类。 # 定时器 线程 在延时期间是可以被关闭的,只需要调用 cancel 方法。 # t2 这个定时器线程,永远不会执行。 11. 限制资源的并发访问--信号量 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种机制。 有时候可能需要允许多个线程同时访问一个资源,但是要限制总数。例如,连接池支持同时连接,但是数目是固定的,或者一个网络应用支持固定数目的并发下载。 一个信号量 管理了一个内部计数器(实际上是一个整数)。调用acquire()方法时 减1 。调用release()方法时,加1 。这个计数器永远不能小于0。 当线程里调用了acquire()发现,内部计数器已经是0了,这个线程会阻塞,直到内部计数大于0。 信号量支持 上下文管理器。
class LUCKY7( xbmcgui.WindowXML ): def __init__( self, *args, **kwargs ): xbmcgui.WindowXML.__init__( self, *args, **kwargs ) self.items_slots = getFruitsAndNonFruits() self.items_slot_1 = sorted( self.items_slots[ 0 ] ) self.items_slot_2 = Shuffle( sorted( self.items_slots[ 1 ] ) ) self.items_slot_3 = sorted( self.items_slots[ 2 ], reverse=True ) self.range_items_slots = range( 21 ) self.all_slots_stopped = False self.slot1_stopped = False self.slot2_stopped = False self.slot3_stopped = False self.is_rolling = False self.game_is_ok = False def play_SFX( self, SFX ): if not xbmc.getCondVisibility( "Skin.HasSetting(Lucky7_SFX_Muted)" ): xbmc.playSFX( SFX ) def onInit( self ): try: if not self.game_is_ok: self.onInitShowSampleSlots() self.load_credits() self.button_auto_spin = self.getControl( 31 ) #Enable and reset bet 2x gain radio button self.button_2x = self.getControl( 62 ) self.set_button_2x() if self.credits[ "jackpot" ] > 0: self.setProperty( "jackpot", "%i" % self.credits[ "jackpot" ] ) self.setProperty( "autospin", "" ) self.game_is_ok = True self.fill_credits() except: print_exc() def onInitShowSampleSlots( self ): try: s1, s2, s3 = random.sample( self.items_slot_1, 3 ) self.setProperty( "slot1_top", s1 ) self.setProperty( "slot1_middle", s2 ) self.setProperty( "slot1_bottom", s3 ) s1, s2, s3 = random.sample( self.items_slot_2, 3 ) self.setProperty( "slot2_top", s1 ) self.setProperty( "slot2_middle", s2 ) self.setProperty( "slot2_bottom", s3 ) s1, s2, s3 = random.sample( self.items_slot_3, 3 ) self.setProperty( "slot3_top", s1 ) self.setProperty( "slot3_middle", s2 ) self.setProperty( "slot3_bottom", s3 ) except: print_exc() def set_button_2x( self, statut=0 ): self.button_2x.setSelected( 0 ) self.button_2x.setEnabled( statut ) self.button_2x.setVisible( statut ) def fill_credits( self ): try: xbmcgui.lock() last_betting = 0 if self.cash: try: last_betting = self.getCurrentListPosition() except: pass zero_cash = self.cash self.clearList() bronze = range( 1, 100 ) for mise in bronze: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money3.png", thumbnailImage="money3.png" ) self.addItem( listitem ) silver = range( 100, 1000, 25 ) for mise in silver: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money2.png", thumbnailImage="money2.png" ) self.addItem( listitem ) gold = range( 1000, 11000, 1000 ) if not self.cash in gold + silver + bronze: gold += [ self.cash ] for mise in gold: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money1.png", thumbnailImage="money1.png" ) self.addItem( listitem ) if last_betting > self.getListSize()-1: last_betting = self.getListSize()-1 self.setCurrentListPosition( last_betting ) except: print_exc() xbmcgui.unlock() self.check_cash() def check_cash( self ): if not self.cash: self.cash = 0 self.betting = 0 self.last_win = 0 self.set_button_2x() if xbmcgui.Dialog().yesno( _( 0 ), _( 11 ) % _( 1 ), _( 12 ) ): self.cash = 5000 self.fill_credits() else: self.clearList() def onFocus( self, controlID ): pass def onClick( self, controlID ): try: if controlID == 20: self.stop_slots( 1 ) elif controlID == 21: self.stop_slots( 2 ) elif controlID == 22: self.stop_slots( 3 ) elif controlID == 23: self.stop_slots( 4 ) elif controlID in ( 24, 25 ): self._start_thread() self.check_cash() elif controlID == 31: if self.button_auto_spin.isSelected(): self.setProperty( "autospin", "true" ) else: self.setProperty( "autospin", "" ) elif controlID == 30: self._show_infos() elif controlID == 300: self._close_game() except: print_exc() def onAction( self, action ): if self.cash and xbmc.getCondVisibility( "Container.OnNext | Container.OnPrevious" ): self.play_SFX( PLAY_COIN_SFX ) try: self.getListItem( self.getCurrentListPosition() ).getLabel() except: try: self.setCurrentListPosition( self.getListSize()-1 ) except: print_exc() try: if not self.is_rolling and KEYMAP[ "close_game" ][ action ]: self._close_game() if self.is_rolling: if KEYMAP[ "action_stop_slot_1" ][ action ]: self.stop_slots( 1 ) elif KEYMAP[ "action_stop_slot_2" ][ action ]: self.stop_slots( 2 ) elif KEYMAP[ "action_stop_slot_3" ][ action ]: self.stop_slots( 3 ) elif KEYMAP[ "action_stop_slots" ][ action ]: self.stop_slots( 4 ) if KEYMAP[ "action_start_spin" ][ action ]: self._start_thread() elif KEYMAP[ "action_bet_max" ][ action ]: self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( self.getListSize()-1 ) elif KEYMAP[ "action_bet_up" ][ action ]: listsize = self.getListSize() pos = self.getCurrentListPosition() + 1 if pos >= listsize: pos = listsize - 1 self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( pos ) elif KEYMAP[ "action_bet_down" ][ action ]: pos = self.getCurrentListPosition() - 1 if pos <= 0: pos = 0 self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( pos ) elif KEYMAP[ "action_bet_2x_gain" ][ action ]: if xbmc.getCondVisibility( "Control.IsVisible(62)" ): if self.button_2x.isSelected(): self.button_2x.setSelected( 0 ) else: self.button_2x.setSelected( 1 ) elif KEYMAP[ "action_auto_spin" ][ action ]: if self.button_auto_spin.isSelected(): self.button_auto_spin.setSelected( 0 ) self.setProperty( "autospin", "" ) else: self.setProperty( "autospin", "true" ) self.button_auto_spin.setSelected( 1 ) elif KEYMAP[ "show_dialog_infos" ][ action ]: self._show_infos() except: print_exc() def _start_thread( self ): if not self.button_auto_spin.isSelected(): self._stop_sub_thread() if not self.is_rolling and self.cash: self.setProperty( "active_spinner", "true" ) self.play_SFX( PLAY_SPINNER_SFX ) if self.last_win and self.button_2x.isSelected(): self.betting = self.last_win * 2 else: self.betting = self.getListItem( self.getCurrentListPosition() ).getLabel().strip( "$" ) self.set_button_2x() self._stop_thread() self.is_rolling = True self._thread = Thread( target=self.start_spin ) self._thread.start() if self.button_auto_spin.isSelected(): self._stop_sub_thread() self._sub_thread = Timer( 3, self._start_thread, () ) self._sub_thread.start() def _stop_thread( self ): try: self._thread.cancel() except: pass def _stop_sub_thread( self ): try: self._sub_thread.cancel() except: pass def stop_slots( self, slot=0 ): if slot: if slot == 1: self.slot1_stopped = True elif slot == 2: self.slot2_stopped = True elif slot == 3: self.slot3_stopped = True else: self.all_slots_stopped = True self._stop_thread() self.play_SFX( PLAY_STOP_SFX ) def start_spin( self ): self.setProperty( "lose", "" ) self.setProperty( "winning", "" ) self.setProperty( "pot_win", "" ) self.setProperty( "all_fruits", "" ) self.setProperty( "slot1_win", "" ) self.setProperty( "slot2_win", "" ) self.setProperty( "slot3_win", "" ) xbmc.sleep( 1200 ) self.setProperty( "active_spinner", "" ) #self.clearProperties() self.items_slot_1 = Shuffle( self.items_slot_1 ) self.items_slot_2 = Shuffle( self.items_slot_2 ) self.items_slot_3 = Shuffle( self.items_slot_3 ) self.all_slots_stopped = False self.slot1_stopped = False self.slot2_stopped = False self.slot3_stopped = False for time_sleep in range( 1, 4 ): if self.all_slots_stopped: break self.play_SFX( PLAY_SPIN_SFX ) time_sleep *= 40 try: for item in self.range_items_slots: if self.all_slots_stopped: break xbmc.sleep( time_sleep ) if not self.slot1_stopped: try: slot1_top = self.items_slot_1[ item + 1 ] except: slot1_top = self.items_slot_1[ 0 ] slot1_middle = self.items_slot_1[ item ] slot1_bottom = self.items_slot_1[ item - 1 ] self.setProperty( "slot1_top", slot1_top ) self.setProperty( "slot1_middle", slot1_middle ) self.setProperty( "slot1_bottom", slot1_bottom ) if not self.slot2_stopped: try: slot2_top = self.items_slot_2[ item + 1 ] except: slot2_top = self.items_slot_2[ 0 ] slot2_middle = self.items_slot_2[ item ] slot2_bottom = self.items_slot_2[ item - 1 ] self.setProperty( "slot2_top", slot2_top ) self.setProperty( "slot2_middle", slot2_middle ) self.setProperty( "slot2_bottom", slot2_bottom ) if not self.slot3_stopped: try: slot3_top = self.items_slot_3[ item + 1 ] except: slot3_top = self.items_slot_3[ 0 ] slot3_middle = self.items_slot_3[ item ] slot3_bottom = self.items_slot_3[ item - 1 ] self.setProperty( "slot3_top", slot3_top ) self.setProperty( "slot3_middle", slot3_middle ) self.setProperty( "slot3_bottom", slot3_bottom ) # slots 1, 2 and 3 stopped if self.slot1_stopped and self.slot2_stopped and self.slot3_stopped: self.all_slots_stopped = True break # for debug only if 3 slots is same #if slot1_middle == slot2_middle == slot3_middle: # self.all_slots_stopped = True # break if not self.all_slots_stopped: if not self.slot1_stopped: self.items_slot_1 = Shuffle( self.items_slot_1 ) if not self.slot2_stopped: self.items_slot_2 = Shuffle( self.items_slot_2 ) if not self.slot3_stopped: self.items_slot_3 = Shuffle( self.items_slot_3 ) except: print_exc() self.set_gain( Gain( slot1_middle, slot2_middle, slot3_middle, slot1_top, slot2_top, slot3_top, slot1_bottom, slot2_bottom, slot3_bottom, gui=self ) ) try: if slot1_middle == slot2_middle == slot3_middle: if slot1_middle == SEVEN: self.play_SFX( PLAY_7_SFX ) xbmc.sleep( 2000 ) elif slot1_middle == BELL: self.play_SFX( PLAY_BELL_SFX ) xbmc.sleep( 4000 ) except: print_exc() #xbmc.sleep( 100 ) self.betting = 0 self.fill_credits() self.is_rolling = False self._stop_thread() def set_gain( self, slots_infos ): #set credits display try: cash_win = 0 _jackpot = 0 if not self.button_2x.isSelected(): self.cash -= slots_infos.betting if slots_infos.win: if slots_infos.all_fruits and not slots_infos.gain: self.play_SFX( PLAY_7_SFX ) xbmc.sleep( 2000 ) if slots_infos.all_fruits: self.setProperty( "all_fruits", _( 405 ) ) if slots_infos.gain: cash_win += slots_infos.gain self.setProperty( "winning", str( cash_win ) ) if slots_infos.win_jackpot: _jackpot = self.credits[ "jackpot" ] self.setProperty( "jackpot", "" ) self.setProperty( "pot_win", str( self.credits[ "jackpot" ] ) ) cash_win += self.credits[ "jackpot" ] self.credits[ "jackpot" ] = 0 self.cash += cash_win self.last_win = cash_win if slots_infos.win_slots[ 0 ]: self.setProperty( "slot1_win", "true" ) if slots_infos.win_slots[ 1 ]: self.setProperty( "slot2_win", "true" ) if slots_infos.win_slots[ 2 ]: self.setProperty( "slot3_win", "true" ) #Enable and reset bet 2x gain radio button self.set_button_2x( 1 ) else: self.last_win = 0 if self.button_2x.isSelected(): slots_infos.betting /= 2 self.cash -= slots_infos.betting self.credits[ "jackpot" ] += slots_infos.betting self.setProperty( "lose", str( slots_infos.betting ) ) self.setProperty( "jackpot", str( self.credits[ "jackpot" ] ) ) #Enable and reset bet 2x gain radio button self.set_button_2x() if slots_infos.win_jackpot: #xbmc.executebuiltin( "XBMC.Action(Screenshot)" ) OK, date_time = self.screenshot() if OK: self.dump_winner_jackpot( slots_infos.betting, cash_win, _jackpot, date_time ) #OK, date_time = self.screenshot() #if OK: self.dump_winner_jackpot( slots_infos.betting, cash_win, _jackpot, date_time ) except: print_exc() def load_credits( self ): test = {} self.credits = {} defaults = { "jackpot": 0, "last_cash": 0 } if os.path.exists( CREDITS_FILE ): try: f = open( CREDITS_FILE, "rb" ) test = load( f ) f.close() except: print_exc() test = {} for key, value in defaults.items(): # add default values for missing settings self.credits[ key ] = test.get( key, defaults[ key ] ) self.save_credits() self.cash = 10000 #demande pour continuer ancienne partie if ( self.credits[ "last_cash" ] > 0 ) and xbmcgui.Dialog().yesno( _( 0 ), _( 5 ) % ( _( 1 ), self.credits[ "last_cash" ] ), _( 6 ), _( 7 ), _( 8 ), _( 9 ) ): self.cash = self.credits[ "last_cash" ] self.credits[ "last_cash" ] = 0 self.last_win = 0 self.betting = 0 def save_credits( self ): try: f = open( CREDITS_FILE, "wb" ) dump( self.credits, f ) f.close() except: print_exc() def dump_winner_jackpot( self, bet, cash, jackpot, date_time ): winners = [] name = xbmc.getInfoLabel( "System.ProfileName" )#unicode( , 'utf-8') thumb = xbmc.getInfoImage( "System.ProfileThumb" ) if os.path.isfile( WINNER_JACKPOT ): try: f = open( WINNER_JACKPOT, "rb" ) winners = load( f ) f.close() except: print_exc() winners = [] try: winners.append( [ name, thumb, bet, cash, jackpot, date_time ] ) f = open( WINNER_JACKPOT, "wb" ) dump( winners, f ) f.close() except: print_exc() #print winners def screenshot( self ): xbmc.sleep( 1000 ) OK = "" name = "" try: name = str( time.time() ) # original size #filename = name + "-big.jpg" W, H = self.getWidth(), self.getHeight() #OK = TakeScreenShot( filename, width=W, height=H ) # thumbs size filename = name + ".jpg" W, H = 384, ( ( 384 * H ) / W ) #W, H = 512, ( ( 512 * H ) / W ) #W, H = int( ( 256 * W ) / H ), 256 OK = TakeScreenShot( filename, width=W, height=H ) except: print_exc() #print OK return ( OK == "OK" ), name def _show_infos( self ): import dialogInfos current_skin, force_fallback = getUserSkin() w = dialogInfos.DialogInfos( "lucky-7-DialogInfos.xml", CWD, current_skin, force_fallback, close_game=self._close_game ) w.doModal() del w del dialogInfos def _close_game( self ): self._stop_sub_thread() self.all_slots_stopped = True #self._stop_thread() if self.cash > 10000: self.credits[ "last_cash" ] = self.cash self.cash = 0 self.save_credits() #xbmc.sleep( 100 ) self.close()
class LUCKY7( xbmcgui.WindowXML ): def __init__( self, *args, **kwargs ): xbmcgui.WindowXML.__init__( self, *args, **kwargs ) self.items_slots = getFruitsAndNonFruits() self.items_slot_1 = sorted( self.items_slots[ 0 ] ) self.items_slot_2 = Shuffle( sorted( self.items_slots[ 1 ] ) ) self.items_slot_3 = sorted( self.items_slots[ 2 ], reverse=True ) self.range_items_slots = range( 21 ) self.all_slots_stopped = False self.slot1_stopped = False self.slot2_stopped = False self.slot3_stopped = False self.is_rolling = False self.game_is_ok = False def play_SFX( self, SFX ): if not xbmc.getCondVisibility( "Skin.HasSetting(Lucky7_SFX_Muted)" ): xbmc.playSFX( SFX ) def onInit( self ): try: if not self.game_is_ok: self.onInitShowSampleSlots() self.load_credits() self.button_auto_spin = self.getControl( 31 ) #Enable and reset bet 2x gain radio button self.button_2x = self.getControl( 62 ) self.set_button_2x() if self.credits[ "jackpot" ] > 0: self.setProperty( "jackpot", "%i" % self.credits[ "jackpot" ] ) self.setProperty( "autospin", "" ) self.game_is_ok = True self.fill_credits() except: print_exc() def onInitShowSampleSlots( self ): try: s1, s2, s3 = random.sample( self.items_slot_1, 3 ) self.setProperty( "slot1_top", s1 ) self.setProperty( "slot1_middle", s2 ) self.setProperty( "slot1_bottom", s3 ) s1, s2, s3 = random.sample( self.items_slot_2, 3 ) self.setProperty( "slot2_top", s1 ) self.setProperty( "slot2_middle", s2 ) self.setProperty( "slot2_bottom", s3 ) s1, s2, s3 = random.sample( self.items_slot_3, 3 ) self.setProperty( "slot3_top", s1 ) self.setProperty( "slot3_middle", s2 ) self.setProperty( "slot3_bottom", s3 ) except: print_exc() def set_button_2x( self, statut=0 ): self.button_2x.setSelected( 0 ) self.button_2x.setEnabled( statut ) self.button_2x.setVisible( statut ) def fill_credits( self ): try: xbmcgui.lock() last_betting = 0 if self.cash: try: last_betting = self.getCurrentListPosition() except: pass zero_cash = self.cash self.clearList() bronze = range( 1, 100 ) for mise in bronze: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money3.png", thumbnailImage="money3.png" ) self.addItem( listitem ) silver = range( 100, 1000, 25 ) for mise in silver: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money2.png", thumbnailImage="money2.png" ) self.addItem( listitem ) gold = range( 1000, 11000, 1000 ) if not self.cash in gold + silver + bronze: gold += [ self.cash ] for mise in gold: zero_cash = self.cash - mise label2 = str( zero_cash ) if zero_cash >= 0: listitem = xbmcgui.ListItem( str( mise ), label2, iconImage="money1.png", thumbnailImage="money1.png" ) self.addItem( listitem ) if last_betting > self.getListSize()-1: last_betting = self.getListSize()-1 self.setCurrentListPosition( last_betting ) except: print_exc() xbmcgui.unlock() self.check_cash() def check_cash( self ): if not self.cash: self.cash = 0 self.betting = 0 self.last_win = 0 self.set_button_2x() if xbmcgui.Dialog().yesno( _( 0 ), _( 11 ) % _( 1 ), _( 12 ) ): self.cash = 5000 self.fill_credits() else: self.clearList() def onFocus( self, controlID ): pass def onClick( self, controlID ): try: if controlID == 20: self.stop_slots( 1 ) elif controlID == 21: self.stop_slots( 2 ) elif controlID == 22: self.stop_slots( 3 ) elif controlID == 23: self.stop_slots( 4 ) elif controlID in ( 24, 25 ): self._start_thread() self.check_cash() elif controlID == 31: if self.button_auto_spin.isSelected(): self.setProperty( "autospin", "true" ) else: self.setProperty( "autospin", "" ) elif controlID == 30: self._show_infos() elif controlID == 300: self._close_game() except: print_exc() def onAction( self, action ): if self.cash and xbmc.getCondVisibility( "Container.OnNext | Container.OnPrevious" ): self.play_SFX( PLAY_COIN_SFX ) try: self.getListItem( self.getCurrentListPosition() ).getLabel() except: try: self.setCurrentListPosition( self.getListSize()-1 ) except: print_exc() try: if not self.is_rolling and KEYMAP[ "close_game" ][ action ]: self._close_game() if self.is_rolling: if KEYMAP[ "action_stop_slot_1" ][ action ]: self.stop_slots( 1 ) elif KEYMAP[ "action_stop_slot_2" ][ action ]: self.stop_slots( 2 ) elif KEYMAP[ "action_stop_slot_3" ][ action ]: self.stop_slots( 3 ) elif KEYMAP[ "action_stop_slots" ][ action ]: self.stop_slots( 4 ) if KEYMAP[ "action_start_spin" ][ action ]: self._start_thread() elif KEYMAP[ "action_bet_max" ][ action ]: self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( self.getListSize()-1 ) elif KEYMAP[ "action_bet_up" ][ action ]: listsize = self.getListSize() pos = self.getCurrentListPosition() + 1 if pos >= listsize: pos = listsize - 1 self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( pos ) elif KEYMAP[ "action_bet_down" ][ action ]: pos = self.getCurrentListPosition() - 1 if pos <= 0: pos = 0 self.play_SFX( PLAY_COIN_SFX ) self.setCurrentListPosition( pos ) elif KEYMAP[ "action_bet_2x_gain" ][ action ]: if xbmc.getCondVisibility( "Control.IsVisible(62)" ): if self.button_2x.isSelected(): self.button_2x.setSelected( 0 ) else: self.button_2x.setSelected( 1 ) elif KEYMAP[ "action_auto_spin" ][ action ]: if self.button_auto_spin.isSelected(): self.button_auto_spin.setSelected( 0 ) self.setProperty( "autospin", "" ) else: self.setProperty( "autospin", "true" ) self.button_auto_spin.setSelected( 1 ) elif KEYMAP[ "show_dialog_infos" ][ action ]: self._show_infos() except: print_exc() def _start_thread( self ): if not self.button_auto_spin.isSelected(): self._stop_sub_thread() if not self.is_rolling and self.cash: self.setProperty( "active_spinner", "true" ) self.play_SFX( PLAY_SPINNER_SFX ) if self.last_win and self.button_2x.isSelected(): self.betting = self.last_win * 2 else: self.betting = self.getListItem( self.getCurrentListPosition() ).getLabel().strip( "$" ) self.set_button_2x() self._stop_thread() self.is_rolling = True self._thread = Thread( target=self.start_spin ) self._thread.start() if self.button_auto_spin.isSelected(): self._stop_sub_thread() self._sub_thread = Timer( 3, self._start_thread, () ) self._sub_thread.start() def _stop_thread( self ): try: self._thread.cancel() except: pass def _stop_sub_thread( self ): try: self._sub_thread.cancel() except: pass def stop_slots( self, slot=0 ): if slot: if slot == 1: self.slot1_stopped = True elif slot == 2: self.slot2_stopped = True elif slot == 3: self.slot3_stopped = True else: self.all_slots_stopped = True self._stop_thread() self.play_SFX( PLAY_STOP_SFX ) def start_spin( self ): self.setProperty( "lose", "" ) self.setProperty( "winning", "" ) self.setProperty( "pot_win", "" ) self.setProperty( "all_fruits", "" ) self.setProperty( "slot1_win", "" ) self.setProperty( "slot2_win", "" ) self.setProperty( "slot3_win", "" ) xbmc.sleep( 1200 ) self.setProperty( "active_spinner", "" ) #self.clearProperties() self.items_slot_1 = Shuffle( self.items_slot_1 ) self.items_slot_2 = Shuffle( self.items_slot_2 ) self.items_slot_3 = Shuffle( self.items_slot_3 ) self.all_slots_stopped = False self.slot1_stopped = False self.slot2_stopped = False self.slot3_stopped = False for time_sleep in range( 1, 4 ): if self.all_slots_stopped: break self.play_SFX( PLAY_SPIN_SFX ) time_sleep *= 40 try: for item in self.range_items_slots: if self.all_slots_stopped: break xbmc.sleep( time_sleep ) if not self.slot1_stopped: try: slot1_top = self.items_slot_1[ item + 1 ] except: slot1_top = self.items_slot_1[ 0 ] slot1_middle = self.items_slot_1[ item ] slot1_bottom = self.items_slot_1[ item - 1 ] self.setProperty( "slot1_top", slot1_top ) self.setProperty( "slot1_middle", slot1_middle ) self.setProperty( "slot1_bottom", slot1_bottom ) if not self.slot2_stopped: try: slot2_top = self.items_slot_2[ item + 1 ] except: slot2_top = self.items_slot_2[ 0 ] slot2_middle = self.items_slot_2[ item ] slot2_bottom = self.items_slot_2[ item - 1 ] self.setProperty( "slot2_top", slot2_top ) self.setProperty( "slot2_middle", slot2_middle ) self.setProperty( "slot2_bottom", slot2_bottom ) if not self.slot3_stopped: try: slot3_top = self.items_slot_3[ item + 1 ] except: slot3_top = self.items_slot_3[ 0 ] slot3_middle = self.items_slot_3[ item ] slot3_bottom = self.items_slot_3[ item - 1 ] self.setProperty( "slot3_top", slot3_top ) self.setProperty( "slot3_middle", slot3_middle ) self.setProperty( "slot3_bottom", slot3_bottom ) # slots 1, 2 and 3 stopped if self.slot1_stopped and self.slot2_stopped and self.slot3_stopped: self.all_slots_stopped = True break # for debug only if 3 slots is same #if slot1_middle == slot2_middle == slot3_middle: # self.all_slots_stopped = True # break if not self.all_slots_stopped: if not self.slot1_stopped: self.items_slot_1 = Shuffle( self.items_slot_1 ) if not self.slot2_stopped: self.items_slot_2 = Shuffle( self.items_slot_2 ) if not self.slot3_stopped: self.items_slot_3 = Shuffle( self.items_slot_3 ) except: print_exc() self.set_gain( Gain( slot1_middle, slot2_middle, slot3_middle, slot1_top, slot2_top, slot3_top, slot1_bottom, slot2_bottom, slot3_bottom, gui=self ) ) try: if slot1_middle == slot2_middle == slot3_middle: if slot1_middle == SEVEN: self.play_SFX( PLAY_7_SFX ) xbmc.sleep( 2000 ) elif slot1_middle == BELL: self.play_SFX( PLAY_BELL_SFX ) xbmc.sleep( 4000 ) except: print_exc() #xbmc.sleep( 100 ) self.betting = 0 self.fill_credits() self.is_rolling = False self._stop_thread() def set_gain( self, slots_infos ): #set credits display try: cash_win = 0 _jackpot = 0 if not self.button_2x.isSelected(): self.cash -= slots_infos.betting if slots_infos.win: if slots_infos.all_fruits and not slots_infos.gain: self.play_SFX( PLAY_7_SFX ) xbmc.sleep( 2000 ) if slots_infos.all_fruits: self.setProperty( "all_fruits", _( 405 ) ) if slots_infos.gain: cash_win += slots_infos.gain self.setProperty( "winning", str( cash_win ) ) if slots_infos.win_jackpot: _jackpot = self.credits[ "jackpot" ] self.setProperty( "jackpot", "" ) self.setProperty( "pot_win", str( self.credits[ "jackpot" ] ) ) cash_win += self.credits[ "jackpot" ] self.credits[ "jackpot" ] = 0 self.cash += cash_win self.last_win = cash_win if slots_infos.win_slots[ 0 ]: self.setProperty( "slot1_win", "true" ) if slots_infos.win_slots[ 1 ]: self.setProperty( "slot2_win", "true" ) if slots_infos.win_slots[ 2 ]: self.setProperty( "slot3_win", "true" ) #Enable and reset bet 2x gain radio button self.set_button_2x( 1 ) else: self.last_win = 0 if self.button_2x.isSelected(): slots_infos.betting /= 2 self.cash -= slots_infos.betting self.credits[ "jackpot" ] += slots_infos.betting self.setProperty( "lose", str( slots_infos.betting ) ) self.setProperty( "jackpot", str( self.credits[ "jackpot" ] ) ) #Enable and reset bet 2x gain radio button self.set_button_2x() if slots_infos.win_jackpot: #xbmc.executebuiltin( "XBMC.Action(Screenshot)" ) OK, date_time = self.screenshot() if OK: self.dump_winner_jackpot( slots_infos.betting, cash_win, _jackpot, date_time ) #OK, date_time = self.screenshot() #if OK: self.dump_winner_jackpot( slots_infos.betting, cash_win, _jackpot, date_time ) except: print_exc() def load_credits( self ): test = {} self.credits = {} defaults = { "jackpot": 0, "last_cash": 0 } if os.path.exists( CREDITS_FILE ): try: f = open( CREDITS_FILE, "rb" ) test = load( f ) f.close() except: print_exc() test = {} for key, value in defaults.items(): # add default values for missing settings self.credits[ key ] = test.get( key, defaults[ key ] ) self.save_credits() self.cash = 10000 #demande pour continuer ancienne partie if ( self.credits[ "last_cash" ] > 0 ) and xbmcgui.Dialog().yesno( _( 0 ), _( 5 ) % ( _( 1 ), self.credits[ "last_cash" ] ), _( 6 ), _( 7 ), _( 8 ), _( 9 ) ): self.cash = self.credits[ "last_cash" ] self.credits[ "last_cash" ] = 0 self.last_win = 0 self.betting = 0 def save_credits( self ): try: f = open( CREDITS_FILE, "wb" ) dump( self.credits, f ) f.close() except: print_exc() def dump_winner_jackpot( self, bet, cash, jackpot, date_time ): winners = [] name = xbmc.getInfoLabel( "System.ProfileName" )#unicode( , 'utf-8') thumb = xbmc.getInfoImage( "System.ProfileThumb" ) if os.path.isfile( WINNER_JACKPOT ): try: f = open( WINNER_JACKPOT, "rb" ) winners = load( f ) f.close() except: print_exc() winners = [] try: winners.append( [ name, thumb, bet, cash, jackpot, date_time ] ) f = open( WINNER_JACKPOT, "wb" ) dump( winners, f ) f.close() except: print_exc() #print winners def screenshot( self ): xbmc.sleep( 1000 ) OK = "" name = "" try: name = str( time.time() ) # original size #filename = name + "-big.jpg" W, H = self.getWidth(), self.getHeight() #OK = TakeScreenShot( filename, width=W, height=H ) # thumbs size filename = name + ".jpg" W, H = 384, ( ( 384 * H ) / W ) #W, H = 512, ( ( 512 * H ) / W ) #W, H = int( ( 256 * W ) / H ), 256 OK = TakeScreenShot( filename, width=W, height=H ) except: print_exc() #print OK return ( OK == "OK" ), name def _show_infos( self ): import dialogInfos current_skin, force_fallback = getUserSkin() try: w = dialogInfos.DialogInfos( "lucky-7-DialogInfos.xml", CWD, current_skin, "PAL", close_game=self._close_game ) except: w = dialogInfos.DialogInfos( "lucky-7-DialogInfos.xml", CWD, current_skin, force_fallback, close_game=self._close_game ) w.doModal() del w del dialogInfos def _close_game( self ): self._stop_sub_thread() self.all_slots_stopped = True #self._stop_thread() if self.cash > 10000: self.credits[ "last_cash" ] = self.cash self.cash = 0 self.save_credits() #xbmc.sleep( 100 ) self.close()
class OBCI_board_simulator(): def __init__(self, filepath, FS=250.0, factorOriginalSpeed=1, skipSeconds=0, daisy=False): # QtCore.QThread.__init__(self) self.simulationCSVFilepath = filepath self.simulationFactorOriginalSpeed = factorOriginalSpeed self.simulateFromCSVskipSeconds = skipSeconds self.fs = FS self.daisy = daisy self.streaming = False self.read_csv_state_ready = False self.start_time = -100000 self.lastSampleTime = -1 self.sampleSupposedDelay = ( 1.0 / self.fs) / self.simulationFactorOriginalSpeed self.state_read_trough = False self.sample = OpenBCISample(0, (), ()) self.thread = None def getSkipedSeconds(self): return self.simulateFromCSVskipSeconds def getSkipedLines(self): return self.nSkipDataLines def read_csv_data_init(self): self.nSkipDataLines = int(self.simulateFromCSVskipSeconds * self.fs) self.read_csv_state_ready = False self.simulationCSVFile = open(self.simulationCSVFilepath, 'rb', buffering=20000000) # opens the csv file # try: #self.inputiSample = 0 self.reader = csv.reader(self.simulationCSVFile, delimiter=';') # creates the reader object for row in self.reader: # iterates the rows of the file in orders # print(row) # prints each row if self.reader.line_num == 1: # index;time_sec;ringpar;ch1;ch2;ch3;ch4;ch5;ch6;ch7;ch8 continue # skip the first header line if self.reader.line_num <= self.nSkipDataLines + 1: continue else: break self.read_csv_state_ready = True # except: # f.close() # closing return self.read_csv_state_ready def readSamples(self): if not self.state_read_trough: self.next_call_time = timeit.default_timer() try: while True: if self.reading: row = next(self.reader) self.sample = namedtuple("Sample", "id channel_data time") self.sample.time = timeit.default_timer() self.sample.id = int(row[2]) if self.daisy and len(row) < 19: print "you chose a 16 channel setup, but the file " + self.simulationCSVFilepath + " probably only a 8 channel recording or not the right file. Choose another 8 channel setup, or another 16 channel recording." sys.exit(0) if self.daisy: self.sample.channel_data = [ float(row[3]), float(row[4]), float(row[5]), float(row[6]), float(row[7]), float(row[8]), float(row[9]), float(row[10]), float(row[11]), float(row[12]), float(row[13]), float(row[14]), float(row[15]), float(row[16]), float(row[17]), float(row[18]) ] if len(row) == 22: self.sample.aux_data = [ float(row[19]), float(row[20]), float(row[21]) ] else: self.sample.aux_data = [0.0, 0.0, 0.0] else: self.sample.channel_data = [ float(row[3]), float(row[4]), float(row[5]), float(row[6]), float(row[7]), float(row[8]), float(row[9]), float(row[10]) ] if len(self.sample.channel_data) == 14: self.sample.aux_data = [ float(row[11]), float(row[12]), float(row[13]) ] else: self.sample.aux_data = [0.0, 0.0, 0.0] self.lastSampleTime = self.sample.time for call in self.callback: call(self.sample) self.next_call_time = self.next_call_time + self.sampleSupposedDelay #print "sleep delay: " + str(intendedSleep) + " next_call_time : " + str(self.next_call_time) + " sampleSupposedDelay: " + str(self.sampleSupposedDelay) while self.next_call_time <= timeit.default_timer(): self.next_call_time = timeit.default_timer( ) + self.sampleSupposedDelay #intendedSleep = self.next_call_time - timeit.default_timer() self.reading = False self.reading = True # print "sleep delay: " + str(self.next_call_time - timeit.default_timer()) intendedSleep = self.next_call_time - timeit.default_timer( ) time.sleep(max(intendedSleep, 0)) except StopIteration: self.state_read_trough = True def start_streaming(self, callback, lapse=-1): if not self.streaming: self.streaming = True self.start_time = timeit.default_timer() # Enclose callback funtion in a list if it comes alone if not isinstance(callback, list): callback = [callback] self.callback = callback if not self.read_csv_state_ready: self.read_csv_data_init() self.state_read_trough = False self.reading = True self.thread = Thread(target=self.readSamples) self.thread.daemon = True self.thread.start() # self.thread = Timer(self.sampleSupposedDelay, self.readNextSample) # self.thread.start() def run(self): # Initialize self.read_csv_data_init() # def init(self): # # Initialize # self.read_csv_data_init() def cancel(self): self.simulationCSVFile.close() # closing self.thread.cancel()
class PyWeather(object): def __init__(self): try: cf = open('config.json', 'r') configstr = cf.read() cf.close() config = json.loads(configstr) self.config = config daynum = str(datetime.datetime.now().day) logging.basicConfig(filename=config['logFilePath'] + 'pyWeather' + daynum + '.log', level=logging.INFO) except KeyboardInterrupt: print('^C received') ws.stop() time.sleep(5) except Exception as e: ws.stop() Logger.error(e) time.sleep(5) def start(self): Logger.info('starting') self.vpstation = VPStation(self.config) self.vpThrd = Thread(target=self.vpstation.start, args=()) self.vpThrd.start() self.isServing = True self.startWebServer() def stop(self): self.vpstation.stop() time.sleep(5) self.vpThrd.cancel() self.isServing = False def startWebServer(self): port = self.config['webPort'] self.server = HTTPServer(('', port), PyWeather.makeHandlerClass(self.vpstation)) print('server port ' + str(port)) while self.isServing: self.server.handle_request() def makeHandlerClass(vpstation): class RequestHandler(BaseHTTPRequestHandler, object): def __init__(self, *args, **kwargs): self.vpstation = vpstation super(RequestHandler, self).__init__(*args, **kwargs) def do_HEAD(self, contentType): self.send_response(200) self.send_header('Content-type', contentType) self.end_headers() def do_GET(self): global vpstation req = self.path[1:] if req == 'current': self.do_HEAD('application/json') self.wfile.write( bytes(self.vpstation.current.toJSON(), 'utf-8')) elif req == 'hilows': self.do_HEAD('application/json') self.wfile.write(json.dumps(self.vpstation.hilows)) elif req == 'alerts': self.do_HEAD('application/json') self.wfile.write(json.dumps(self.vpstation.alerts)) else: self.do_HEAD('text/html') self.send_response(404) def do_POST(self): cmd = self.path[1:] content_length = int(self.headers['Content-Length']) post_data = self.rfile.read(content_length) self.do_HEAD('application/json') #self.wfile.write(json.dumps(retval)) return RequestHandler
from threading import Thread, current_thread def fn(tname, count): th = current_thread() for i in range(count): if hasattr(th, "cancel") and getattr(th, "cancel") == True: break print("In {} counting {}".format(tname, i)) sleep(0.5) t1 = Thread(target=fn, args=("foo", 10)) t2 = Thread(target=fn, args=("bar", 15)) t1.start() t2.start() fn("main", 5) t1.cancel = True t1.join() print("Main: t1 completed...") sleep(2) t2.cancel = True t2.join() print("Main: t2 completed...") print("Main complete...")
class LoggerPlugin: """ Args: logger (RTLogger): The parent RTLogger-instance """ def __init__(self, logger=None, *args, **kwargs): # Plugin setup # self.setDeviceName() self._devicename = "noDevice" self.rtoc = rtoc if logger is not None: self.logger = logger self._cb = logger.database.addDataCallback self._ev = logger.database.addNewEvent self._plt = logger.database.plot self._bot = logger.telegramBot else: self._logger = None self._cb = None self._ev = None self._plt = None self._bot = None self.widget = None self._pluginThread = None self._oldPerpetualTimer = False self.lockPerpetialTimer = Lock() self._log = deque([], 100) # ------------- self.run = False # False -> stops thread """ Use this parameter to start/stop threads. This makes sure, RTOC can close your plugin correctly.""" self.smallGUI = False """ If this is True, the plugin-GUI will be shown in a dropdown menu (GUI related)""" self.widget = None """ Replace this with your QWidget to enable the plugin-GUI""" self._samplerate = 1 def getDir(self, dir=None): """ Returns: Path of your plugin """ if dir is None: dir = __file__ if getattr(sys, 'frozen', False): # frozen packagedir = os.path.dirname(sys.executable)+'/RTOC/plugins' else: # unfrozen packagedir = os.path.dirname(os.path.realpath(dir)) return packagedir def updateInfo(self): self.logger.analysePlugins() def stream(self, y=[], snames=[], dname=None, unit=None, x=None, slist=None, sdict=None): """ Use this function to send new measurements to RTOC. You can send multiple signals at once. This function is a wrapper for :py:meth:`.RT_data.addData` You can choose one of three ways to send measurements. **dict** Args: sdict (dict): A dict containing keys like this: `{'Temperature':[28,'°C'], 'Voltage':[12,'V']}` dname (str): The devicename of this signal, e.g: `'Freezer'` **list** Args: slist (list): A list containing these lists: `[y, dname, unit]`. E.g: `[[28,'Temperature','°C'],[12,'Voltage','V']]` dname (str): The devicename of this signal, e.g: `'Freezer'` **seperate** Args: y (list): A list containing all measured values, e.g: `[28, 12]` snames (list): A list containing all signalnames, e.g: `['Temperature','Voltage']` dname (str): The devicename of this signal, e.g: `'Freezer'` unit [optional] (list): A list containing all units, e.g: `['°C', 'V']` x [optional] (list): A list containing all x-data. In a normal dataseries x is always set to time.time(). Returns: bool: True, if data was sent successfully, False, if not. """ if self._cb: now = time.time() if dname is None: dname = self._devicename if slist is None and sdict is None: if type(y) == int or type(y) == float: y = [y] if type(x) != list: x = [now]*len(y) if len(y) != len(x): x = [now]*len(y) self._cb(y=y, snames=snames, dname=dname, unit=unit, x=x) return True elif slist is not None: y = [] x = [] unit = [] snames = [] for sig in slist: if type(sig) == list: if len(sig) == 3: y.append(sig[0]) snames.append(sig[1]) unit.append(sig[2]) x.append(now) self._cb(y=y, snames=snames, dname=dname, unit=unit, x=x) return True elif sdict is not None: for dev in sdict.keys(): dname = dev y = [] x = [] unit = [] snames = [] if type(sdict[dev]) == dict: for sig in sdict[dev].keys(): if type(sdict[dev][sig]) == list: if len(sdict[dev][sig]) == 2: y.append(sdict[dev][sig][0]) snames.append(sig) unit.append(sdict[dev][sig][1]) x.append(now) else: logging.error('STREAM ERROR, signal {}.{} has not this format: [y, "unit"]'.format(dname, sig)) else: logging.error('STREAM_ERROR:signal {}.{} was malformed.'.format(dname, sig)) self._cb(y=y, snames=snames, dname=dname, unit=unit, x=x) else: logging.error('STREAM_ERROR: device {} was malformed.'.format(dname)) return True else: logging.error('STREAM_ERROR: The data you provided with in your plugin was wrong."') else: logging.error('STREAM_ERROR: cannot stream signals. No callback connected') return False def plot(self, x=[], y=[], sname='noName', dname=None, unit='', hold='off', autoResize=False): """ Use this function to send a signal to RTOC. You can send multiple x-y-pairs for one signal. You can either replace the data, which is currently stored in RTOC, if the parameter `hold` is `off` (default). Or you can append the data to the existing data with `hold ='on'`. `hold='mergeX'` will only add xy-pairs, if the x-value is not in the existing data. `hold='mergeY'` will only add xy-pairs, if the y-value is not in the existing data. This function is a wrapper for :py:meth:`.RT_data.plot` Args: x (list): A list containing all x values, e.g: `[1, 2, 3, 4, 5, 6, 7, 8]` y (list): A list containing all y values, e.g: `[28,26,25,24,23,22,22,21]` sname (str): The devicename of this signal, e.g: `'Temperature'` dname (str): The devicename of this signal, e.g: `'Freezer'` unit (str): The signal unit, e.g: `'°C'` hold ('off','on','mergeX' or 'mergeY'): Defines, how RTOC handles the data. (Default: 'off') autoResize (bool): Tell RTOC, to resize the recordLength, if data is too long. (Default: False) Returns: bool: True, if data was sent successfully, False, if not. """ if y == []: y = x x = list(range(len(x))) if dname is None: dname = self._devicename if self._plt: self._plt(x, y, sname, dname, unit, hold=hold, autoResize=autoResize) return True else: logging.warning("No event connected") return False def event(self, text='', sname=None, dname=None, priority=0, id=None, value=None, x=None): """ Use this function to send an event to RTOC. This function is a wrapper for :py:meth:`.RT_data.addNewEvent` Args: text (str): A description of this event, e.g: `'Freezer door opened'` sname (str): The devicename of this event, e.g: `'Temperature'` dname (str): The devicename of this event, e.g: `'Freezer'` priority (int): 0: Information, 1: Warning, 2: Error id (str): Apply an id to this event. This id is used to trigger **Actions** value (any): Unused x (float): Set a custom timestamp (Default: time.time()) Returns: bool: True, if data was sent successfully, False, if not. """ if sname is None: sname = "unknownEvent" if dname is None: dname = self._devicename if self._ev: self._ev(text, sname, dname, x, priority, value=value, id=id) return True else: logging.warning("No event connected") return False def setDeviceName(self, devicename="noDevice"): """ Use this function to set a default devicename. If you do this, you don't need to submit the devicename with any call of any function Args: devicename (str): Default: `'noDevice'` Returns: None """ self._devicename = devicename # Is shown in GUI def close(self): """ This function stops threads using `self.run`. It also closes the QWidget. Normally this function is only called by RTOC, when disconnecting plugins, but you can also call it. """ self.run = False if self.widget: self.widget.hide() self.widget.close() if self._pluginThread and not self._oldPerpetualTimer: self._pluginThread.cancel() def setSamplerate(self, rate): """ Sets the samplerate [Hz] of the defined perpetual timer. Args: rate (float) Returns: bool: True, if perpetual timer was already configured, False, if not. """ if self._pluginThread is not None: self.samplerate = rate return True else: return False def setInterval(self, interval): """ Sets the interval [s] of the defined perpetual timer. Args: interval (float) Returns: bool: True, if perpetual timer was already configured, False, if not. """ if self._pluginThread is not None: self.samplerate = 1/interval return True else: return False @property def samplerate(self): return self._samplerate @samplerate.setter def samplerate(self, samplerate): self._samplerate = samplerate if self._pluginThread is not None and not self._oldPerpetualTimer: self._pluginThread.setSamplerate(samplerate) def info(self, msg): date = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) message = [date, 0, str(msg)] self._log.append(message) logging.info(msg) def warning(self, msg): date = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) message = [date, 1, str(msg)] self._log.append(message) logging.warning(msg) def error(self, msg): date = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) message = [date, 2, str(msg)] self._log.append(message) logging.error(msg) def debug(self, msg): date = str(datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')) message = [date, -1, str(msg)] self._log.append(message) logging.debug(msg) def createPersistentVariable(self, name, fallback=None, dname=None, docs=None): """ Creates a persistent variable, which can be edited and will be restored after restart/reboot. You can create it like this: self.createPersistentVariable('perVar', 5) After this, you can access it's value with 'self.perVar' and edit it in the same way. Args: name (str): Name of the parameter, fallback (any): Alternative value, if parname is not available (for initialization), dname (str): Devicename, selected by default Returns: PersistentVariable: Parameter to be used in Logger. """ # if dname == None: # dname = self._devicename # return PersistentVariable(self.logger, parname, fallback, dname) # Create 'private' parameter with _ in front: self._name if self.logger.isPersistentVariable(name, dname): fallback = self.logger.loadPersistentVariable(name, None, dname) setattr(self.__class__, '_'+name, fallback) # This intermediate function handles the strange double self arguments def setter(self, name, dname, selfself, value): self._setPersistentAttribute(name, value, dname) # Make sure, that the parameters are "the values, which would be represented at this point with print(...)" setpart = partial(setter, self, name, dname) getpart = partial(getattr, self, '_'+name) # Create an attribute with the actual name. The getter refers to it's self._name attribute. The setter function to self._setGroupAttribute(name, value, parameter) setattr(self.__class__, name, property(getpart, setpart)) # If contains docs, create a third attribute at self.__doc_PARNAME__ if docs != None: setattr(self, '__doc_'+name+'__', docs) def _setPersistentAttribute(self, name, value, dname): setattr(self.__class__, '_'+name, value) self.logger.savePersistentVariable(name, value, dname) def initPersistentVariable(self, parname, value=None, dname=None): if dname == None: dname = self._devicename return self.logger.initPersistentVariable(parname, value, dname) def loadPersistentVariable(self, parname, fallback=None, dname=None): """ Loads a persistent variable, which can be edited and will be restored after restart/reboot. Args: parname (str): Name of the parameter, fallback (any): Alternative value, if parname is not available (for initialization), dname (str): Devicename, selected by default Returns: any: Parameter-value """ if dname == None: dname = self._devicename return self.logger.loadPersistentVariable(parname, fallback, dname) def savePersistentVariable(self, parname, value, dname=None): """ Saves a persistent variable to a file in RTOC-directory. Args: parname (str): Name of the parameter, fallback (any): Alternative value, if parname is not available (for initialization), dname (str): Devicename, selected by default Returns: bool: True, if variable successfully saved. """ if dname == None: dname = self._devicename return self.logger.savePersistentVariable(parname, value, dname) def setPerpetualTimer(self, fun, samplerate=None, interval = None, old = False): """ Configures a perpetual timer. A perpetual timer is a thread, which is repeated infinitly in a specified time-interval or samplerate. Args: fun (function): The function to be called periodically. samplerate (float): The desired samplerate. interval (float): The desired time-delay interval. old (bool): If True, an old method for perpetual timer is used (based on :mod:`threading.Thread`). If False, the new method will be used (based on :mod:`threading.Timer`). Returns: bool: True, if perpetual timer could be configured, False, if not. """ if old: self._oldPerpetualTimer = True else: self._oldPerpetualTimer = False if samplerate is None and interval is None: samplerate = self.samplerate elif samplerate is None: samplerate = 1/interval if not self._oldPerpetualTimer: try: self._samplerate = samplerate self._pluginThread = _perpetualTimer(fun, samplerate, self.lockPerpetialTimer) return True except Exception: self._pluginThread = None return False else: try: self._samplerate = samplerate self._pluginThread = Thread(target=self.__updateT, args=(fun,)) return True except Exception: self._pluginThread = None return False def start(self): """ Starts the perpetual timer Returns: bool: True, if perpetual timer was already configured, False, if not. """ if self._pluginThread: self.run = True self._pluginThread.start() return True else: self.run = False return False def cancel(self): """ Stops the perpetual timer Returns: bool: True, if perpetual timer was already configured, False, if not. """ if self._pluginThread: if not self._oldPerpetualTimer: self._pluginThread.cancel() self.run = False return True else: self.run = False return False def __updateT(self, func): diff = 0 while self.run: if diff < 1/self._samplerate: time.sleep(1/self._samplerate-diff) start_time = time.time() func() diff = (time.time() - start_time) def telegram_send_message(self, text, priority=0, permission='write'): """ Sends a message to all clients with given permission and higher permission. Args: text (str): Text to be send to the clients. priority (int): Priority to decide, which allow each client to disable notifications (0: Information, 1: Warning, 2: Error) permission (str): Choose user-permission (blocked, read, write, admin) """ if self._bot is not None: self._bot.send_message_to_all(self._devicename+': '+str(text), priority, permission) else: logging.warning('TelegramBot is not enabled or wrong configured! Can not send message "{}"'.format(text)) def telegram_send_photo(self, path, priority=0, permission='write'): """ Sends the picture at a given path to all clients with given permission and higher permission. Args: path (str): Path to the picture to send. priority (int): Priority to decide, which allow each client to disable notifications (0: Information, 1: Warning, 2: Error) permission (str): Choose user-permission (blocked, read, write, admin) """ if self._bot is not None: self._bot.send_photo(path, priority, permission) else: logging.warning('TelegramBot is not enabled or wrong configured! Can not send photo "{}"'.format(path)) def telegram_send_document(self, path, priority=0, permission='write'): """ Sends any document at a given path to all clients with given permission and higher permission. Args: path (str): Path to the file to send. priority (int): Priority to decide, which allow each client to disable notifications (0: Information, 1: Warning, 2: Error) permission (str): Choose user-permission (blocked, read, write, admin) """ if self._bot is not None: self._bot.send_document(path, priority, permission) else: logging.warning('TelegramBot is not enabled or wrong configured! Can not send file "{}"'.format(path)) def telegram_send_plot(self, signals={}, title='', text='', events=[], dpi=300, priority=0, permission='write'): """ Sends any document at a given path to all clients with given permission and higher permission. Args: signals (dict): Contains multiple sets of x-y data, e.g. ``{'signal1':[1,2,3,4,5],[4,3,6,5,7]}`` title (str): The title displayed above the graph. text (str): The plot-description text events (list): A list containing pseudo-events (text+vertical-line), e.g. ``[[10, 'Hello world at x=10']]`` dpi (int): Resolution of plot. priority (int): Priority to decide, which allow each client to disable notifications (0: Information, 1: Warning, 2: Error) permission (str): Choose user-permission (blocked, read, write, admin) """ if self._bot is not None: self._bot.send_plot(signals, title, text, events, dpi, priority, permission) else: logging.warning('TelegramBot is not enabled or wrong configured! Can not send plot')
class BasePolicy(object): """ Template Policy that implements minimal functionality to run an argument """ def __init__(self, name="base", argument=None): """ Args: name: argument: """ self.name = name self.current_statement = None self.current_premise = None self._cache = [] self.last_dialog = None self.finished = False self._in_agreement = True self.argument = argument self._output = "" self._input = "" self._async_thread = None self._skip_feedback = False self._last_prompt = "" # lib def bind(self, argument): """ Args: argument: """ self.argument = argument self.argument.load() def reset(self): """ """ self._in_agreement = True self.current_premise = None self.current_statement = None self._cache = [] self.last_dialog = None self.finished = False def speak(self, text): """ - normalize text - cache response, self._cache_this(text) - manage output, self._output += text - return normalized text """ text = str(text).strip() self._cache_this(text) if self._output and not self._output.endswith("\n"): self._output += "\n" self._output += text return text def is_cached(self, entry): """ check if entry was used already Args: entry: text or Statement Returns: is_cached (bool) """ entry = str(entry).strip() return entry in self.already_spoken def _cache_this(self, entry): """ Args: entry: """ entry = str(entry).strip() self._cache.append(entry) def _clean_prompt(self, prompt): """ Args: prompt: Returns: """ prompt = prompt or "Do you agree with {{statement}} ?" if isinstance(prompt, list): prompt = random.choice(prompt) if self.current_statement is not None: current_statement = self.current_statement.text.strip() else: current_statement = "what i just said" prompt = prompt \ .replace("{{statement}}", current_statement) \ .replace("{statement}", current_statement) \ .replace("{{ statement }}", current_statement) \ .replace("{ statement }", current_statement) return prompt + " " # dialog data @property def user_agrees(self): """ Does the user agree with the argument Returns: in_agreement (bool) """ return self._in_agreement @property def already_spoken(self): """ Returns: already spoken responses (list) """ return self._cache @property def output(self): """ Returns: current bot dialog (str) """ return self._output @property def intro_statement(self): """ Returns: argument introduction (str) """ if self.argument is not None: return str(self.argument.intro_statement) return "" @property def conclusion_statement(self): """ Returns: argument conclusion (str) """ if self.argument is not None: return self.argument.conclusion_statement return "" @property def premises(self): """ Returns: all premises of this argument (list) """ if self.argument is not None: return self.argument.premises return [] # dialog actions def start(self): """ prepare context of dialog - reset policy, self.reset() - set running flag, self.finished = False - speak intro statement Returns: intro statement (str) """ self.reset() self.finished = False return self.speak(self.intro_statement) def end(self): """ handle outcome of dialog - unset running flag, self.finished = True - return speak conclusion statement Returns: conclusion statement (str) """ self.finished = True return self.speak(self.conclusion_statement) def choose_premise(self, argument=None): """ select which Premise to tackle next Returns: next premise (Premise) """ argument = argument or self.argument choices = [t for t in argument.premises if not self.is_cached(t)] if not len(choices): return None assertion = random.choice(choices) self._cache_this(assertion) # remember assertion return assertion def choose_next_statement(self, premise=None): """ select which Statement to tackle next Returns: next statement (Statement) """ premise = premise or self.current_premise choices = [t for t in premise.statements if not self.is_cached(t)] if not len(choices): # go to next premise next_assertion = self.choose_premise() if next_assertion is None: self.finished = True return None # no statements left self.current_premise = next_assertion return self.choose_next_statement() statement = random.choice(choices) self.current_statement = statement return statement def agree(self): """ Agree with current premise """ self._in_agreement = True def disagree(self): """ Disagree with current premise """ self._in_agreement = False def what(self, default_answer="i don't know how to explain"): """ explain current statement """ answer = default_answer choices = [ t for t in self.current_premise.what if not self.is_cached(t) ] if len(choices): answer = random.choice(choices) return self.speak(answer) def why(self, default_answer="i don't know why"): """ explain cause of current statement """ answer = default_answer choices = [ t for t in self.current_premise.why if not self.is_cached(t) ] if len(choices): answer = choices[0] return self.speak(answer) def how(self, default_answer="i don't know how"): """ explain how current statement """ answer = default_answer choices = [ t for t in self.current_premise.how if not self.is_cached(t) ] if len(choices): answer = random.choice(choices) return self.speak(answer) def when(self, default_answer="i don't know when"): """ explain when current statement happened """ answer = default_answer choices = [ t for t in self.current_premise.when if not self.is_cached(t) ] if len(choices): answer = random.choice(choices) return self.speak(answer) def where(self, default_answer="i don't know where"): """ explain where current statement happened """ answer = default_answer choices = [ t for t in self.current_premise.where if not self.is_cached(t) ] if len(choices): answer = random.choice(choices) return self.speak(answer) def sources(self, default_answer="i don't remember where i learned this"): """ sources of current statement """ answer = default_answer if len(self.current_premise.sources): answer = " ".join(self.current_premise.sources) return answer def skip_feedback(self): """ Do not ask for user feedback """ self._skip_feedback = True def reprompt(self): """ Speak last used prompt Returns: last prompt (str) """ return self.speak(self._last_prompt) # sync def _run_once(self): """ Returns: """ # check if argument is fully exposed if self.finished: return None # check if we have an assertion if self.current_premise is None: current_assertion = self.choose_premise() self.current_premise = current_assertion # pick action if not self.user_agrees: return self.on_negative_feedback() else: return self.on_positive_feedback() def run(self): """ run the interaction, ask if user agrees or not after every statement NOTE: ignores on user input callback, mostly meant for quick testing """ # introduce argument print(self.start()) while not self.finished: try: # choose output output = self._run_once() if output is None: # wait for output continue print(output) if self.finished: break # get user feedback if self._skip_feedback: self._skip_feedback = False continue if self.get_feedback(): self.agree() else: self.disagree() except Exception as e: log.exception(e) # finish off argument print(self.end()) def get_feedback(self, prompt=None): """ used in run(), if running async wait_for_feedback is used instead ask user if he agrees with current statement or not prompt is a string or list of strings, if it's a list a random entry will be picked return True or False """ prompt = self._clean_prompt(prompt) self._last_prompt = prompt return "y" in input(prompt).lower() # async def wait_for_input(self): """ wait until self.submit_input is called """ self._input = "" while not self._input: sleep(0.5) def wait_for_feedback(self, prompt=None): """ ask user if he agrees with current statement or not prompt is a string or list of strings, if it's a list a random entry will be picked return True or False """ prompt = self._clean_prompt(prompt) self._output += "\n" + prompt self._last_prompt = prompt self.wait_for_input() return "y" in self._input.lower() def submit_input(self, text): """ Args: text: utterance (str) """ self._output = "" if self.on_user_input(text): self._input = text def run_async(self): """ Start listening for user input """ self._async_thread = Thread(target=self._async_loop) self._async_thread.setDaemon(True) self._async_thread.start() def stop(self): """ Stop listening for user input """ self.finished = True try: self._async_thread.join() self._async_thread.cancel() except: pass self._async_thread = None def _async_loop(self): """ run the interaction async """ # introduce argument self.start() while not self.finished: try: # choose output if not self._run_once(): continue if self._skip_feedback: self._skip_feedback = False continue # get user feedback if self.wait_for_feedback(): self.agree() else: self.disagree() except Exception as e: log.exception(e) # finish off argument self.end() # events def on_user_input(self, text): """ handle user input intent parsing should be done here typical actions are - calling self.agree() or self.disagree() to direct the policy (return True) - calling self.what(), self.why(), self.how(), self.when(), self.where() and setting the output (return False) NOTE: only when running async return True or False, this determines if dialog should proceed or wait for different user input """ return True def on_positive_feedback(self): """ react to positive feedback by default goes to next statement """ statement = self.choose_next_statement() if not statement: return None return self.speak(statement) def on_negative_feedback(self): """ react to negative feedback by default goes to next statement """ statement = self.choose_next_statement() if not statement: return None return self.speak(statement)