def get_imsi(lte: LTE) -> str:
    """
    Get the international mobile subscriber identity (IMSI) from SIM
    """
    IMSI_LEN = 15
    get_imsi_cmd = "AT+CIMI"

    print("\n>> getting IMSI")
    modem_suspended = False
    if lte.isconnected():
        lte.pppsuspend()
        modem_suspended = True
    result = _send_at_cmd(lte, get_imsi_cmd)
    if modem_suspended:
        lte.pppresume()
    if result[-1] == 'OK' and len(result[0]) == IMSI_LEN:
        return result[0]

    raise Exception("getting IMSI failed: {}".format(repr(result)))
def set_modem_func_lvl(lte: LTE, func_lvl: int):
    """
    Sets modem to the desired level of functionality
    Throws exception if operation fails.
    :param func_lvl: the functionality level (0: minimum,
                                              1: full,
                                              4: disable modem both transmit and receive RF circuits)
    """
    get_func_cmd = "AT+CFUN?"
    set_func_cmd = "AT+CFUN={}".format(func_lvl)

    print("\n>> setting up modem")
    modem_suspended = False
    if lte.isconnected():
        lte.pppsuspend()
        modem_suspended = True

    # check if modem is already set to the correct functionality level
    result = _send_at_cmd(lte, get_func_cmd)
    if result[-1] == 'OK' and result[-2] == '+CFUN: {}'.format(func_lvl):
        if modem_suspended:
            lte.pppresume()
        return

    # set modem functionality level
    result = _send_at_cmd(lte, set_func_cmd)
    if result[-1] == 'OK':
        # check if modem is set and ready
        result = _send_at_cmd(lte, get_func_cmd)
        if result[-1] == 'OK' and result[-2] == '+CFUN: {}'.format(func_lvl):
            if modem_suspended:
                lte.pppresume()
            return

    if modem_suspended:
        lte.pppresume()
    raise Exception("setting up modem failed: {}".format(repr(result)))
class NetworkConnector:

    def __init__(self):
        self.logger = logging.get_logger(__name__)
        self.lte = LTE()

    def _attach(self):
        """
            Attaches to the 1nce network
        """
        self.lte.attach()
        while not self.lte.isattached():
            time.sleep(0.5)
            print(".", end="")
        self.logger.info("Sim attached to iot.1nce.net")

    def connect(self):
        """
            Connects to the 1nce network
        """
        self._attach()
        self.lte.connect()
        while not self.lte.isconnected():
            time.sleep(0.5)
        self.logger.info("Sim connected to iot.1nce.net")

    def disconnect(self):
        self.lte.disconnect()
        self.logger.info("Sim disconnected from iot.1nce.net")

    def _send_at_command(self, command):
        """
            Sends AT command over the modem

        :rtype: Response string
        """
        self.lte.pppsuspend()
        resp = self.lte.send_at_cmd(command)
        self.lte.pppresume()
        return resp

    def get_reception(self):
        """
            Gets the current reception to the 1nce network

        :return: Number Reception to the 1nce network
        """
        return self._send_at_command("AT+CSQ")

    def get_ip_address(self):
        """"
            Gets the Device it's Local IP address

        :return IP Address
        """
        resp = self._send_at_command("AT+CGPADDR=1")
        self.logger.info(resp)
        search = re.search(r"\"([1-2]?\d?\d\.[1-2]?\d?\d\.[1-2]?\d?\d\.[1-2]?\d?\d)\"", resp)
        if search:
            return search.group(1)
        return None
Exemple #4
0
        elif line == "ERROR":
            returnOk = False
        else:
            # try:
            #     returnVector += [line.split(" ")[1]]
            # except:
            returnVector += [line]
        if verbose:
            print(line)
    return (returnOk, returnVector)

lte = LTE()
try:
    print("imei", lte.imei())
except:
    lte.pppsuspend()
    print("imei", lte.imei())


send_at_cmd_pretty("AT+CPSMS=?")
# +CPSMS: (0-2), , ,("00000000"-"11111111"),("00000000"-"11111111")
#         modes 0-2
#               ^no Periodic-RAU values
#                 ^no GPRS READY timer values
#                   ^Periodic TAU values : 0000 0000 - 1111 1111
#                                            ^Active Time values
# +CPSMS:
# (list of supported <mode>s),
# (list of supported <Requested_Periodic-RAU>s),
# (list of supported <Requested_GPRS-READY-timer>s) in GERAN/UTRAN,
# (list of supported <Requested_Periodic-TAU>s), in E-UTRAN
Exemple #5
0
        print("\nConnected in attempt #"+str(i+1))
        break

packet = b'$\x1a\x01\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03www\x06google\x03com\x00\x00\x01\x00\x01'
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(20)
s.connect(("8.8.8.8", 53))
s.send(packet)
resp=s.recv(100)
result=False
if (len(resp)>34): # very hacky error checking
    ip=resp[-4:]
    result=str(ip[0])+'.'+str(ip[1])+'.'+str(ip[2])+'.'+str(ip[3])
print("DNS result: "+str(result))

lte.pppsuspend() # can't send AT commands while in data mode
time.sleep_ms(100)
csq=lte.send_at_cmd('AT+CSQ').replace('\r\n','').replace('OK','')
sgnl=int(csq.split(',')[0].split(' ')[1])
if sgnl!=99:
    sgnl=-113+(2*sgnl)
    cesq=lte.send_at_cmd('AT+CESQ').replace('\r\n','').replace('OK','').split(',')
    rsrq=int(cesq[4])
    if rsrq!=255:
        rsrq=-20+(rsrq*0.5)
        rsrp=int(cesq[5])
    if rsrp!=255:
        rsrp=-140+rsrp

print(sgnl,rsrq,rsrp)
lte.pppresume()
class DatacakeGateway:
    def machine_callback(self, arg):
        evt = machine.events()
        if (evt & machine.PYGATE_START_EVT):
            self.machine_state = config.GATEWAY_STATE_OK
            pycom.rgbled(config.RGB_GATEWAY_OK)
        elif (evt & machine.PYGATE_ERROR_EVT):
            self.machine_state = config.GATEWAY_STATE_ERROR
            pycom.rgbled(config.RGB_GATEWAY_ERROR)
        elif (evt & machine.PYGATE_STOP_EVT):
            self.machine_state = config.GATEWAY_STATE_STOP
            pycom.rgbled(config.RGB_GATEWAY_STOP)

    def __init__(self):

        print("Init: Initialization of Gateway class...")

        # Machine
        machine.callback(
            trigger=(machine.PYGATE_START_EVT | machine.PYGATE_STOP_EVT
                     | machine.PYGATE_ERROR_EVT),
            handler=self.machine_callback)
        self.machine_state = 0

        # LTE
        self.lte = LTE()
        self.lte_connection_state = 0

        # RTC
        self.rtc = RTC()

        # Gateway
        # Read the GW config file from Filesystem
        self.gateway_config_file = None

        # Timers
        self.rgb_breathe_timer = Timer.Chrono()

        # Startup
        # Should be called outside init
        # self.start_up()

    def lte_event_callback(self, arg):
        #self.blink_rgb_led(5, 0.25, config.RGB_LTE_ERROR)
        #self.lte.deinit()
        #machine.reset()
        print(
            "\n\n\n#############################################################"
        )
        print("CB LTE Callback Handler")
        ev = arg.events()  # NB: reading the events clears them
        t = time.ticks_ms()
        print("CB", t, time.time(), ev, time.gmtime())
        self.blink_rgb_led(3, 0.25, config.RGB_LTE_ERROR)
        if ev & LTE.EVENT_COVERAGE_LOSS:
            print("CB", t, "coverage loss")
        if ev & LTE.EVENT_BREAK:
            print("CB", t, "uart break signal")
        try:
            self.lte.pppsuspend()
            if not self.lte.isattached():
                print("not attached ... reattach")
                self.lte.detach()
                self.init_lte()
            else:
                print("attached ... resume")
                self.lte.pppresume()
        except Exception as ex:
            sys.print_exception(ex)
        print(
            "#############################################################\n\n\n"
        )

    def init_gateway(self):
        print("Init GW: Starting LoRaWAN Concentrator...")
        try:
            self.gateway_config_file = open(config.GW_CONFIG_FILE_PATH,
                                            'r').read()
        except Exception as e:
            print("Error opening Gateway Config: {}".format(e))
            # TODO: Handle Error
            return False
        else:
            machine.pygate_init(self.gateway_config_file)
            print("Init GW: LoRaWAN Concentrator UP!")
            return True

    def init_rtc(self):
        print("Init RTC: Syncing RTC...")
        try:
            self.rtc.ntp_sync(server="pool.ntp.org")
            while not self.rtc.synced():
                self.blink_rgb_led(1,
                                   0.25,
                                   config.RGB_RTC_IS_SYNCING,
                                   delay_end=False)
            self.blink_rgb_led(3, 0.1, config.RGB_RTC_IS_SYNCING)
        except Exception as e:
            print("Exception syncing RTC: {}".format(e))
            return False
        else:
            print("Init RTC: Synced!")
            return True

    def init_lte(self):

        self.lte_connection_state = 0
        self.lte.init()
        #self.lte.lte_callback(LTE.EVENT_COVERAGE_LOSS, self.lte_event_callback)
        self.lte.lte_callback(LTE.EVENT_BREAK, self.lte_event_callback)

        while True:

            # attach LTE
            if self.lte_connection_state == 0:
                print("Init LTE: Attaching LTE...")
                self.lte.attach(band=config.LTE_BAND, apn=config.LTE_APN)
                while not self.lte.isattached():
                    self.blink_rgb_led(1,
                                       0.25,
                                       config.RGB_LTE_IS_ATTACHING,
                                       delay_end=False)
                self.blink_rgb_led(3, 0.1, config.RGB_LTE_IS_ATTACHING)
                self.lte_connection_state += 1
                print("Init LTE: Attached!")

            # connect LTE
            if self.lte_connection_state == 1:
                print("Init LTE: Connecting LTE...")
                self.lte.connect()
                while not self.lte.isconnected():
                    self.blink_rgb_led(1,
                                       0.25,
                                       config.RGB_LTE_IS_CONNECTING,
                                       delay_end=False)
                self.blink_rgb_led(3, 0.1, config.RGB_LTE_IS_CONNECTING)
                self.lte_connection_state += 1
                print("Init LTE: Connected!")

            # done
            if self.lte_connection_state == 2:
                return True

    def blink_rgb_led(self,
                      times,
                      speed,
                      color_on,
                      color_off=config.RGB_OFF,
                      delay_end=True):
        for index in range(times):
            pycom.rgbled(config.RGB_OFF)
            time.sleep(speed)
            pycom.rgbled(color_on)
            time.sleep(speed)
        pycom.rgbled(config.RGB_OFF)
        if delay_end is True:
            time.sleep(0.1)

    def start_up(self):
        print("Start Up: Now starting up Gateway...")
        self.init_lte()
        self.init_rtc()
        self.init_gateway()
        #self.main_loop()

    def main_loop(self):

        # Start Timers
        self.rgb_breathe_timer.start()

        while True:

            if self.rgb_breathe_timer.read(
            ) > config.TIMER_RGB_BREATHE_INTERVAL:
                self.rgb_breathe_timer.reset()
Exemple #7
0
class StartIoT:
    def __init__(self, network=LTE_M):
        self._network = network
        self.lte = LTE()
        try:
            self.lte.deinit()
            self.lte.reset()
        except:
            pass
        sleep(5)

        self.lte.init()
        sleep(5)

        self._assure_modem_fw()

    def _assure_modem_fw(self):
        response = self.lte.send_at_cmd('ATI1')
        if response != None:
            lines = response.split('\r\n')
            fw_id = lines[1][0:3]
            is_nb = fw_id == 'UE6'
            if is_nb:
                print('Modem is using NB-IoT firmware (%s/%s).' %
                      (lines[1], lines[2]))
            else:
                print('Modem in using LTE-M firmware (%s/%s).' %
                      (lines[1], lines[2]))
            if not is_nb and self._network == NB_IOT:
                print(
                    'You cannot connect using NB-IoT with wrong modem firmware! Please re-flash the modem with the correct firmware.'
                )
                raise WrongNetwork
            if is_nb and self._network == LTE_M:
                print(
                    'You cannot connect using LTE-M with wrong modem firmware! Please re-flash the modem with the correct firmware.'
                )
                raise WrongNetwork
        else:
            print('Failed to determine modem firmware. Rebooting device...')
            reset()  # Reboot the device

    def _get_assigned_ip(self):
        ip_address = None
        try:
            self.lte.pppsuspend()
            response = self.send_at_cmd_pretty('AT+CGPADDR=1')
            self.lte.pppresume()
            lines = response.split('\r\n')
            sections = lines[1].split('"')
            ip_address = sections[1]
        except:
            print('Failed to retrieve assigned IP from LTE network.')

        return ip_address

    def send_at_cmd_pretty(self, cmd):
        print('>', cmd)
        response = self.lte.send_at_cmd(cmd)
        if response != None:
            lines = response.split('\r\n')
            for line in lines:
                if len(line.strip()) != 0:
                    print('>>', line)
        else:
            print('>> No response.')
        return response

    def connect(self):
        # NB-IoT
        if (self._network == NB_IOT):
            self.send_at_cmd_pretty('AT+CFUN=0')
            self.send_at_cmd_pretty('AT+CEMODE=0')
            self.send_at_cmd_pretty('AT+CEMODE?')
            self.send_at_cmd_pretty('AT!="clearscanconfig"')
            self.send_at_cmd_pretty('AT!="addscanfreq band=%s dl-earfcn=%s"' %
                                    (BAND, EARFCN))
            self.send_at_cmd_pretty('AT+CGDCONT=1,"IP","%s"' % APN)
            self.send_at_cmd_pretty('AT+COPS=1,2,"%s"' % COPS)
            self.send_at_cmd_pretty('AT+CFUN=1')

        # LTE-M (Cat M1)
        else:
            self.send_at_cmd_pretty('AT+CFUN=0')
            self.send_at_cmd_pretty('AT!="clearscanconfig"')
            self.send_at_cmd_pretty('AT!="addscanfreq band=%s dl-earfcn=%s"' %
                                    (BAND, EARFCN))
            self.send_at_cmd_pretty('AT+CGDCONT=1,"IP","%s"' % APN)
            self.send_at_cmd_pretty('AT+CFUN=1')
            self.send_at_cmd_pretty('AT+CSQ')

        # For a range scan:
        # AT!="addscanfreqrange band=20 dl-earfcn-min=3450 dl-earfcn-max=6352"

        print('Attaching...')
        seconds = 0
        while not self.lte.isattached() and seconds < attach_timeout:
            sleep(0.25)
            seconds += 0.25
        if self.lte.isattached():
            print('Attached!')
        else:
            print('Failed to attach to LTE (timeout)!')
            raise AttachTimeout
        self.lte.connect()

        print('Connecting...')
        seconds = 0
        while not self.lte.isconnected() and seconds < connect_timeout:
            sleep(0.25)
            seconds += 0.25
        if self.lte.isconnected():
            print('Connected!')
        else:
            print('Failed to connect to LTE (timeout)!')
            raise ConnectTimeout

        print('Retrieving assigned IP...')
        ip_address = self._get_assigned_ip()

        print("Device IP: {}".format(ip_address))
        print(ip_address)

        # Initialise the CoAP module
        Coap.init(ip_address)

        # Register the response handler for the requests that the module initiates as a CoAP Client
        Coap.register_response_handler(self.response_callback)

        # A CoAP server is needed if CoAP push is used (messages are pushed down from Managed IoT Cloud)
        # self.setup_coap_server()

    def setup_coap_server(self):
        # Add a resource with a default value and a plain text content format
        r = Coap.add_resource('',
                              media_type=Coap.MEDIATYPE_APP_JSON,
                              value='default_value')
        # Configure the possible operations on the resource
        r.callback(
            Coap.REQUEST_GET | Coap.REQUEST_POST | Coap.REQUEST_PUT
            | Coap.REQUEST_DELETE, True)

        # Get the UDP socket created for the CoAP module
        coap_server_socket = Coap.socket()
        # Create a new poll object
        p = uselect.poll()
        # Register the CoAP module's socket to the poll
        p.register(coap_server_socket,
                   uselect.POLLIN | uselect.POLLHUP | uselect.POLLERR)
        # Start a new thread which will handle the sockets of "p" poll
        _thread.start_new_thread(socket_thread, (p, coap_server_socket))

        print('CoAP server running!')

    # The callback that handles the responses generated from the requests sent to a CoAP Server
    def response_callback(self, code, id_param, type_param, token, payload):
        # The ID can be used to pair the requests with the responses
        print('ID: {}'.format(id_param))
        print('Code: {}'.format(code))
        print('Type: {}'.format(type_param))
        print('Token: {}'.format(token))
        print('Payload: {}'.format(payload))

    def disconnect(self):
        if self.lte.isconnected():
            self.lte.disconnect()

    def dettach(self):
        if self.lte.isattached():
            self.lte.dettach()

    def send(self, data):
        if not self.lte.isconnected():
            raise Exception('Not connected! Unable to send.')

        id = Coap.send_request(IOTGW_IP,
                               Coap.REQUEST_POST,
                               uri_port=IOTGW_PORT,
                               uri_path=IOTGW_ENDPOINT,
                               payload=data,
                               include_options=True)
        print('CoAP POST message ID: {}'.format(id))

    def pull(self, uri_path='/'):
        if not self.lte.isconnected():
            raise Exception('Not connected! Unable to pull.')

        id = Coap.send_request(IOTGW_IP,
                               Coap.REQUEST_GET,
                               uri_port=IOTGW_PORT,
                               uri_path=uri_path,
                               include_options=True)
        Coap.read()
        print('CoAP GET message ID: {}'.format(id))