-
Notifications
You must be signed in to change notification settings - Fork 65
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
API Documentation #90
Comments
Please refer to these files for now. A more detailed document will be provided later. |
I took some time reverse-engineering API calls and crafting a bash-curl-way of interacting with the API. Pretty surely also easy to adapt in other programming languages. Note: Some API paths seems to mismatch between "reality" (NanoKVM with latest 2.0.9 as of today) and today's available code on GitHub: For example, It does not include all available API calls (such as I thought it might be useful for others, so here we go: AUTHNote:
# Login to NanoKVM and receive token
# Adjust variables below
HOSTNAME="192.168.0.1"
USERNAME="admin"
PASSWORD="admin"
# Usually hardcoded and no need to change
PWSECKEY="nanokvm-sipeed-2024"
# Encrypt password via AES-256-CBC before sending to API
PASSENC=$(echo -n "$PASSWORD" | openssl enc -aes-256-cbc -base64 -salt -md md5 -pass pass:$PWSECKEY 2>/dev/null)
# Build JSON string for login, urlencode values as backend expects
AUTHJSON=$(jq -crnM --arg u "$USERNAME" --arg p "$PASSENC" '{"username":$u|@uri,"password":$p|@uri}')
# Send request via curl to NanoKVM
REQUEST=$(curl -s -X POST http://$HOSTNAME/api/auth/login -H 'Content-Type: application/json' --data-raw "$AUTHJSON")
# Parse token via jq from above request
TOKEN=$(echo $REQUEST | jq -r .data.token)
# Set cookie variable to be used by curl
COOKIE="nano-kvm-token=$TOKEN" After this, below commands can be used. GENERAL (named "VM" in code)Get device info# curl -s -b $COOKIE http://$HOSTNAME/api/vm/info
{"code":0,"msg":"success","data":{"ip":"<IP>","mdns":"kvm-<LAST 4 DIGITS OF MAC>.local","image":"2024-08-17-18-13-713161.img","firmware":"2.0.9","deviceKey":"<ID>"}} Get GPIO LED state# curl -s -b $COOKIE http://$HOSTNAME/api/vm/gpio/led
{"code":0,"msg":"success","data":{"pwr":true,"hdd":false}} Trigger power switchNote:
# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/vm/gpio -H "Content-Type: application/json" -d '{"type":"power","duration":800}'
{"code":0,"msg":"success","data":null} STREAMGet current image and save to image.jpgNote: This uses ffmpeg to convert the mjpeg stream to a image with name image.jpg. # curl -s -N -b $COOKIE http://$HOSTNAME/api/stream/mjpeg -o - | ffmpeg -y -i - -frames:v 1 -vcodec mjpeg image.jpg If you want to do something fancy:
Record the stream to x264-encoded fileNote:
# curl -s -N -b $COOKIE http://$HOSTNAME/api/stream/mjpeg -o - | ffmpeg -y -use_wallclock_as_timestamps 1 -f mjpeg -i - -an -t 30 -c:v libx264 -f mp4 output.mp4 Type text automatically# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/hid/paste -H "Content-Type: application/json" -d '{"content": "this is a test"}'
{"code":0,"msg":"success","data":null}
# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/hid/paste -H "Content-Type: application/json" -d '{"content": "vyos\nvyos\n"}'
{"code":0,"msg":"success","data":null} Reset HID# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/hid/reset
{"code":0,"msg":"success","data":null} Get current frame detection stateNote: Not specifying # curl -s -b $COOKIE http://$HOSTNAME/api/stream/mjpeg/detect
{"code":0,"msg":"success","data":{"enabled":false}} Toggle frame detection# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/stream/mjpeg/detect
{"code":0,"msg":"success","data":{"enabled":true}}
# curl -s -X POST -b $COOKIE http://$HOSTNAME/api/stream/mjpeg/detect
{"code":0,"msg":"success","data":{"enabled":false}} STORAGEGet available images# curl -s -b $COOKIE http://$HOSTNAME/api/storage/images | jq -r
{
"code": 0,
"msg": "success",
"data": {
"files": [
"/data/ubuntu-24.04-desktop-amd64.iso"
]
}
} Change mounted imageNote: Path is absolute path to ISO file # curl -s -X POST -b $COOKIE http://$HOSTNAME/api/storage/image/mount -H "Content-Type: application/json" -d '{"file": "/data/ubuntu-24.04-desktop-amd64.iso"}'
{"code":0,"msg":"success","data":null} Get currently mounted image# curl -s -b $COOKIE http://$HOSTNAME/api/storage/images/mounted
{"code":0,"msg":"success","data":{"file":"/data/ubuntu-24.04-desktop-amd64.iso"}} VIRTUAL DEVICESGet current virtual devices state# curl -s -b $COOKIE http://$HOSTNAME/api/vm/device/virtual
{"code":0,"msg":"success","data":{"network":true,"disk":true}} Set/Toggle state of virtual deviceNote: Use
|
Nice! Thanks for your work and sharing this! |
kudos for the tesseract example, more people should figure out stuff like this and do it! |
@wj-xiao Hi! is there a non-authenticated local API endpoint for scripts running on the device? Would be easier for sharing, unless someone says it's bad for security and I just didn't notice a problem there. |
@FlorianHeigl By default, APIs require authentication. However, you can disable authentication by modifying the configuration file. Please note that this will make the device insecure. |
Is there an API that will allow me to click? Also press keys |
Could not find a specific API call last time I checked, so I assume it's sent through the established websocket connection. Possible for sure, but way more tricky. |
I see the code has now been shared so I may go through and do this myself, but it would be nice to have documentation for the HTTP API used.
I note so far that there is a request to
/api/auth/login
to perform the login, but the password is not sent as plaintext. Subsequent requests to the API seem to use a token that is set as a cookie.Other endpoints include:
GET
/api/vm/gpio/led
which returns the LED state:{"code":0,"msg":"success","data":{"pwr":false,"hdd":false}}
GET
/api/storage/images/mounted
{"code":0,"msg":"success","data":{"file":""}}
POST
/api/vm/gpio
with data like:{"type":"power","duration":800}
will press the power button for 800ms.Returns:
{"code":0,"msg":"success","data":null}
It would be great to have docs on how to use this to integrate in to other systems (I would like to add an integration in to Home Assistant for example) to control multiple machines.
The text was updated successfully, but these errors were encountered: