HDZGOGGLE Web UI and API A Web UI and Web API that leverages SumolX's work on services for the HDZero goggles.
These services allow applications to access and update the SD card and goggle settings. Goggle settings are saved in file and loaded on reboot. The BusyBox Web Server only supports Get and Post methods. Other methods, when needed are represented with the URI. Server errors are returned as primary in the reponse header. API errors are returned as misscellaneous in the header. Errors and messages are returned as plain text in the body of the response. A login is required to use sevices but the web server currently does not support HTTPS. Any one with access to your network could gain access to your goggle settings. Don't give anyone access to your goggle network.
The first section of the settings file must not be changed. The goggle will reset the entire file to defaults if it is missing.
Get a line or lines from a section by name, or get all sections.
/cgi-bin/setting?section=birthday&line=year
{"section":"birthday","setting_list":[{"key": "year", "value": "1980", "line": "57"}]}
/cgi-bin/setting?section=birthday
{"section":"birthday","setting_list":[{"key": "year", "value": "1980", "line": "57"},{"key": "month", "value": "10", "line": "58"},{"key": "day", "value": "3", "line": "59"}]}
/cgi-bin/setting
{"sections":[{"section":"settings","settings":[{"key":"file_version", "value":"1", "ln": "2"}],"osd":[{"key":"is_visible", "value":"false", "ln": "4"},{"key":"embpipedded_mode", "value":"0", "ln": "5"},{"key":"orbit", "value":"0", "ln": "6"},{"key":"startup_visibility", "value":"1", "ln": "7"}],"power":[{"key":"cell_count", "value":"3", "ln": "9"},{"key":"warning_type", "value":"2", "ln": "10"},{"key":"power_ana_rx", "value":"1", "ln": "11"},{"key":"calibration_offset", "value":"0", "ln": "12"}],"wifi":[{"key":"clientid", "value":"067342ACC43FFF", "ln": "14"},{"key":"enable", "value":"true", "ln": "15"},{"key":"mode", "value":"1", "ln": "16"},{"key":"ap_ssid", "value":"HDZero", "ln": "17"},{"key":"ap_passwd", "value":"divimath", "ln": "18"},{"key":"sta_ssid", "value":"Guest", "ln": "19"},{"key":"sta_passwd", "value":"XXXXXXX!", "ln": "20"},{"key":"dhcp", "value":"true", "ln": "21"},{"key":"ip_addr", "value":"192.168.4.110", "ln": "22"},{"key":"netmask", "value":"255.255.255.0", "ln": "23"},{"key":"gateway", "value":"192.168.4.10", "ln": "24"},{"key":"dns", "value":"192.168.2.1", "ln": "25"},{"key":"rf_channel", "value":"6", "ln": "26"},{"key":"root_pw", "value":"divimath", "ln": "27"},{"key":"ssh", "value":"true", "ln": "28"}],"autoscan":[{"key":"last_source", "value":"1", "ln": "30"}],"fans":[{"key":"top_speed", "value":"4", "ln": "32"}],"record":[{"key":"mode_manual", "value":"true", "ln": "34"},{"key":"osd", "value":"false", "ln": "35"},{"key":"audio", "value":"false", "ln": "36"},{"key":"format_ts", "value":"true", "ln": "37"}],"clock":[{"key":"year", "value":"2024", "ln": "39"},{"key":"month", "value":"12", "ln": "40"},{"key":"day", "value":"24", "ln": "41"},{"key":"hour", "value":"11", "ln": "42"},{"key":"min", "value":"0", "ln": "43"},{"key":"sec", "value":"0", "ln": "44"},{"key":"format", "value":"0", "ln": "45"}],"scan":[{"key":"channel", "value":"1", "ln": "47"}],"source":[{"key":"analog_format", "value":"0", "ln": "49"}],"image":[{"key":"oled", "value":"8", "ln": "51"},{"key":"brightness", "value":"39", "ln": "52"},{"key":"saturation", "value":"28", "ln": "53"},{"key":"contrast", "value":"25", "ln": "54"},{"key":"auto_off", "value":"1", "ln": "55"}]}]}
Create new lines or a new section after the line or section provided in the URI given. Or create new lines or a new section at the end of the section or the end of file if no line or section is provided in the URI. If lines or section exists a error will be returned. Lines that don't exits will be created in existing section. Takes a JSON Section object with one or more Lines. Returns the section that remains after insert.
/cgi-bin/setting?post=line
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"00"}]}
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"57"}]}
/cgi-bin/setting?post=line&after=month
{"section":"birthday","setting_list":[{"key":"day","value":"24","line":"00"}]}
{"section":"birthday","setting_list":[{"key":"day","value":"24","line":"59"}]}
/cgi-bin/setting?post=section
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"00"},{"key":"month","value":"04","line":"00"},{"key":"day","value":"24","line":"00"}]}
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"57"},{"key":"month","value":"04","line":"58"},{"key":"day","value":"24","line":"59"}]}
/cgi-bin/setting?post=section&after=clock
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"00"},{"key":"month","value":"04","line":"00"},{"key":"day","value":"24","line":"00"}]}
{"section":"birthday","setting":[{"key":"year","value":"2024","line":"47"},{"key":"month","value":"04","line":"48"},{"key":"day","value":"24","line":"49"}]}
Replaces all lines in a section with one or more lines passed as content. Return an error if the section does not exist.
/cgi-bin/setting?put=line
{"section":"birthday","setting_list":[{"key":"Year","value":"2025","line":"00"},{"key":"Month","value":"06","line":"00"}]}
{"section":"birthday","setting_list":[{"key":"Year","value":"2025","line":"57"},{"key":"Month","value":"06","line":"58"}]}
Change one or more line values in a section. Throw error if line or section does not exist.
/cgi-bin/setting?patch=line
{"section":"birthday","setting_list":[{"key":"Year","value":"1954","line":"00"},{"key":"Month","value":"02","line":"00"},{"key":"Day","value":"02","line":"00"}]}
{"section":"birthday","setting_list":[{"key":"Year","value":"1954","line":"57"},{"key":"Month","value":"02","line":"58"}]}
Status: 400 Bad Request
Error: line does not exist.
Delete one or more lines in a section or delete entire section? Throws error if a line or section does not exist. Returns the delected lines and section.
/cgi-bin/setting?delete=line
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"00"}]}
{"section":"birthday","setting_list":[ {"key": "year", "value": "2024", "line": "57"}, ] }
/cgi-bin/settings?delete=section
{"section":"birthday","setting_list":[]}
{"section":"birthday","setting_list":[{"key":"year","value":"2024","line":"57"},{"key":"month","value":"05","line":"58"},{"key":"day","value":"24","line":"59"}]}
There is likley more work that could be done on the File API. The API operates on the SD Card mount point only and accepts an absolute path or path relative to the mount point. Don't give anyone access to your network. The connection is not secure. It discourages malicious code by scrubbing paths and limiting file names. Uploads and downloads are limited to 25 MG. Paths can be either absolute /mnt/extsd/mov
List will accepts simple globs and a single period extension. Example filter="filename*.jpg", filter = ".jpg", or filter="filename." will work. The stat method will accept a path outside of sd card.
/cgi-bin/file
{"info_list":[ {"name":"FSCK","date":"2025-02-26","time":"18:16:06.618056704","offset":"-0500","size":"4096","permissions":"drwxr-xr-x"},{"name":"HDZERO_GOGGLE-75-191-9.4.0.bin","date":"2025-03-18","time":"14:49:51.286455950","offset":"-0400","size":"7464962","permissions":"-rw-r--r--"},{"name":"isp0_0_0_0_ctx_saved.bin","date":"2025-02-26","time":"18:14:53.551053720","offset":"-0500","size":"40472","permissions":"-rw-r--r--"},{"name":"movies","date":"2025-02-23","time":"13:28:37.747766228","offset":"-0500","size":"4096","permissions":"drwxr-xr-x"}]}
/cgi-bin/file?list=/movies/stars
{"info_list":[ {"name":"hdz_000.jpg","date":"2025-03-18","time":"14:49:50.291455909","offset":"-0400","size":"6978","permissions":"-rw-r--r--"}]}
cgi-bin/file?list=/movies&filter=*.jpg
{"info_list":[ {"name":"/mnt/extsd//movies/hdz_000.jpg","date":"2025-02-13","time":"12:27:03.301328631","offset":"-0500","size":"6976","permissions":"-rw-r--r--"},{"name":"/mnt/extsd//movies/hdz_001.jpg","date":"2025-02-13","time":"12:27:04.232328669","offset":"-0500","size":"6976","permissions":"-rw-r--r--"},{"name":"/mnt/extsd//movies/hdz_004.jpg","date":"2025-02-13","time":"12:27:10.074328908","offset":"-0500","size":"6976","permissions":"-rw-r--r--"},{"name":"/mnt/extsd//movies/hdz_006.jpg","date":"2025-02-13","time":"12:27:11.799328978","offset":"-0500","size":"6976","permissions":"-rw-r--r--"},{"name":"/mnt/extsd//movies/save_this.jpg","date":"2025-02-13","time":"12:27:09.060328867","offset":"-0500","size":"11072","permissions":"-rw-r--r--"}]}
/cgi-bin/file?stat=/tmp
{"path":"/dev/sda2","used":"80826360","available":"828671496"}
/cgi-bin/file?download=/movies/hdz_006.mp4
Opens the download file dialog to download the file. Size is limited to 25 MG.
Upload one or more files. Copy one or more files or convert a file to mp4. Takes an array of source and destination paths. Conversion uses ffmpeg with libx264 library built in. The license will required user to build ffmpeg. Resultng MP4 files are about 25% size of the orginal and took about 4 minutes per file on my desktop. Conversions overwrite and a .con text file is created for each conversion with the output file name. Could add something that checks the .con or header for the completed conversion.
/cgi-bin/file?put=copy
{"fr_to_list":[{"from_path":"/movies/save_this.ts","to_path":"movies/stars/bars.ts"},{"from_path":"/movies/hdz_0006na.mp4","to_path":"movies/stars/hdz_0006na.mp4"}]}
copied from /mnt/extsd/movies/save_this.ts to /mnt/extsd/movies/stars/bars.ts.
copied from /mnt/extsd/movies/hdz_0006na.mp4 to /mnt/extsd/movies/stars/hdz_0006na.mp4.
/cgi-bin/file?put=mp4
{"fr_to_list":[{"from_path":"/movies/hdz_001.ts","to_path":"movies/stars/hdz_001.mp4"},{"from_path":"/movies/hdz_004.ts","to_path":"movies/stars/hdz_004.mp4"}]}
Conversion completed from /mnt/extsd/movies/hdz_001.ts to /mnt/extsd/movies/stars/hdz_001.mp4.
Conversion completed from /mnt/extsd/movies/hdz_004.ts to /mnt/extsd/movies/stars/hdz_004.mp4.
/cgi-bin/file?put=upload
--00234c79-80ba-414a-92fe-68733bb023b1
Content-Disposition: form-data; name="files"; filename="HDZERO_GOGGLE-75-191-9.4.0.bin"
Content-Type: application/octet-stream ...
Successfully uploaded --00234c79-80ba-414a-92fe-68733bb023b1
file: /mnt/extsd/HDZERO_GOGGLE-75-191-9.4.0.bin next: 255
Move or rename one or more files. Takes an array of source and destination paths.
/cgi-bin/file?patch=file
/cgi-bin/file?patch=format
{"fr_to_list":[{"from_path":"/mnt/extsd/movies/save_this.jpg","to_path":"/mnt/extsd/movies/stars/save_this.jpg"},{"from_path":"/mnt/extsd/movies/stars/save_this.ts","to_path":"/mnt/extsd/movies/save_this.ts"}]}
Delete all files from a list of directories or delete a list of files. Displays the number of lines deleted if directory. Displays each path delete or error if does not exist.
/cgi-bin/file?delete=file
/cgi-bin/file?delete=directory
If you appreciate this work or find the functionality useful. Please consider donating to support this project.
