Beispiel #1
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 #2
0
 def _send(self, packet):
     # Check STX and ETX
     if packet.stx != KFNET_STX or packet.etx != KFNET_ETX:
         skibase.log_warning(("Invalid packet: \n%s") \
                             %(bytes_to_hex_str(bytes(packet))))
         return
     # Verify length
     if len(bytes(packet)) != MCAST_PACKET_LEN:
         skibase.log_warning(("Packet ID '%s'. Packet is %d/%d bytes long") \
                              %(packet.id.decode(),
                              len(bytes(packet)),
                              MCAST_PACKET_LEN))
         return
     # Check if we will resend packet (if not new packet)
     number = random.randint(0x00, 0xFF)
     if packet.rp < number and packet.ttl != KFNET_TTL_RETRANS:
         skibase.log_debug(("Discard resend of packet ID '%s' (%d < %d)") \
                           %(packet.id.decode(), packet.rp, number))
         return
     # Decrease TTL
     if packet.ttl < 1:
         skibase.log_debug(("Discard packet ID '%s'. TTL is %d") \
                           %(packet.id.decode(), packet.ttl))
         return
     packet.ttl -= 1
     # Send
     self.mcast_sender_obj.mcast_send(bytes(packet))
     skibase.log_info(("Sent packet ID '%s'. TTL is %d") \
                      %(packet.id.decode(), packet.ttl+1))
Beispiel #3
0
def do_delay_task(task):
    if task > skibase.TASK_DELAY_MS and \
       ((task & skibase.MAJOR_TASK) == skibase.TASK_DELAY_MS):
        delay = task & skibase.MINOR_TASK
        skibase.log_debug("Delay: %d ms" % delay)
        time.sleep(delay / 1000)
    else:
        skibase.log_warning("Delay: task %04x not within limits" % task)
Beispiel #4
0
def get_program_from_task(task):
    if task >= skibase.TASK_PROGRAM and \
       ((task & skibase.MAJOR_TASK) == skibase.TASK_PROGRAM):
        program = task & skibase.MINOR_TASK
        skibase.log_debug("Program from task: %s" % \
          program_id_to_str(program))
        return program
    else:
        skibase.log_warning("Program: task %s not within limits" % \
          skibase.task_to_str(task))
        return 0
Beispiel #5
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 #6
0
 def run(self):
     while not self._got_stop_event():
         this_program = self.program
         skibase.log_info("sphat: %02x" % this_program)
         try:
             scrollphathd.clear()
             if this_program == 0x00:
                 self.show_string(this_program, "Kesselfall 2019 ")
             elif this_program == 0x01:
                 self.do_storm(this_program)
             elif this_program == 0x02:
                 self.do_graph(this_program)
             elif this_program == 0x03:
                 self.do_forest_fire(this_program)
             elif this_program == 0x04:
                 self.do_storm(this_program)
             elif this_program == 0x05:
                 self.do_cells(this_program)
             elif this_program == 0x06:
                 self.show_string(this_program, "Kesselfall 2019 ")
             elif this_program == 0x07:
                 self.do_forest_fire(this_program)
             elif this_program == 0x08:
                 self.do_swirl(this_program)
             elif this_program == 0x09:
                 self.do_plasma(this_program)
             elif this_program == 0x0A:
                 self.do_swirl(this_program)
             elif this_program == 0x0B:
                 self.do_plasma(this_program)
             elif this_program == 0xff:
                 while self.program == this_program and not self._got_stop_event(
                 ):
                     scrollphathd.show()
             else:
                 scroll_string = "ERROR%d" % this_program
         except:
             skibase.log_warning("sphat does not work")
             for i in range(int(60000 / SCROLL_TEXT_RATE_MS)):
                 if self.program == this_program and not self._got_stop_event(
                 ):
                     time.sleep(SCROLL_TEXT_RATE_MS / 1000)
                 else:
                     break
Beispiel #7
0
def test():
    # Arguments
    parser = argparse.ArgumentParser(description=__doc__)
    parser = skibase.args_add_log(parser)
    parser = args_add_butt(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 Butt
    butt_obj = butt_start(main_queue)
    
    # Loop
    skibase.log_notice("Running butt unittest")
    while not skibase.signal_counter and butt_obj.status():
        try:
            task = main_queue.get(block=True, timeout=0.25)
        except queue.Empty:
            task = None
        if task is not None:
            if task == skibase.TASK_BUTTON_PRESS:
                skibase.log_notice("butt press")
            elif task == skibase.TASK_BUTTON_LONG:
                skibase.log_notice("butt long press")
            else:
                skibase.log_warning("butt got unknown task")
        
    # Stop Butt
    butt_stop(butt_obj)

    skibase.log_notice("butt unittest ended")
Beispiel #8
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()