Query status information from Huawei’s HiLink 3G/LTE modems

While Huawei provides status information for its HiLink modems via a web page, this is hardly useful when using the modem on a headless Linux server. I just published a small Python-based command-line tool on Github which displays some useful information about the modem’s status.

root@wopr~#: python ./hstatus.py
Huawei E3372 LTE Modem (IMEI: 121032526613216)
 Hardware version: CL1D3271AM Ver.A
 Software version: 22.286.53.01.161
 Web UI version: 16.100.05.00.03-Mod1.4
 Serial: L8FDW11512114431
 MAC address (modem): 00:0D:87:12:1C:1D
 Connection status: Connected
   Network type: UMTS (3G)
   Signal level: ▁▃▄▆█
   Roaming: Enabled
   Modem WAN IP address: 10.197.75.231
   Public IP address: 185.13.106.181
   DNS IP addresses: 212.113.0.5, 66.28.0.62
   Network operator: Swisscom
   Connected for: 03:15:15 (hh:mm:ss)
   Downloaded: 615.17 KB
   Uploaded: 258.69 KB
 Total downloaded: 14.69 MB
 Total uploaded: 1.34 MB
 Unread SMS: 1

The tool has been tested on a Huawei E3276 and a E3372 modem. For the newer E3372 modem I had to add some code to supply a RequestVerificationToken in the HTTP header.

Feel free to send a pull request on Github with your own tweaks!

The repository is available here: github.com/trick77/huawei-hilink-status

5 thoughts on “Query status information from Huawei’s HiLink 3G/LTE modems

  1. Any ideas?

    snb@snb:~$ python ./modem.py
    Traceback (most recent call last):
    File “./modem.py”, line 18, in
    from poster.encode import multipart_encode
    ImportError: No module named poster.encode

    Thank you! :)

  2. Thx for your script ..
    i have a 4g router and i need a python script to show me the mega bite that used
    from this api url “/api/monitoring/traffic-statistics”
    Hope you can help me

  3. Thanks for the great article and comment! I also have a question regarding to E3372h. I was trying to get the token via HTTP request, however, why do I always get 100002 from webpage display? If I use curl, I can only get response of ’empty reply from server’. Could any of you help with this issue? Thanks!

  4. Hey, thanks for the tool. But it did not work for the E3372h (the ones you get on ebay from Latvia or Russia) since they introduced cookies. Here is a fix for that, using the information from http://pastebin.com/6EzuSN7M. Unfortunately, SignalStrength is not transmitted, but /api/device/signal gives RSRQ, RSRP, RSSI, SINR and RSCP.

    Greetings
    Johannes

    $ diff -u0 hstatus.py hstatusE3372h.py
    — hstatus.py 2016-03-05 19:24:58.000000000 +0100
    +++ hstatusE3372h.py 2016-05-26 23:36:25.448407795 +0200
    @@ -32,0 +33 @@
    + sessionID = None
    @@ -34 +35 @@
    – r = requests.get(url=’http://’ + device_ip + ‘/api/webserver/token’, allow_redirects=False, timeout=(2.0,2.0))
    + r = requests.get(url=’http://’ + device_ip + ‘/api/webserver/SesTokInfo’, allow_redirects=False, timeout=(2.0,2.0))
    @@ -36 +37 @@
    – return token
    + return (token, sessionID)
    @@ -39,2 +40,5 @@
    – if ‘response’ in d and ‘token’ in d[‘response’]:
    – token = d[‘response’][‘token’]
    + if ‘response’ in d and ‘TokInfo’ in d[‘response’]:
    + token = d[‘response’][‘TokInfo’]
    + d = xmltodict.parse(r.text, xml_attribs=True)
    + if ‘response’ in d and ‘SesInfo’ in d[‘response’]:
    + sessionID = d[‘response’][‘SesInfo’]
    @@ -43 +47 @@
    – return token
    + return (token, sessionID)
    @@ -46 +50 @@
    -def call_api(device_ip, token, resource, xml_attribs=True):
    +def call_api(device_ip, token, sessionID, resource, xml_attribs=True):
    @@ -48 +52 @@
    – if token is not None:
    + if token is not None and sessionID is not None:
    @@ -49,0 +54 @@
    + headers = {‘Cookie’: sessionID}
    @@ -166,2 +171,2 @@
    -def print_traffic_statistics(device_ip, token, connection_status):
    – d = call_api(device_ip, token, ‘/api/monitoring/traffic-statistics’)
    +def print_traffic_statistics(device_ip, token, sessionID, connection_status):
    + d = call_api(device_ip, token, sessionID, ‘/api/monitoring/traffic-statistics’)
    @@ -181,2 +186,2 @@
    -def print_connection_status(device_ip, token):
    – d = call_api(device_ip, token, ‘/api/monitoring/status’)
    +def print_connection_status(device_ip, token, sessionID):
    + d = call_api(device_ip, token, sessionID, ‘/api/monitoring/status’)
    @@ -219,2 +224,2 @@
    -def print_device_info(device_ip, token):
    – d = call_api(device_ip, token, ‘/api/device/information’)
    +def print_device_info(device_ip, token, sessionID):
    + d = call_api(device_ip, token, sessionID, ‘/api/device/information’)
    @@ -242 +247 @@
    -def print_provider(device_ip, token, connection_status):
    +def print_provider(device_ip, token, sessionID, connection_status):
    @@ -244 +249 @@
    – d = call_api(device_ip, token, ‘/api/net/current-plmn’)
    + d = call_api(device_ip, token, sessionID, ‘/api/net/current-plmn’)
    @@ -249,2 +254,2 @@
    -def print_unread(device_ip, token):
    – d = call_api(device_ip, token, ‘/api/monitoring/check-notifications’)
    +def print_unread(device_ip, token, sessionID):
    + d = call_api(device_ip, token, sessionID, ‘/api/monitoring/check-notifications’)
    @@ -271,6 +276,6 @@
    -token = get_token(device_ip)
    -print_device_info(device_ip, token)
    -connection_status = print_connection_status(device_ip, token)
    -print_provider(device_ip, token, connection_status)
    -print_traffic_statistics(device_ip, token, connection_status)
    -print_unread(device_ip, token)
    +token, sessionID = get_token(device_ip)
    +print_device_info(device_ip, token, sessionID)
    +connection_status = print_connection_status(device_ip, token, sessionID)
    +print_provider(device_ip, token, sessionID, connection_status)
    +print_traffic_statistics(device_ip, token, sessionID, connection_status)
    +print_unread(device_ip, token, sessionID)

Comments are closed.