Page 1 of 3

uPing - Ping library for MicroPython

Posted: Fri Sep 21, 2018 10:08 am
by shawwwn
MicroPython implementation of ICMP Ping.
Works exactly like linux's ping command.

https://gist.github.com/shawwwn/91cc897 ... 34c38195fb

Example:

Code: Select all

>>> import uping
>>> uping.ping('google.com')
PING google.com (64.233.185.138): 64 data bytes
84 bytes from 64.233.185.138: icmp_seq=1, ttl=40, time=71.636004 ms
84 bytes from 64.233.185.138: icmp_seq=2, ttl=40, time=70.365000 ms
84 bytes from 64.233.185.138: icmp_seq=3, ttl=40, time=71.599998 ms
84 bytes from 64.233.185.138: icmp_seq=4, ttl=40, time=82.879000 ms
4 packets transmitted, 4 packets received
(4, 4)
>>>

Usage:

Code: Select all

uping.ping(host, count=4, timeout=5000, interval=10, quiet=False, size=64)
  • @host: host's domain name or ip address to ping.
  • @count: how many packets to send
  • @timeout: stop if not receiving anything within a certain time period (milliseconds)
  • @interval: time between sending each packet
  • @quiet: suppress print messages
  • @size: ICMP packet size (bytes), must > 16
  • @return: tuple(number of packet transmitted, number of packets received)

Re: uPing - Ping library for MicroPython

Posted: Sat Sep 22, 2018 4:34 am
by pythoncoder
Very useful!

A couple of points about the code. PEP 8 suggests indenting by 4 spaces. Tabs carry hazards (notably the case where an invisible space creeps in and causes indentation errors) so are generally not recommended.

On the plus side I've been writing Python for donkey's years and it never occurred to me to write

Code: Select all

not quiet and print('something')
Neat!

Re: uPing - Ping library for MicroPython

Posted: Sat Sep 22, 2018 7:57 am
by shawwwn
Just changed. Thanks!

Re: uPing - Ping library for MicroPython

Posted: Sun Nov 18, 2018 11:02 pm
by KJM
I can't get this to run on a pycom gpy. File "/flash/lib/uping.py", line 46, in ping AttributeError: 'function' object has no attribute 'randint' which I fudged with h.id=100 as a workaround

then File "/flash/lib/uping.py", line 51, in ping AttributeError: 'module' object has no attribute 'SOCK_RAW' which I'm not smart enough to fix.

I'm grief stricken! I could so use a pinger on this platform. Thoughts anyone on a fix?

Re: uPing - Ping library for MicroPython

Posted: Mon Nov 19, 2018 6:41 am
by pythoncoder
If you're running the Pycom fork I can only think that this fork lacks some useful features. You may be able to work round the randint issue with uos.urandom(4) with suitable conversion to an integer. FWIW the value of usocket.SOCK_RAW is 3 but if the underlying implementation is absent from their fork I'm afraid your only option is to talk nicely to Pycom.

More and more of the issues in this forum are down to variations between forks/ports :(

Re: uPing - Ping library for MicroPython

Posted: Mon Nov 19, 2018 4:49 pm
by HermannSW
The randint issue only occurs on my ESP8266, not on the ESP32.
This little diff fixes it:

Code: Select all

$ diff uping.py.orig uping.py
45c45,46
<     h.id = urandom.randint(0, 65535)
---
>     urandom.seed(utime.ticks_us())
>     h.id = urandom.getrandbits(16)
$ 
But with that change both ESP modules run into index error:

Code: Select all

>>> uping.ping("woogle.de")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "uping.py", line 53, in ping
IndexError: list index out of range
>>> 
Last line here is it:

Code: Select all

$ head -53 uping.py | tail -9
    urandom.seed(utime.ticks_us())
    h.id = urandom.getrandbits(16)
    h.seq = 1

    # init socket
    sock = usocket.socket(usocket.AF_INET, usocket.SOCK_RAW, 1)
    sock.setblocking(0)
    sock.settimeout(timeout/1000)
    addr = usocket.getaddrinfo(host, 1)[0][-1][0] # ip address
$ 
P.S:
I inserted "print(usocket.getaddrinfo(host, 1))", empty list explains error

Code: Select all

>>> uping.ping("google.de")
[]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "uping.py", line 54, in ping
IndexError: list index out of range
>>> ### closed ###
$ 
P.P.S:
My fault, modules were AP only with no internet connection.
Now I made station active as well:

Code: Select all

>>> usocket.getaddrinfo("google.de",1)[0][-1][0]
'172.217.20.131'
>>> 

But now uping.py errors out on line 50 (socket init, ESP8266 module):

Code: Select all

>>> uping.ping("google.de")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "uping.py", line 50, in ping
OSError: [Errno 22] EINVAL
>>> 
What is wrong with this simple statement on 1.9.4 ESP8266 MicroPython?

Code: Select all

>>> sock = usocket.socket(usocket.AF_INET, usocket.SOCK_RAW, 1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 22] EINVAL
>>> 

Re: uPing - Ping library for MicroPython

Posted: Tue Jan 08, 2019 8:35 pm
by johncblacker
Running into a problem trying to run uping.ping('192.168.0.2')
I get:

>>> uping.ping('192.168.0.2')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "uping.py", line 49, in ping
OSError: [Errno 22] Invalid argument

Tried again:

>>> import usocket
>>> sock = usocket.socket(usocket.AF_INET, usocket.SOCK_RAW, 1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
OSError: [Errno 22] Invalid argument

Doesn't like that socket create statment...

Re: uPing - Ping library for MicroPython

Posted: Tue Jan 08, 2019 8:53 pm
by johncblacker
experimenting a little and found that it definitely doesn't like "usocket.SOCK_RAW"; however, I can print usocket.SOCK_RAW and get an output value of 3...

Re: uPing - Ping library for MicroPython

Posted: Sat Jan 19, 2019 2:15 pm
by pmp-p
@johncblacker: more likely it's the 1 it does not like, as IPPROTO_ICMP is probably not handled on various ports.

Re: uPing - Ping library for MicroPython

Posted: Thu May 09, 2019 6:45 am
by nedoskiv
Works good for me, on esp32 using latest build

I can just suggest one fix to be maded, when you trying to ping hostname that cannot be resolved, it fails:

Code: Select all

>>> uping.ping("diar.bg")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "uping.py", line 52, in ping
IndexError: list index out of range