Esempio n. 1
0
class NanoGateWay:
    def __init__(self):
        self.sock = None
        self.connected = False
        self.wlan = WLAN(mode=WLAN.STA)
        self.riders = {} # dictionary of riders
        # initialize LoRa as a Gateway (with Tx IQ inversion)
        self.lora = LoRa(tx_iq=True, rx_iq=False)

    def connect_to_wlan(self):
        if not self.wlan.isconnected():
            # TODO: change for the correct credentials here (ssid and password)
            self.wlan.connect(ssid='KCOMIoT', auth=(None, '10noCHOSun'), timeout=7000)
            while not self.wlan.isconnected():
                time.sleep_ms(50)

    def connect_to_server(self):
        if self.sock:
            self.sock.close()
        self.sock = socket.socket()                 # TCP
        try:
            self.sock.connect((TCP_IP, TCP_PORT))   # TODO
            self.sock.settimeout(1)
            self.connected = True
        except Exception:
             self.sock.close() # just close the socket and try again later
             print('Socket connect failed, retrying...')
             time.sleep_ms(500)
    
    def send(self, msg):
        if self.connected and self.sock:
            try:
                self.sock.send(msg)
            except Exception:
                self.connected = False
                self.sock.close()
                self.sock = None

    def new_rider(self, name, company, badge, bike, eventid, ridetimestamp):
        rider = Rider(name, company, badge, bike, eventid, ridetimestamp)
        self.riders[bike] = rider

    def recv(self):
        if self.connected and self.sock:
            try:
                data = self.sock.recv(1024)
            except socket.timeout:
                return None
            except socket.error as e:
                if e.args[0] != EAGAIN:
                    self.connected = False
                return None
            return data

    def run(self):
        data = self.recv()
        if data:
            print(data)
            parsed_json = json.loads(data.decode('ascii'))
            print(parsed_json)
            if parsed_json['RideStatus'] == "started":
                self.new_rider(parsed_json['RiderName'], parsed_json['Company'], 
                               parsed_json['BadgeNumber'], parsed_json['BikeID'],parsed_json['EventID'],parsed_json['RideTimestamp'])
                # start the race
                print(str({'id':parsed_json['BikeID'], 'cm': 's'}))
                packet_tx = json.dumps({'id':parsed_json['BikeID'], 'cm': 's'})
                print ("packet_tx = " + packet_tx)
                self.lora.send(packet_tx, True)

        lora_d = self.lora.recv()
        if lora_d:
            parsed_json = json.loads(lora_d.decode('ascii'))
            print(parsed_json)
            # update the rider info (if the rider already exists)
            bike_id = parsed_json['id']
            if bike_id in self.riders:
                self.riders[bike_id].speed = parsed_json['sp']
                self.riders[bike_id].distance = parsed_json['ds']
                self.riders[bike_id].crank = parsed_json['cr']
                if parsed_json['st'] == 'i' or parsed_json['st'] == 'f':
                    self.riders[bike_id].status = 'finished'
                elif parsed_json['st'] == 'r':
                    self.riders[bike_id].status = 'counting'
                else:
                    self.riders[bike_id].status = 'started'
                # Assemble the TCP packet
                wheel_count=self.riders[bike_id].crank * 7
                json_d = {"RiderName":self.riders[bike_id].name, "Company":self.riders[bike_id].company, "BadgeNumber":self.riders[bike_id].badge, \
                          "EventID":self.riders[bike_id].eventid, "RideTimestamp":'{:f}'.format(self.riders[bike_id].ridetimestamp), "BikeID":bike_id, \
                          "RideStatus":self.riders[bike_id].status, "RideInfo":[{"CounterTimestamp": float(time.ticks_ms()), \
                          "CrankCounter":self.riders[bike_id].crank, "WheelCounter":wheel_count}]}
                json_str = json.dumps(json_d)
                print("Outgoing from Gateway: " + str(json_str))
                self.send(json_str+"\n")
        if not self.connected:
            self.connect_to_wlan()
            self.connect_to_server()
Esempio n. 2
0
def main():
    start_delay_ms = 0
    time_ms = time.ticks_ms()
    last_sent_ms = time_ms
    state = 'IDLE'   # States are: 'IDLE', 'RUNNING', 'FINISHED'

    Pin('G4', mode=Pin.IN, pull=Pin.PULL_DOWN)
    crank = PulseCounter('G5', Pin.PULL_DOWN, Pin.IRQ_RISING, 250)

    # initialize LoRa as a node (with Rx IQ inversion)
    lora = LoRa(tx_iq=False, rx_iq=True)

    # LCD pin configuration:
    lcd_rs        = 'G11'
    lcd_en        = 'G12'
    lcd_d4        = 'G15'
    lcd_d5        = 'G16'
    lcd_d6        = 'G13'
    lcd_d7        = 'G28'

    lcd_columns   = 16
    lcd_rows      = 1

    lcd = LCD.CharLCD(lcd_rs, lcd_en, lcd_d4, lcd_d5, lcd_d6, lcd_d7, lcd_columns, lcd_rows)

    rider = Rider(lcd)

    print("Ready for first rider.")
    lcd.clear()
    lcd.message("Ready fo\nr first rider.")

    while True:
        if state == 'IDLE':
            packet_rx = lora.recv()
            if packet_rx:
                try:
                    parsed_json = json.loads(packet_rx.decode('ascii'))
                    cmd = parsed_json['cm']
                    id = parsed_json['id']
                    if cmd == 's' and id == config.id:
                        print('Going to running state')
                        start_delay_ms = ((machine.rng() % 30) * 100) + time.ticks_ms()
                        # send 's' (started) state over LoRa
                        packet_tx = json.dumps({'id': config.id, 'cr':0, 'ds':int(rider.distance()), 'sp':int(rider.avg_speed()), 'st':'s'})
                        lora.send(packet_tx, True)
                        rider.countdown()
                        crank.counter = 0
                        # change to the running state and notify the gateway
                        state = 'RUNNING'
                        packet_tx = json.dumps({'id': config.id, 'cr':0, 'ds':int(rider.distance()), 'sp':int(rider.avg_speed()), 'st':'r'})
                        lora.send(packet_tx, True)
                except Exception:
                    print('Corrupted LoRa packet')
            else:
                time.sleep_ms(50)

        elif state == 'RUNNING':
            if rider.ride(crank):
                print('Going to finished state')
                state = 'FINISHED'
                packet_tx = json.dumps({'id': config.id, 'cr':crank.counter, 'ds':int(rider.distance()), 'sp':int(rider.avg_speed()), 'st':'f'})
                lora.send(packet_tx, True)
            time_ms = time.ticks_ms()
            if time_ms < start_delay_ms:
                pass
            elif time_ms > last_sent_ms + LORA_SEND_PERIOD_MS:
                last_sent_ms = time_ms
                packet_tx = json.dumps({'id':config.id, 'cr':crank.counter, 'ds':int(rider.distance()), 'sp':int(rider.avg_speed()), 'st':'r'})
                print(packet_tx + ' {}'.format(last_sent_ms))
                lora.send(packet_tx, True)
            else:
                print('attempt to receive lora')
                packet_rx = lora.recv()
                if packet_rx:
                    print(packet_rx)
                    try: # I've seen this failing sometimes
                        parsed_json = json.loads(packet_rx.decode('ascii'))
                        # check the packet received and process the commands
                    except Exception:
                        print('Corrupted LoRa packet')

            time.sleep(1.0 - (((time.ticks_ms() / 1000) - rider.starttime) % 1.0))

        else:
            print('finishing ride')
            rider.finish()
            # change to the running state and notify the gateway
            state = 'IDLE'
            packet_tx = json.dumps({'id': config.id, 'cr':crank.counter, 'ds':int(rider.distance()), 'sp':int(rider.avg_speed()), 'st':'i'})
            lora.send(packet_tx, True)
            crank.counter = 0