Ecowitt GW3000

Table of Contents

1. OTA Protocol

Fortunately the OTA protocol API works via plaintext HTTP making interception trivial.

1.1. Update version check (requested at gateway startup)

Request:

GET /api/ota/v1/version/info?id=04%3A83%3A08%3A78%3A53%3AC3&model=GW3000A&time=1761864689&user=1&version=V1.0.6&sign=EF98ED368F668F3D6C2223787F8BA8B5 HTTP/1.0
Accept: application/json, */*
Host: ota.ecowitt.net
User-Agent: GW3000A FreeRTOS
Connection: Close

Parameters:

Name Description Values seen Notes
id Device MAC address    
model Device model GW3000A  
time current UNIX timestamp    
user unknown 1  
version Current FW version V1.0.6  
sign Request signature HMAC    

Response:

HTTP/1.1 200 OK
Connection: close
Date: Thu, 30 Oct 2025 22:51:30 GMT
Ecowitt-ECS: update3
Via: ens-cache4.de5[359,0]
Timing-Allow-Origin: *
EagleId: a3b55c9817618646897573258e

{"code":0,"msg":"Success","time":"1761864689","data":{"id":786,"name":"V1.1.4","content":"-Fixed an issue where custom server settings could not be saved,","attach1file":"https:\/\/oss.ecowitt.net\/ota\/20251029\/0d62de1a721abed911fb1238d2a3e11c.bin","attach2file":"","queryintval":86400}}
</pre>

The sign parameter in the request is used for replay protection. For example, when an attempt is made to use curl to send the same request the server responds with an error:

$ curl -i 'http://ota.ecowitt.net/api/ota/v1/version/info?id=04%3A83%3A08%3A78%3A53%3AC3&model=GW3000A&time=1761864689&user=1&version=V1.0.6&sign=EF98ED368F668F3D6C2223787F8BA8B5'
HTTP/1.1 200 OK
Transfer-Encoding: chunked
Connection: keep-alive
Date: Thu, 11 Dec 2025 22:33:50 GMT
Ecowitt-ECS: update5
Via: ens-cache3.de7[230,0]
Timing-Allow-Origin: *
EagleId: a3b5839717654924300652332e

{"code":40012,"msg":"invalid time","time":"1765492430","data":[]}

Links

Github  Sourcehut  Hackaday

  Fediring