Beispiel #1
0
 def run(self):
     t_next = skibase.get_time_millis() + KFNET_PACKET_TIMEOUT_MS
     while not self._got_stop_event():
         # Send to network (from queue)
         while self._queue.empty() is False:
             packet = self._queue.get()
             self._send(packet)
             # relay back the task that was sent.
             # The main program will wait for the task to be relayed
             # back before acting.
             # Add delay before relaying
             self._main_queue.put(skibase.TASK_DELAY_MS + 12)
             self._main_queue.put(packet.task)
             self._queue.task_done()
         # Receive from network (to queue)
         packet = self._receive()  # blocking
         if packet is not None:
             self._main_queue.put(packet.task)
         # Check if p_to for p_id is timed out (once every X ms)
         t_now = skibase.get_time_millis()
         if t_now > t_next:
             for [p_to, p_id] in self._known_packet_ids[:]:
                 if p_to < t_now:
                     skibase.log_debug(
                       ("Removing packet ID '%s' with timeout %d.") \
                       % (p_id.decode(), p_to))
                     self._known_packet_ids.remove([p_to, p_id])
             t_next = t_next + 1000
     # Empty queue and stop
     while self._queue.empty() is False:
         self._queue.get()
         self._queue.task_done()
Beispiel #2
0
def test():
    skibase.set_time_start()

    # Arguments
    parser = argparse.ArgumentParser(description=__doc__)
    parser = skibase.args_add_log(parser)
    parser = args_add_kfnet(parser)
    args = parser.parse_args()

    # Parse
    skibase.log_config(args.loglevel.upper(), args.syslog)

    # Signal
    skibase.signal_setup([signal.SIGINT, signal.SIGTERM])

    # Start queue
    main_queue = queue.Queue()

    # Start kfnet
    kfnet_obj = kfnet_start(main_queue, args.interface, MCAST_GRP,
                            args.ip_addr, args.mcast_port)

    # Loop (main)
    skibase.log_notice("Running Kesselfall network unittest")
    counter = random.randint(0, 0xFF)
    t_next_send = skibase.get_time_millis()
    while not skibase.signal_counter and kfnet_obj.status():
        try:
            task = main_queue.get(block=True, timeout=0.25)
        except queue.Empty:
            task = None
        if task:
            try:
                skibase.log_notice("-> task: %s" % skibase.task_to_str(task))
            except:
                skibase.log_warning("kfnet got unknown task")
            main_queue.task_done()
        if t_next_send < skibase.get_time_millis():
            # Send packet to kfnet task
            # otherwise use kfnet_obj.queue_task(task)
            packet = kfnet_obj.create_packet()
            packet.task = skibase.TASK_PROGRAM + \
                          (counter & skibase.MINOR_TASK)
            kfnet_obj.queue_packet(packet)
            skibase.log_notice("<- Packet: %s :: task: %s" %\
              (packet.id.decode(), task_to_str(packet.task)))
            t_next_send = t_next_send \
                          + random.randint(CHANGE_RATE_MIN, CHANGE_RATE_MAX)
            counter += 1

    kfnet_obj = kfnet_stop(kfnet_obj)
    skibase.log_notice("Kesselfall network unittest ended")
Beispiel #3
0
 def _receive(self):
     data = self.mcast_listener_obj.mcast_check_receive()
     if data is not None:
         # On an ad-hoc mesh network we will probably receive the
         # same packet multiple times. We will only store each
         # packet (packet ID) for a short time, and then discard
         # it in case of an "rereceived" packet.
         packet = KesselfallHeader.from_buffer_copy(data)
         # Check if packet was sent by ourselves
         if packet.src == self.source_id:
             return None
         # Check packet is valid
         if packet.stx != KFNET_STX or packet.etx != KFNET_ETX:
             skibase.log_warning(("Invalid packet: \n%s") \
                             %(bytes_to_hex_str(data)))
             return None
         t_timeout = skibase.get_time_millis() + KFNET_PACKET_TIMEOUT_MS
         for i, [p_to, p_id] in enumerate(self._known_packet_ids[:]):
             # Check if this packet was already received.
             if packet.id == p_id:
                 # Renew timeout
                 skibase.log_debug(
                   "Renewing timout of packet ID '%s' from %d to %d." \
                   % (packet.id.decode(), p_to, t_timeout))
                 self._known_packet_ids[i] = [t_timeout, p_id]
                 return None
         # We have identified a new packet
         # Send packet and add it to the list of _known_packet_ids
         self._send(packet)  # Prioritize send
         skibase.log_info(
           "Received packet '%s' with timeout: %d." \
           % (packet.id.decode(), t_timeout))
         self._known_packet_ids.append([t_timeout, packet.id])
         return packet
     return None
Beispiel #4
0
def loop(main_queue, program_id, kfnet_obj, butt_obj, sphat_obj, ws281x_obj,
         dbgled_obj):
    next_kick = 0
    program_can_change_again = 0

    while not skibase.signal_counter \
      and kfnet_obj.status() \
      and butt_obj.status() \
      and sphat_obj.status() \
      and ws281x_obj.status() \
      and dbgled_obj.status():
        next_kick = wd.wd_check(next_kick)
        try:
            task = main_queue.get(block=True, timeout=LOOP_SPEED)
        except queue.Empty:
            task = None
        if task:
            if task == skibase.TASK_BUTTON_PRESS:
                now = skibase.get_time_millis()
                if now >= program_can_change_again:
                    program_id = get_next_program(program_id)
                    # Add program_id to kfnet as a task that is transmitted
                    # Do not execute task yet, but wait for kfnet to relay
                    # the task back when it is sent. This should make the
                    # network appear more "in sync".
                    kfnet_obj.queue_task(skibase.TASK_PROGRAM + program_id)
                    skibase.log_info("task: press: %s" % \
                      program_id_to_str(program_id))
                    program_can_change_again = now + PROGRAM_CHANGE_BLOCK_MS
                else:
                    skibase.log_info("Ignoring program change.")
            elif task == skibase.TASK_BUTTON_LONG_1:
                skibase.log_info("task: long press")
                ws281x_obj.program = 0xff
                sphat_obj.program = 0xff
                dbgled_obj.program = 0xff
            elif task == skibase.TASK_BUTTON_LONG_2:
                do_shutdown()
                main_queue.task_done()
                break
            elif (task & skibase.MAJOR_TASK) == skibase.TASK_DELAY_MS:
                skibase.log_info("task: delay")
                do_delay_task(task)
            elif (task & skibase.MAJOR_TASK) == skibase.TASK_PROGRAM:
                program_id = get_program_from_task(task)
                ws281x_obj.program = program_id
                sphat_obj.program = program_id
                dbgled_obj.program = program_id
                skibase.log_notice("task: program: %s" % \
                  program_id_to_str(program_id))
            else:
                skibase.log_warning("skipi got unknown task!")
                try:
                    skibase.log_warning("task: %s" % task_to_str(task))
                except:
                    skibase.log_warning("log task failed...")
                    print(task)
            main_queue.task_done()
Beispiel #5
0
 def create_packet(self):
     # Fill packet with default stuff
     packet = KesselfallHeader()
     packet.stx = KFNET_STX
     packet.id = generate_packet_id().encode()
     packet.src = self.source_id
     packet.ttl = KFNET_TTL_RETRANS
     packet.rp = KFNET_RETRANS_PROBABILITY
     packet.etx = KFNET_ETX
     # Add packet to _known_packet_ids
     t_timeout = skibase.get_time_millis() + KFNET_PACKET_TIMEOUT_MS
     self._known_packet_ids.append([t_timeout, packet.id])
     return packet
Beispiel #6
0
    def run(self):
        button = gpiozero.Button(BUTT_PIN,
                                 pull_up=True)

        while not self._got_stop_event():
            button.wait_for_press(timeout=0.500)
            if not button.is_pressed:
                continue
            t_press = skibase.get_time_millis()
            
            button.wait_for_release(timeout=(LONG_PRESS_TIME+10)/1000)
            t_release = skibase.get_time_millis()
            
            press_time = t_release - t_press
            
            if press_time >= LONG_PRESS_TIME:
                skibase.log_debug("Button Long press")
                self._main_queue.put(skibase.TASK_BUTTON_LONG_1)
                if button.is_pressed:
                    button.wait_for_release(timeout=None)
                self._main_queue.put(skibase.TASK_BUTTON_LONG_2)
            else:
                self._main_queue.put(skibase.TASK_BUTTON_PRESS)
                skibase.log_debug("Button Press")
Beispiel #7
0
def wd_check(next_kick):
    time_ms = skibase.get_time_millis()
    if time_ms >= next_kick or next_kick == 0:
        wd_kick()
        next_kick = time_ms + (WD_INTERVAL_SEC * 1000) - WD_GUARD_TIME_MS
    return next_kick