Micropython vs CPython and sockets

Discussion about programs, libraries and tools that work with MicroPython. Mostly these are provided by a third party.
Target audience: All users and developers of MicroPython.
Post Reply
hybotics
Posts: 33
Joined: Tue Apr 03, 2018 2:58 am
Contact:

Micropython vs CPython and sockets

Post by hybotics » Tue Jul 06, 2021 1:09 am

Hi,

I found some Python code that gets the current time from NTP servers. It works great with CPython.

I want to convert this to work with Micropython, but there seem to be some issues with the socket library that I can not do anything with. The code is included below and the error message I am getting is at the end. It seems like this should work but Micropython seems to be missing some functionality or there is an alternate way to do this that I am not aware of. I am very new to working with this kind of code.

Code: Select all

from socket import AF_INET, SOCK_DGRAM
import socket
import struct
import time


def getNTPTimeMP(host = "pool.ntp.org"):
  port = 123
  buf = 1024
  address = (host, port)
  msg = '\x1b' + 47 * '\0'

  # Reference time (in seconds since 1900-01-01 00:00:00)
  TIME1970 = 2208988800 # 1970-01-01 00:00:00

  # Connect to server
  client = socket.socket(AF_INET, SOCK_DGRAM)
  client.sendto(msg.encode('utf-8'), address)
  msg, address = client.recvfrom( buf )

  t = struct.unpack( "!12I", msg )[10]
  t -= TIME1970

  t1 = time.ctime(t)
  time_string = t1.replace("  "," ")

  #print("t1 = '{0}',\nt2 = '{1}',\ntime_string = {2}".format(t1, t2, time_string))
  return time_string

t = getNTPTimeMP()
z = t.split(" ")
print(t)
print(z)

# MPY: soft reboot
# Traceback (most recent call last):
#   File "main.py", line 31, in <module>
#   File "main.py", line 19, in getNTPTimeMP
# ValueError: invalid arguments
# MicroPython v1.16 on 2021-06-23; TinyPICO with ESP32-PICO-D4
Is there an alternate way to make this work or does Micropython need more functionality is the usocket library?

8-Dale

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Micropython vs CPython and sockets

Post by davef » Tue Jul 06, 2021 1:34 am

Can't tell what is wrong with what you are doing so will just copy my getUTC.py script. Which hardware device are you trying to get this to work on. What follows works on a ESP32 or ESP8266.

Micropython uses ntptime.py

Code: Select all

#  utime.mktime appears to be able to handle a full 9-tuple

import ntptime
import utime
import machine


def getntptime():
    now = 0
#    ntptime.host = 'nz.pool.ntp.org'
    count = 0

    while (count < 5):
        count += 1

        print('.', end = '')

        try:
            now = ntptime.time()

            if (now > 660000000): #  just tests to see if you have something reasonable 
                count = 0
                break
        except OSError as err:
            try:
                with open('errors.txt', 'a') as outfile:
                    outfile.write(str(err) + '\n')
            except OSError:
                pass

        utime.sleep(1)

    if (count == 5):
        count = 0
        machine.reset()

    print(' got epoch')
    utime.sleep(1)


 #  only correct for 2021 in NZ
    HHApril = utime.mktime((2021,4,4,3,0,0,0,0,0)) #  time of April change to NZST
    HHSept = utime.mktime((2021,9,26,2,0,0,0,0,0)) #  time of Sept change to NZDT

    if now < HHApril:               # we are before the first Sunday of April
        ntptime.NTP_DELTA = 3155673600 - (13 * 3600) #  NZDT: UTC-13H
    elif now < HHSept:              # we are before the last Sunday of Sept
        ntptime.NTP_DELTA = 3155673600 - (12 * 3600) #  NZST: UTC-12H
    else:                           # we are after the last Sunday of Sept
        ntptime.NTP_DELTA = 3155673600 - (13 * 3600) #  NZDT: UTC-13H


    count = 0

    while (count < 5):
        count += 1

        print('.', end = '')

        try:
            my_time = ntptime.settime() # set the rtc datetime from the remote server

            if (str(my_time) == 'None'):
                count = 0
                break
        except OSError as err:
            try:
                with open('errors.txt', 'a') as outfile:
                    outfile.write(str(err) + '\n')
            except OSError:
                pass
        except Exception:
            try:
                with open('errors.txt', 'a') as outfile:
                    outfile.write('settime failed' + '\n')
            except OSError:
                pass

        utime.sleep(1)

    if (count == 5):
        count = 0
        machine.reset()

    print(' time has been set')
    utime.sleep(1)

hybotics
Posts: 33
Joined: Tue Apr 03, 2018 2:58 am
Contact:

Re: Micropython vs CPython and sockets

Post by hybotics » Tue Jul 06, 2021 2:52 pm

davef wrote:
Tue Jul 06, 2021 1:34 am
Can't tell what is wrong with what you are doing so will just copy my getUTC.py script. Which hardware device are you trying to get this to work on. What follows works on a ESP32 or ESP8266.
I am using Unexpected Maker's tinyPicos.
davef wrote:
Tue Jul 06, 2021 1:34 am
Micropython uses ntptime.py
Ah! OK, got it! I am just getting back into Micropython as there are just some things I can not do, or at least not do easily with other firmware.

Thank you!

8-Dale

hybotics
Posts: 33
Joined: Tue Apr 03, 2018 2:58 am
Contact:

Re: Micropython vs CPython and sockets

Post by hybotics » Tue Jul 06, 2021 10:59 pm

davef wrote:
Tue Jul 06, 2021 1:34 am
Micropython uses ntptime.py
I tried running your code and all it seems to do is:

Code: Select all

MPY: soft reboot
.....ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:5880
load:0x40078000,len:13840
load:0x40080400,len:4952
entry 0x400806c4
.....ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 188777542, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:5880
load:0x40078000,len:13840
load:0x40080400,len:4952
entry 0x400806c4
Over and over.

MicroPython v1.16 on 2021-06-23; TinyPICO with ESP32-PICO-D4

8-Dale

njepsen
Posts: 11
Joined: Tue Jun 22, 2021 4:08 am
Location: New Zealand.

Re: Micropython vs CPython and sockets

Post by njepsen » Wed Jul 21, 2021 6:05 am

@Davef,
I notice you are in chCh. I am in palmy nth. Also having lots of issues with uPython and sockets trying to get reliable TCP POSTs to a server. lte seems a bit flakey, and Ive managed to get attach & connect working well with AT commands but from time to time (not using lte) , if connectivity is lost the only recovery is a power cycle, which is not a solution with units in the field.
Using lte, there are times when a attach takes a LONG time. I have about 100 units out in the field using an Atmega device and these connect in a few seconds or less with AT commands to a Telit modem so i'm not happy with the ESP32 built in modem or i'm doing something wrong.
I'll post some code if your'e happy to comment.
neil

davef
Posts: 811
Joined: Thu Apr 30, 2020 1:03 am
Location: Christchurch, NZ

Re: Micropython vs CPython and sockets

Post by davef » Wed Jul 21, 2021 6:58 am

hybotics,

For some reason I never saw your posting. Were any errors messages saved on flash?

njepsen,

Sure post the code here. Getting consistent WiFi on the ESP32 has been a long rocky road. Having got my system running on a ESP32_SPIRAM with very little drama I have gone back to the ESP32 and seem to be able to get some consistent performance.

I'll post my versions of ntptime.py, getUTC.py and wifi_functions.py if you want to see if there is something in them that might help. I am a beginner as far as socket programming goes.

Post Reply