NerdMiner_v2 icon indicating copy to clipboard operation
NerdMiner_v2 copied to clipboard

Configuration with CURL?

Open PSLLSP opened this issue 2 years ago • 2 comments
trafficstars

I connected to http://192.168.4.1 at NerdMinerAP WiFi and I see that I can use some magic API, like http://192.168.4.1/wifisave or http://192.168.4.1/param but it is not documented; some parameters has to be passed. I assume this can be used to configure NerdMiner with curl and other CLI tools. Could be this documented?


Other issue is that configuration of NerdMiner is not machine friendly. I can configure it with curl but it is not easy to get information about device. For example curl http://192.168.4.1/info will read information about NerdMiner, like MAC address, serial number (chip ID), WiFi Manager version, build date, etc, but it is a HTML designed for humans, HTML with stylesheet information, etc; such page is not easily parsed. It would be nice to have info page, that will return structured information, like JSON file. I assume this configuration part belongs to WiFi Manager; it surprise me, that there is no machine friendly interface; or maybe it is hidden...

Blind configuration of NerdMiner device is "easy" (just POST parameters with curl), reading information about NerdMiner device is "difficult"...

In theory, HTML could be valid XML file but in most cases it is not and the same applies to NerdMiner pages...

$ curl -s http://192.168.4.1/info > NerdMiner-info.html
$ xmlstarlet val NerdMiner-info.html 
NerdMiner-info.html - invalid

Again, in the case that HTML is valid XML, information can be extracted easily with code...

PSLLSP avatar Nov 07 '23 11:11 PSLLSP

My try on CURL configuration, bash script runs on Linux. Configuration is read from JSON file, compatible with JSON file for configuration from SD card. jq utility has to be installed; sudo apt-get install -y jq on Debian/Ubuntu/Mint/Raspbian/Armbian/...

DEMO:

$ sh NerdMinerAP-setup-json.sh config-demo-ckpool.json
Using config file config-demo-ckpool.json
Final JSON config:
{
  "SSID": "NerdAP",
  "WifiPW": "wifiSECRET",
  "PoolUrl": "solo.ckpool.org",
  "PoolPort": 3333,
  "BtcWallet": "bc1q28kkr5hk4gnqe3evma6runjrd2pvqyp8fpwfzu.DEMO",
  "PoolPassword": "x",
  "Timezone": 0,
  "SaveStats": false
}
INFO: Connect this computer to WiFi NerdMinerAP
INFO: Waiting for 192.168.4.1...
INFO: Waiting for 192.168.4.1...
INFO: Waiting for 192.168.4.1...
INFO: Configuring NerdMiner...
EXIT CODE: 0

Parameters could be hardcoded to the script or rewritten with environment variables; this can be used for scripting. Example, change WiFi password:

$ WIFIPASS="superSECRET" sh NerdMinerAP-setup-json.sh config-demo-ckpool.json 
Using config file config-demo-ckpool.json
Final JSON config:
{
  "SSID": "NerdAP",
  "WifiPW": "superSECRET",
  "PoolUrl": "solo.ckpool.org",
  "PoolPort": 3333,
  "BtcWallet": "bc1q28kkr5hk4gnqe3evma6runjrd2pvqyp8fpwfzu.DEMO",
  "PoolPassword": "x",
  "Timezone": 0,
  "SaveStats": false
}
INFO: Connect this computer to WiFi NerdMinerAP
INFO: Waiting for 192.168.4.1...
...

This is the script for curl configuration:

$ cat NerdMinerAP-setup-json.sh
#!/bin/sh

# uplaod configuration to NerdMiner device over WiFi.
# NerdMiner device has to be in WiFi configuration mode and this computer has to be connected to WiFi NerdMinerAP

# DEFAULT values
XTIMEZONE="0"
NERDMINERAP="NerdMinerAP"
NERDMINERIP="192.168.4.1" # NerdMiner in configuration mode

CONFIG="$1"

if [ -z "$CONFIG" ]; then
    echo "WARNING: Missing an argument, trying with file 'config.json'"
    CONFIG="config.json"
else
    echo "Using config file $CONFIG"
    shift
fi

if ! $(type jq > /dev/null 2>&1); then
  echo "ERROR: command 'jq' is not in the PATH"
  exit 1
fi

jq 'length' "$CONFIG" > /dev/null
if [ $? != 0 ]; then
    echo "ERROR: $CONFIG is not valid JSON file"
    exit 3
fi

[ -z "$WIFISSID" ] && WIFISSID="$(jq -r '.SSID' $CONFIG)"
[ -z "$WIFIPASS" ] && WIFIPASS="$(jq -r '.WifiPW' $CONFIG)"

[ -z "$POOLHOST" ] && POOLHOST="$(jq -r '.PoolUrl' $CONFIG)"
[ -z "$POOLPORT" ] && POOLPORT="$(jq -r '.PoolPort' $CONFIG)"

[ -z "$POOLUSER" ] && POOLUSER="$(jq -r '.BtcWallet' $CONFIG)"  # In most cases WALLET.WORKER or just WALLET
[ -z "$POOLPASS" ] && POOLPASS="$(jq -r '.PoolPassword' $CONFIG)"

[ -z "$TIMEZONE" ] && TIMEZONE="$(jq -r '.Timezone' $CONFIG)"

[ -z "$SAVESTATS" ] && SAVESTATS="$(jq -r '.SaveStats' $CONFIG)"

[ -z "$WIFISSID" -o "$WIFISSID" = "null" ] && echo "ERROR: SSID is not defined" && exit 2
[ -z "$WIFIPASS" -o "$WIFIPASS" = "null" ] && echo "ERROR: WifiPW is not defined" && exit 2

[ -z "$POOLHOST" -o "$POOLHOST" = "null" ] && echo "ERROR: PoolUrl is not defined" && exit 2
[ -z "$POOLPORT" -o "$POOLPORT" = "null" ] && echo "ERROR: PoolPort is not defined" && exit 2

[ -z "$POOLUSER" -o "$POOLUSER" = "null" ] && echo "ERROR: BtcWallet is not defined" && exit 2
[ -z "$POOLPASS" -o "$POOLPASS" = "null" ] && POOLPASS="x"

[ -n "$POOLWORKER" ] && POOLUSER="$POOLUSER.$POOLWORKER"  # add WORKER to POOLUSER

[ -z "$TIMEZONE" -o "$TIMEZONE" = "null" ] && TIMEZONE="$XTIMEZONE" && echo "WARNING: Timezone is not defined, using $XTIMEZONE"

[ "$SAVESTATS" != "true" ] && SAVESTATS="false"

# NerdMiner configuration endpoint
NMURL="http://$NERDMINERIP/wifisave"

# Fill FORM fields with values
NMCONFIG="s=${WIFISSID}&p=${WIFIPASS}&Poolurl=${POOLHOST}&Poolport=${POOLPORT}&btcAddress=${POOLUSER}&Poolpassword=${POOLPASS}&TimeZone=${TIMEZONE}"
[ "$SAVESTATS" = "true" ] && NMCONFIG="${NMCONFIG}&SaveStatsToNVS="

HEADERS=""
HEADERS="$HEADERS -H 'Content-Type: application/x-www-form-urlencoded'"
HEADERS="$HEADERS -H 'Accept: text/html'"
#HEADERS="$HEADERS -H 'Origin: http://$NERDMINERIP'"
#HEADERS="$HEADERS -H 'Referer: http://$NERDMINERIP/wifi?'"
#HEADERS="$HEADERS -H 'Cache-Control: max-age=0'"
#HEADERS="$HEADERS -H 'Connection: close'"

# print config JSON
if :; then
cat <<+++
Final JSON config:
{
  "SSID": "$WIFISSID",
  "WifiPW": "$WIFIPASS",
  "PoolUrl": "$POOLHOST",
  "PoolPort": $POOLPORT,
  "PoolPassword": "$POOLPASS",
  "BtcWallet": "$POOLUSER",
  "Timezone": $TIMEZONE,
  "SaveStats": $SAVESTATS
}
+++
fi

echo "INFO: Connect this computer to WiFi $NERDMINERAP"
[ -f connect-wifiap.sh ]  && connect-wifiap.sh "$NERDMINERAP" # call a script to connect to configuration WiFi
while :; do
   echo "INFO: Waiting for $NERDMINERIP..."
   ping -c1 -q "$NERDMINERIP" > /dev/null
   [ $? = 0 ] && break
   sleep 5
done
#sleep 10 # optional delay

#echo "DEBUG: $NMCONFIG"
echo "INFO: Configuring NerdMiner..."
curl -s -X POST "$HEADERS" --data-raw "$NMCONFIG" "$@" "$NMURL" > /dev/null
echo "EXIT CODE: $?"

And this is the JSON file used in these examples:

$ cat config-demo-ckpool.json 
{
  "SSID": "NerdAP",
  "WifiPW": "wifiSECRET",
  "PoolUrl": "solo.ckpool.org",
  "PoolPort": 3333,
  "BtcWallet": "bc1q28kkr5hk4gnqe3evma6runjrd2pvqyp8fpwfzu.DEMO",
  "Timezone": 0,
  "SaveStats": false
}

One more note. An easy way to modify JSON with jq. Example, change WiFi parameters, merge two JSON files; note parameter -s to jq, it is important:

$ cat config-myWiFi.json 
{
  "SSID": "myAP", "WifiPW": "mySECRET"
}

$ jq -s 'add' config-demo-ckpool.json config-myWiFi.json > config-merged.json
$ cat config-merged.json
{
  "SSID": "myAP",
  "WifiPW": "mySECRET",
  "PoolUrl": "solo.ckpool.org",
  "PoolPort": 3333,
  "BtcWallet": "bc1q28kkr5hk4gnqe3evma6runjrd2pvqyp8fpwfzu.DEMO",
  "Timezone": 0,
  "SaveStats": false
}

Several JSON files could be merged:

$ cat config-pool-public.json
{
  "PoolUrl": "public-pool.io",
  "PoolPort": 21496
}

$ jq -s 'add' config-demo-ckpool.json config-myWiFi.json config-pool-public.json
{
  "SSID": "myAP",
  "WifiPW": "mySECRET",
  "PoolUrl": "public-pool.io",
  "PoolPort": 21496,
  "BtcWallet": "bc1q28kkr5hk4gnqe3evma6runjrd2pvqyp8fpwfzu.DEMO",
  "Timezone": 0,
  "SaveStats": false
}

PSLLSP avatar Nov 12 '23 11:11 PSLLSP

Waiting for AP NerdMinerAP is a boring task, this is a script for Debian/Ubuntu/Mint that waits for NerdMinerAP and connects to it; after that provisioning script with "CURL" can be started... It uses Network Managerutility nmcli:

$ cat connect-wifiap.sh
#!/bin/sh
# Search for BSSID and connect to it
# BTW, password for NerdMinerAP is MineYourCoins

BSSID="NerdMinerAP"
[ -n "$1" ] && BSSID="$1"

nmcli radio wifi on
while sleep 2; do
  echo "INFO: Waiting for WiFi $BSSID..."
  nmcli --wait 20 dev wifi connect "$BSSID" 2>/dev/null && break
  nmcli device wifi rescan ssid "$BSSID" 2>/dev/null
done
echo "INFO: Connected to WiFi $BSSID"

nmcli connection show --active
nmcli dev wifi show  # show QR code!! password is shown...

PSLLSP avatar Nov 29 '23 22:11 PSLLSP