-
Notifications
You must be signed in to change notification settings - Fork 1
Hotspot API Server
- About
- Authentication
-
API Calls
GET /summary
GET /nettest
GET /troubleshoot
GET /stats
GET /activity
GET /peers/book
GET /peers/ping
GET /peers/connect
GET /peers/reset
GET /config
PATCH /config
GET /networks
POST /verify_password
POST /reset_password
POST /reboot
POST /factory_reset
POST /pair
POST /resync
POST /txn/add_gateway
POST /txn/assert_location
GET /fwupdate
PATCH /fwupdate
GET /logs/{name}
POST /logs/start
POST /logs/stop
{method} /sbapi/{path...}
The Hotspot API Server is a small webserver written in Python that exposes an API dedicated to remote controlling the Chameleon OS.
The server lives at /opt/hotspot-api-server.
Each request that requires authentication, must include an Authorization
header containing HTTP basic auth data:
Authorization: Basic BASE64(<username:password>)
There are two defined usernames:
-
admin
- works with user-configurable password and the default password isadmin
. -
dashboard
- for internal purposes, works with a password obtained as follows:SHA256(<hostname>:<wlan_mac>:<pub_key_hex>:<ecc_sn>)
All hex digits are lowercase.
Returns a summary of the current hotspot state. Does not require authentication. Response body looks like this:
{
"serial_number": "11068ec1",
"os_prefix": "cham",
"cpu_usage": 60, /* percent */
"mem_used": 150, /* MB */
"mem_total": 7192, /* MB */
"swap_used": 250, /* MB */
"swap_total": 2048, /* MB */
"storage_used": 58686, /* MB */
"storage_total": 3205, /* MB */
"temperature": 47, /* C */
"miner_height": 762332,
"miner_listen_addr": "/ip4/79.141.2.132/tcp/44158",
"miner_listen_ok": true,
"hotspot_name": "magnificent-midnight-wolf",
"concentrator_model": "sx1302",
"region": "EU868",
"fw_version": "2021.03.09.0",
"ecc_sn": "0123104236962a42ee",
"swarm_key_mode": false,
"address": "112axoWXqxrdT5Gd56iz7Mychkt9UU3EV3d9krTnkrLvodjJRYC2",
"pub_key": "d0cfaae2f6157e55978e8a715a5117cd7a23b766d4419b762402d8de4839e0f8212a0c5120deca00c616fb1125617e8d7f6e47adff213349efc949735809d788",
"eth_mac": "dc:a6:32:ad:aa:ff",
"wlan_mac": "dc:a6:32:ad:ab:00",
"bt_mac": "dc:a6:32:ad:ab:01",
"uptime": 86400, /* seconds */
"time": 1622664430 /* Unix timestamp, in seconds */,
"last_panic": { /* null if no panic within last 12h */
"service": "packetforwarder",
"message": "no region information",
"timestamp": 1634447900,
"uptime": 7436
},
"current_state": "lora_ready" /* powered_up|ip_ready|miner_syncing|lora_ready|updating_firmware|no_net|panic|rebooting */
}
If the pretty=true
query argument is passed, field names and their values are prepared for pretty printing.
If the quick=true
query argument is passed, only values for fields that are immediately available will be returned.
Performs a quick network connection analysis and returns the results. Does not require authentication. Response body looks like this:
{
"download_speed": 2505, /* kBytes/s */
"latency": 11, /* milliseconds */
"public_ip": "79.114.24.84",
"sb_api_reachable": true,
"helium_api_reachable": true
}
If the pretty=true
query argument is passed, field names and their values are prepared for pretty printing.
Performs self diagnosis and returns the results. Requires authentication.
Response body looks like this:
{
"hardware": {
"ethernet_present": true,
"wifi_present": true,
"bluetooth_present": true,
"concentrator_present": false,
"ecc_present": true,
"ecc_provisioned": true
},
"network": {
"download_speed": 3037,
"latency": 24,
"sb_api_reachable": true,
"helium_api_reachable": true
},
"miner": {
"ping": "true,
"region_ok": false,
"listening": true,
"reachable": true,
"direct": false
}
}
If the pretty=true
query argument is passed, field names and their values are prepared for pretty printing.
Returns some stats about the hotspot. Does not require authentication. Response body looks like this:
{
"blockchain_height": 862332,
"rewards_1d": 8.32, /* HNT */
"rewards_7d": 58.24, /* HNT */
"rewards_30d": 249.6, /* HNT */
"rewards_365d": 3036.8, /* HNT */
"oracle_price": 14.123456 /* USD */
}
Returns the hotspot's recent activity. Does not require authentication. Response body looks like this:
[
{
"block": 868235,
"time": 1622628182,
"amount": 1974,
"type": "rewards_v2"
},
...
]
Returns the miner's peers book. Does not require authentication. Response body looks like this:
[
{
"local": "/ip4/192.168.1.234/tcp/44158",
"remote": "/ip4/13.83.228.67/tcp/44159",
"p2p": "/p2p/1129rTuZbPA8fg1mc4TXbRfVa5QDb4UNj3P1o14N92WVMSVa46bU",
"address": "1129rTuZbPA8fg1mc4TXbRfVa5QDb4UNj3P1o14N92WVMSVa46bU",
"name": "big-grape-beaver"
},
...
]
Pings a peer and returns the round-trip time. Does not require authentication.
Query argument address
is required and represents the peer's address (e.g. 1129rTuZbPA8fg1mc4TXbRfVa5QDb4UNj3P1o14N92WVMSVa46bU
).
Response body looks like this:
{
"round_trip_time": 235 /* or null if ping failed */
}
Attempts to connect to a peer and returns the status. Does not require authentication.
Query argument address
is required and represents the peer's address (e.g. 1129rTuZbPA8fg1mc4TXbRfVa5QDb4UNj3P1o14N92WVMSVa46bU
).
Response body looks like this:
{
"success": true
}
Resets the peers book and restarts the miner. Requires authentication.
Response body is empty.
Returns the current configuration. Requires authentication. Response body looks like this:
{
"cpu_freq_max": 1500000, /* in kHz, null means default */
"led_brightness": 50, /* from 0 to 100 */
"led_ok_color": "green", /* red, green, blue, yellow, cyan, magenta, orange, white, off */
"network_type": "wifi", /* wifi, ethernet */
"network_ssid": "My Network 1", /* can be null */
"nat_external_ip": "72.012.123.234", /* can be null */
"nat_external_port": 44159, /* can be null */
"nat_internal_port": 44158, /* can be null */
"panic_on_relayed": false,
"panic_on_unreachable": false,
"force_sync_enabled": true,
"periodic_reset_peers": false,
"max_inbound_connections": 6,
"outbound_gossip_connections": 2,
"pf_antenna_gain": 2.3, /* dBi */
"pf_rssi_offset": -215.4, /* dBm */
"pf_tx_power": 14 /* dB */,
"remote_enabled": true,
"external_wifi_antenna": true,
"periodic_reboot": true
}
Updates the configuration. Requires authentication. Request body looks like this:
{
"cpu_freq_max": 1500000, /* in kHz, null means default */
"led_brightness": 50, /* from 0 to 100 */
"led_ok_color": "green", /* red, green, blue, yellow, cyan, magenta, orange, white, off */
"network_type": "wifi", /* wifi, ethernet */
"network_ssid": "My Network 1", /* ignored when network_type != wifi */
"network_psk": "deadbeef", /* ignored when network_type != wifi */
"nat_external_ip": "72.012.123.234", /* null disables */
"nat_external_port": 44159, /* null disables */
"nat_internal_port": 44158, /* null disables */
"panic_on_relayed": false,
"panic_on_unreachable": false,
"force_sync_enabled": true,
"periodic_reset_peers": false,
"max_inbound_connections": 6,
"outbound_gossip_connections": 2,
"pf_antenna_gain": 2.3, /* dBi */
"pf_rssi_offset": -215.4, /* dBm */
"pf_tx_power": 14, /* dB */
"password": "password1234",
"old_password": "password123",
"remote_enabled": true,
"external_wifi_antenna": true,
"periodic_reboot": true
}
All fields are optional. If a field is given as null
, it will be restored to its default value.
If password
is supplied, an additional old_password
field must be included as well and must contain the current password.
Returns available networks. Requires authentication. Response body looks like this:
{
"ethernet": true,
"wifi": [
"My Network 1",
"Neighbor's Network 2",
...
]
}
Verifies a given password. Request body looks like this:
{
"password": "password1234"
}
Returns 204
if password is valid and 200
(with a result message) otherwise.
Resets the device password.
If request body is empty (first part of the reset flow), the unit will generate a random code and will set LED strip colors using an associated pattern. The code is made up of the first lowercase letter of each of the available colors: [r]ed
, [g]reen
, [b]lue
, [c]yan
, [m]agenta
, [y]ellow
, [o]range
and [w]hite
.
To set a new password (second part of the reset flow), request body should look like:
{
"code": "rgbcmy",
"password": "my_new_password"
}
An invalid code will result in a 403
status code and a 2 seconds delay. A valid code will result in a 204
and the admin
password will be set to the supplied one.
The generated code expires in 60
seconds. The LED strip will return to normal at the end of the password reset flow.
Reboots the unit. Requires authentication.
Resets the unit to factory defaults. Requires authentication.
Enables temporary unit pairing mode. Requires authentication.
Forces a miner resynchronization. Requires authentication.
Pushes an add_gateway
transaction to the miner, returning the base64-encoded transaction. Requires authentication.
Request body looks like this:
{
"owner": "12ySLkgCNJHkvGg7G9jiq1PE7Dm691H8aSjex8xMR5Pwtic9XV6",
"payer": "14rb2UcfS9U89QmKswpZpjRCUVCVu1haSyqyGY486EvsYtvdJmR"
}
Response body looks like this:
CpYBCiEBA9fOirleO0dNfigK0zBn/PDeCLnXsx4fB5nDanX46tgSIQDQz6ri9hV+VZeOinFaURfNeiO3ZtRBm3YkAtjeSDng+CJGMEQCIF0WfBAH8Xt0CcQjUXJVf9Bb4ScOGWD63kCNLXo1+3n9AiAVTNjy395sKDsp6+zIDA7CRVHbE1Xl+KCStoC8IQ4SpzjAhD1AyN8C
Pushes an assert_location
transaction to the miner, returning the base64-encoded transaction. Requires authentication.
Request body looks like this:
{
"owner": "12ySLkgCNJHkvGg7G9jiq1PE7Dm691H8aSjex8xMR5Pwtic9XV6",
"payer": "14rb2UcfS9U89QmKswpZpjRCUVCVu1haSyqyGY486EvsYtvdJmR",
"location": "45.12345,21.23456",
"nonce": 1
}
nonce
is optional and defaults to 1
.
Response body looks like this:
CpYBCiEBA9fOirleO0dNfigK0zBn/PDeCLnXsx4fB5nDanX46tgSIQDQz6ri9hV+VZeOinFaURfNeiO3ZtRBm3YkAtjeSDng+CJGMEQCIF0WfBAH8Xt0CcQjUXJVf9Bb4ScOGWD63kCNLXo1+3n9AiAVTNjy395sKDsp6+zIDA7CRVHbE1Xl+KCStoC8IQ4SpzjAhD1AyN8C
Returns information about the currently running and latest firmware version. Requires authentication.
Response body looks like this:
{
"current": "2021.07.09.0",
"latest": "2021.07.09.0",
"beta": false,
"status": "idle"
}
Possible statuses are: idle
, downloading
, extracting
, flashing boot
, rebooting
.
Starts the firmware upgrade process. Requires authentication.
Returns the log indicated by name
. Requires authentication.
If the optional max_lines
query argument is supplied, the last indicated number of lines are returned (defaults to 1000
).
The following logs are defined:
-
miner
(/var/log/miner/console.log
) -
packet_forwarder
(/var/log/packet_forwarder.log
) -
kernel
(dmesg
) -
system
(/var/log/messages
)
Starts sending logs via MQTT. Logs will be sent until explicitly stopped or the unit is rebooted. Requires authentication.
See Logs Via MQTT.
Stops sending logs via MQTT. See Logs Via MQTT. Requires authentication.
Performs a SB API passthrough request, adding the required Authorization
header. Requires authentication.