Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: luc-github/ESP3D-WEBUI
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v3.0.0-alpha3
Choose a base ref
...
head repository: luc-github/ESP3D-WEBUI
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v3.0.0-beta1
Choose a head ref

Commits on Oct 7, 2019

  1. Update issue templates

    luc-github authored Oct 7, 2019
    Copy the full SHA
    987a129 View commit details
  2. Copy the full SHA
    deb87a4 View commit details

Commits on Oct 8, 2019

  1. Update french thanks @ewidance

    Luc committed Oct 8, 2019
    Copy the full SHA
    e700f25 View commit details

Commits on Oct 22, 2019

  1. Update FUNDING.yml

    luc-github authored Oct 22, 2019

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    34a6669 View commit details

Commits on Nov 3, 2019

  1. Copy the full SHA
    b8c8f3c View commit details
  2. Copy the full SHA
    874dfdc View commit details

Commits on Nov 28, 2019

  1. Fixes #74, #76

    luc-github committed Nov 28, 2019
    Copy the full SHA
    8e511c5 View commit details
  2. Fix brokenUI on phone

    Fixes #75
    luc-github committed Nov 28, 2019
    Copy the full SHA
    7e4811b View commit details

Commits on Jan 5, 2020

  1. Fixes #86

    luc-github committed Jan 5, 2020
    Copy the full SHA
    9b71d00 View commit details

Commits on Jan 14, 2020

  1. Create config.yml

    luc-github authored Jan 14, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    87ac127 View commit details
  2. Update config.yml

    luc-github authored Jan 14, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e33fb9e View commit details

Commits on Jan 15, 2020

  1. Copy the full SHA
    c0ef8b9 View commit details
  2. Copy the full SHA
    242477e View commit details
  3. Update files.js

    luc-github committed Jan 15, 2020
    Copy the full SHA
    9605427 View commit details

Commits on Jan 16, 2020

  1. Copy the full SHA
    223baaf View commit details
  2. Create index.html.gz

    luc-github committed Jan 16, 2020
    2
    Copy the full SHA
    f6922ba View commit details

Commits on Mar 17, 2020

  1. Base for simplified chinese

    Luc committed Mar 17, 2020
    Copy the full SHA
    b50cb98 View commit details

Commits on Mar 19, 2020

  1. Copy the full SHA
    6f477c4 View commit details

Commits on Mar 20, 2020

  1. Fixe #90 GRBL help translation not displayed as expected

    thanks @zrwd01  for pointing this out
    luc-github committed Mar 20, 2020
    Copy the full SHA
    5abb5e9 View commit details
  2. Copy the full SHA
    cece692 View commit details
  3. Update README.md

    luc-github authored Mar 20, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5da9e20 View commit details

Commits on Apr 16, 2020

  1. fix typo

    luc-github committed Apr 16, 2020
    Copy the full SHA
    185a7de View commit details

Commits on Apr 24, 2020

  1. Remove FR: report from not verbose mode

    TFT bigtreetech do permanent polling which bring FR:XXX% every second
    luc-github committed Apr 24, 2020
    Copy the full SHA
    0789242 View commit details
  2. Fixes #79

    luc-github committed Apr 24, 2020
    Copy the full SHA
    1152ccf View commit details

Commits on Apr 25, 2020

  1. Add support for temperature / positions broadcast

    Add support for Flow rate / Feed rate broadcast, initialize Feed rate / Flow rate control if info available
    Add rendering for custom command for temperature / position /etc
    luc-github committed Apr 25, 2020
    Copy the full SHA
    d3e5b6d View commit details

Commits on Apr 26, 2020

  1. Add BTT USB DISK and onBoard SD support

    Clean the console.log of broadcast data
    luc-github committed Apr 26, 2020
    Copy the full SHA
    3c774e5 View commit details
  2. Copy the full SHA
    d6f9ebe View commit details
  3. Use translation for SD

    luc-github committed Apr 26, 2020
    Copy the full SHA
    fddbcee View commit details

Commits on May 10, 2020

  1. Copy the full SHA
    462b04b View commit details
  2. Copy the full SHA
    8c42fd0 View commit details

Commits on May 26, 2020

  1. update main screenshot

    luc-github committed May 26, 2020
    Copy the full SHA
    82539ee View commit details

Commits on May 30, 2020

  1. Copy the full SHA
    db672f3 View commit details

Commits on Jun 8, 2020

  1. Update README.md

    luc-github authored Jun 8, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    e07012a View commit details

Commits on Jun 9, 2020

  1. Update README.md

    luc-github authored Jun 9, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    a62a876 View commit details

Commits on Jun 11, 2020

  1. Add Hungarian Thanks @kondorzs

    Update Italian Thanks @onekk
    luc-github committed Jun 11, 2020
    Copy the full SHA
    069771a View commit details
  2. Copy the full SHA
    f137b71 View commit details

Commits on Jun 16, 2020

  1. update german thanks @Wesie

    luc-github committed Jun 16, 2020
    Copy the full SHA
    50860c2 View commit details

Commits on Jun 18, 2020

  1. Update README.md

    luc-github authored Jun 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    fdb7120 View commit details
  2. Update README.md

    luc-github authored Jun 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5075e32 View commit details
  3. Update README.md

    luc-github authored Jun 18, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    5680fe5 View commit details

Commits on Jul 7, 2020

  1. Copy the full SHA
    f90291e View commit details

Commits on Jul 10, 2020

  1. Copy the full SHA
    a42a712 View commit details

Commits on Jul 11, 2020

  1. Added firmware checks for temperature controls

    BToersche committed Jul 11, 2020
    Copy the full SHA
    d09e4b2 View commit details
  2. Copy the full SHA
    14cdc40 View commit details

Commits on Jul 12, 2020

  1. Copy the full SHA
    c7e95f1 View commit details
  2. Merge pull request #103 from BToersche/2.1

    Added support for Marlin T0 redundant, probe and chamber temperatures
    luc-github authored Jul 12, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    f8714ab View commit details
  3. Copy the full SHA
    bc0d43e View commit details
  4. Merge pull request #105 from luc-github/2.1-BTT-TFT

    2.1 add support of BTT TFT commands
    luc-github authored Jul 12, 2020

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
    Copy the full SHA
    dd8ec5f View commit details
  5. Copy the full SHA
    84ca772 View commit details

Commits on Aug 22, 2020

  1. Copy the full SHA
    cd95bd2 View commit details
Showing 556 changed files with 86,673 additions and 34,817 deletions.
37 changes: 37 additions & 0 deletions .github/ci/final-check.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/bash
# Exit immediately if a command exits with a non-zero status.
set -e
# Enable the globstar shell option
shopt -s globstar
# Make sure we are inside the github workspace
cd $GITHUB_WORKSPACE
echo $STEPS_CONTEXT
step=$1
status=$2
export BODYMESSAGE="$(git log -1 $GITHUB_SHA --pretty=oneline --abbrev-commit)"
export BACKTICK='`';
export TIMESTAMP=$(date --utc +%FT%TZ);
export GITHUB_ACTOR_NAME="$(git log -1 $GITHUB_SHA --pretty="%aN")";
export COMMIT_FORMATTED="[$BACKTICK${GITHUB_SHA:0:7}$BACKTICK](https://github.com/$GITHUB_REPOSITORY/commit/$GITHUB_SHA)";

if [[ "$status" == "success" ]];
then
echo "Success build"
if [ -z "$DISCORD_WEBHOOK_URL" ];
then
echo "no need bot"
else
curl -v -H User-Agent:bot -H Content-Type:application/json -d '{"avatar_url":"https://pngimg.com/uploads/github/github_PNG90.png","username":"github-action","embeds":[{"author":{"name":"Build #'"$step"' Passed - '"$GITHUB_ACTOR_NAME"'","url":"https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'"},"url":"https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'","title":"['"$GITHUB_REPOSITORY"':job#'"$GITHUB_RUN_NUMBER"'] ","color":65280,"fields":[{"name":"_ _", "value": "'"$COMMIT_FORMATTED"' - '"$BODYMESSAGE"'"}],"timestamp":"'"$TIMESTAMP"'","footer":{"text":"ESP3D CI"}}]}' $DISCORD_WEBHOOK_URL;
fi
else
echo "Build failed"
if [ -z "$DISCORD_WEBHOOK_URL" ];
then
echo "no need bot"
else
curl -v -H User-Agent:bot -H Content-Type:application/json -d '{"avatar_url":"https://pngimg.com/uploads/github/github_PNG90.png","username":"github-action","embeds":[{"author":{"name":"Build #'"$step"' Failed - '"$GITHUB_ACTOR_NAME"'","url":"https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'"},"url":"https://github.com/'"$GITHUB_REPOSITORY"'/actions/runs/'"$GITHUB_RUN_ID"'","title":"['"$GITHUB_REPOSITORY"':job#'"$GITHUB_RUN_NUMBER"'] ","color":16711680,"fields":[{"name":"_ _", "value": "'"$COMMIT_FORMATTED"' - '"$BODYMESSAGE"'"}],"timestamp":"'"$TIMESTAMP"'","footer":{"text":"ESP3D CI"}}]}' $DISCORD_WEBHOOK_URL;
fi
exit 1
fi


32 changes: 32 additions & 0 deletions .github/workflows/build-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
name: build-ci

on: [pull_request, push]

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Use Node.js
uses: actions/setup-node@v3
with:
node-version: '16.x'
- name: Install libraries
id: setuptools
run: npm install
continue-on-error: true
- name: Build all files
id: buildall
run: npm run buildall
continue-on-error: true
- name: Failure check
env:
STEPS_CONTEXT: ${{ toJson(steps) }}
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
if: steps.setuptools.outcome == 'failure' || steps.buildall.outcome == 'failure'
run: bash ./.github/ci/final-check.sh "$GITHUB_RUN_ID" "failure"
- name: Success check
env:
DISCORD_WEBHOOK_URL: ${{ secrets.DISCORD_WEBHOOK_URL }}
if: steps.setuptools.outcome == 'success' && steps.buildall.outcome == 'success'
run: bash ./.github/ci/final-check.sh "$GITHUB_RUN_ID" "success"
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
/.idea
node_modules
dist
.vscode
build
server
1 change: 1 addition & 0 deletions .nvmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
14.16.1
37 changes: 37 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"printWidth": 80,
"tabWidth": 4,
"useTabs": false,
"semi": false,
"singleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"overrides": [
{
"files": "*.js",
"options": {
"parser": "babel"
}
},
{"files": "*.css",
"options": {
"parser": "css"
}
},
{"files": "*.scss",
"options": {
"parser": "scss"
}
},
{"files": "*.json",
"options": {
"printWidth": 120,
}
}
]
}
19 changes: 0 additions & 19 deletions .travis.yml

This file was deleted.

311 changes: 311 additions & 0 deletions Memo/Commands.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,311 @@
# Direct ESP3D commands (V3.x)

## Conventions

1 - add space to separate parameters
2 - if parameter has space add \\ in front of space to not be seen as separator
3 - json json=YES json=TRUE json=1 are paremeters to switch output to json
By default output is plain text, to get json formated output
add json or json=yes after main parameters
The json format is {
cmd:"<command id>", //the id of requested command
status:"<ok/error>" //give if it is success or an failure
data:"<response>" // response corresponding to answer in json format too
}

## Commands

- Show commands help
`[ESP]<command id> json=<no>`

- Set/Get STA SSID
`[ESP100]<SSID> json=<no> pwd=<admin password for set/get & user password to get>`

- Set STA Password
`[ESP101]<Password> json=<no> pwd=<admin password>`

- Set/Get STA IP mode (DHCP/STATIC)
`[ESP102]<mode> json=<no> pwd=<admin password>`

- Set/Get STA IP/Mask/GW/DNS
`[ESP103]IP=<IP> MSK=<IP> GW=<IP> DNS=<IP> json=<no> pwd=<admin password>`

- Set/Get sta fallback mode which can be WIFI-AP, BT, OFF
`[ESP104]<state> json=<no> pwd=<admin password>`

- Set/Get AP SSID
`[ESP105]<SSID> json=<no> pwd=<admin password>`

- Change AP Password
`[ESP106]<Password> json=<no> pwd=<admin password>`

- Set/Get AP IP
`[ESP107]<IP> json=<no> pwd=<admin password>`

- Set/Get AP channel
`[ESP108]<channel> json=<no> pwd=<admin password>`

- Set/Get radio state which can be WIFI-STA, WIFI-AP, BT, ETH-STA, ETH-AP, OFF
`[ESP110]<state> json=<no> pwd=<admin password>`

- Get current IP
`[ESP111]json=<no>`

- Get/Set hostname
`[ESP112]<Hostname> json=<no> pwd=<admin password>`

- Get /Set Boot radio state which can be ON, OFF
`[ESP114]<state> json=<no> pwd=<user/admin password>`

- Get/Set immediate network(WiFi/BT/Ethernet) state which can be ON, OFF
`[ESP115]<state> json=<no> pwd=<admin password>`

- Get/Set HTTP state which can be ON, OFF
`[ESP120]<state> json=<no> pwd=<admin password>`

- Get/Set HTTP port
`[ESP121]<port> json=<no> pwd=<admin password>`

- Get/Set Telnet state which can be ON, OFF, CLOSE
`[ESP130]<state> json=<no> pwd=<admin password>`

- Get/Set Telnet port
`[ESP131]<port> json=<no> pwd=<admin password>`

- Sync / Set / Get current time
`[ESP140]<SYNC> <srv1=XXXXX> <srv2=XXXXX> <srv3=XXXXX> <zone=xxx> <dst=YES/NO> <time=YYYY-MM-DDTHH:mm:ss> <NOW> json=<no> pwd=<admin password>`

- Get/Set display/set boot delay in ms / Verbose boot
`[ESP150]<delay=time in milliseconds><verbose=ON/OFF>pwd=<admin password>`

- Get/Set WebSocket state which can be ON, OFF
`[ESP160]<state> json=<no> pwd=<admin password>`

- Get/Set WebSocket port
`[ESP161]<port> json=<no> pwd=<admin password>`

- Get/Set Camera command value / list all values in JSON/plain
label can be: light/framesize/quality/contrast/brightness/saturation/gainceiling/colorbar/awb/agc/aec/hmirror/vflip/awb_gain/agc_gain/aec_value/aec2/cw/bpc/wpc/raw_gma/lenc/special_effect/wb_mode/ae_level
`[ESP170]<label=value> json=<no> pwd=<admin password>`

- Save frame to target path and filename (default target = today date, default name=timestamp.jpg)
`[ESP171] <path=target path> <filename=target filename>`

- Get/Set Ftp state which can be ON, OFF, CLOSE
`[ESP180]<state> json=<no> pwd=<admin password>`

- Get/Set Ftp ports
`[ESP181]ctrl=<port> active=<port> passive=<port> json=<no> pwd=<admin password>`

- Get/Set WebDav state which can be ON, OFF, CLOSE
`[ESP190]<state> json=<no> pwd=<admin password>`

- Get/Set WebDav port
`[ESP191]<port> json=<no> pwd=<admin password>`

- Get/Set SD Card Status
`[ESP200]<RELEASE> <REFRESH> json=<no> pwd=<user/admin password>`
`RELEASE` will force the release of SD from ESP3D if SD is shared
`REFRESH` will refresh the SD info is available`

- Get/Set pin value
`[ESP201]P=<pin> V=<value> [PULLUP=YES RAW=YES ANALOG=NO ANALOG_RANGE=255]pwd=<admin password>`

- if no V=<value> get P=<pin> value
- if V=<value> 0/1 set INPUT_PULLUP value, but for GPIO16(ESP8266) INPUT_PULLDOWN_16
- if PULLUP=YES set input pull up (for GPIO16(ESP8266) INPUT_PULLDOWN_16), if not set input
- if RAW=YES do not set pinmode just read value

Note: Flash pins according chip cannot be used

- Get/Set SD card Speed factor 1 2 4 6 8 16 32
`[ESP202]SPEED=<value> json=<no> pwd=<user/admin password>`

- Get Sensor Value / type/Set Sensor type
`[ESP210]<type=NONE/xxx> <interval=XXX in millisec> json=<no> pwd=<user/admin password>`

- Output to esp screen status
`[ESP214]<Text> json=<no> pwd=<user/admin password>`

- Touch Calibration
`[ESP215]<CALIBRATE> json=<no> pwd=<user password>`

- Show defined pins
`[ESP220]<SNAP> json=<no> pwd=<user password>`

- Play sound
`[ESP250]F=<frequency> D=<duration> json=<no> pwd=<user password>`
Note: No parameter just play beep

- Delay command
`[ESP290]<delay in ms> json=<no>pwd=<user password>`

- Get full EEPROM settings content
`[ESP400] pwd=<admin password>`
Note: do not give any passwords

\*Set EEPROM setting
position in EEPROM, type: B(byte), I(integer/long), S(string), A(IP address / mask)
`[ESP401]P=<position> T=<type> V=<value> json=<no> pwd=<user/admin password>`

```
Description: Positions:
ESP_RADIO_MODE 0 //1 byte = flag
ESP_STA_SSID 1 //33 bytes 32+1 = string ; warning does not support multibyte char like chinese
ESP_STA_PASSWORD 34 //65 bytes 64 +1 = string ;warning does not support multibyte char like chinese
ESP_STA_IP_MODE 99 //1 byte = flag
ESP_STA_IP_VALUE 100 //4 bytes xxx.xxx.xxx.xxx
ESP_STA_MASK_VALUE 104 //4 bytes xxx.xxx.xxx.xxx
ESP_STA_GATEWAY_VALUE 108 //4 bytes xxx.xxx.xxx.xxx
ESP_BAUD_RATE 112 //4 bytes = int
ESP_NOTIFICATION_TYPE 116 //1 byte = flag
ESP_CALIBRATION 117 //1 byte = flag
ESP_AP_CHANNEL 118 //1 byte = flag
ESP_BUZZER 119 //1 byte = flag
ESP_INTERNET_TIME 120 //1 byte = flag
ESP_HTTP_PORT 121 //4 bytes = int
ESP_TELNET_PORT 125 //4 bytes = int
FREE 129 //1 bytes = flag
ESP_HOSTNAME 130 //33 bytes 32+1 = string ; warning does not support multibyte char like chinese
ESP_SENSOR_INTERVAL 164 //4 bytes = int
ESP_SETTINGS_VERSION 168 //8 bytes = 7+1 = string ESP3D + 2 digits
ESP_ADMIN_PWD 176 //21 bytes 20+1 = string ; warning does not support multibyte char like chinese
ESP_USER_PWD 197 //21 bytes 20+1 = string ; warning does not support multibyte char like chinese
ESP_AP_SSID 218 //33 bytes 32+1 = string ; warning does not support multibyte char like chinese
ESP_AP_PASSWORD 251 //65 bytes 64 +1 = string ;warning does not support multibyte char like chinese
ESP_AP_IP_VALUE 316 //4 bytes xxx.xxx.xxx.xxx
ESP_BOOT_DELAY 320 //4 bytes = int
ESP_WEBSOCKET_PORT 324 //4 bytes= int
ESP_HTTP_ON 328 //1 byte = flag
ESP_TELNET_ON 329 //1 byte = flag
ESP_WEBSOCKET_ON 330 //1 byte = flag
ESP_SD_SPEED_DIV 331 //1 byte = flag
ESP_NOTIFICATION_TOKEN1 332 //251 bytes 250+1 = string ; warning does not support multibyte char like chinese
ESP_NOTIFICATION_TOKEN2 583 //64 bytes 63+1 = string ; warning does not support multibyte char like chinese
ESP_SENSOR_TYPE 647 //1 bytes = flag
ESP_TARGET_FW 648 //1 bytes = flag
FREE 649 //1 bytes = flag
FREE 650 //1 bytes = flag
ESP_TIME_SERVER1 651 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER2 780 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_TIME_SERVER3 909 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_REMOTE_SCREEN 1038 //1 bytes = flag
ESP_SD_MOUNT 1039 //1 bytes = flag
ESP_SESSION_TIMEOUT 1040 //1 bytes = flag
FREE FLAG 1041 //1 bytes = flag
ESP_SD_CHECK_UPDATE_AT_BOOT 1042//1 bytes = flag
ESP_NOTIFICATION_SETTINGS 1043 //129 bytes 128+1 = string ; warning does not support multibyte char like chinese
ESP_CALIBRATION_1 1172 //4 bytes = int
ESP_CALIBRATION_2 1176 //4 bytes = int
ESP_CALIBRATION_3 1180 //4 bytes = int
ESP_CALIBRATION_4 1184 //4 bytes = int
ESP_CALIBRATION_5 1188 //4 bytes = int
ESP_SETUP 1192 //1 byte = flag
FREE 1193 //1 byte = flag
FREE 1194 //1 byte = flag
FREE 1195 //1 byte = flag
ESP_FTP_CTRL_PORT 1196 //4 bytes = int
ESP_FTP_DATA_ACTIVE_PORT 1200 //4 bytes = int
ESP_FTP_DATA_PASSIVE_PORT 1204 //4 bytes = int
ESP_FTP_ON 1208 //1 byte = flag
ESP_AUTO_NOTIFICATION 1209 //1 byte = flag
ESP_VERBOSE_BOOT 1210 //1 byte = flag
ESP_WEBDAV_ON 1211 //1 byte = flag
ESP_WEBDAV_PORT 1212 //4 bytes = int
ESP_STA_DNS_VALUE 1216 //4 bytes= int
ESP_SECURE_SERIAL 1220 //1 byte = flag
ESP_SERIAL_BRIDGE_ON 1223 //1 byte = flag
FREE 1224 //1 byte = flag
ESP_SERIAL_BRIDGE_BAUD 1225 //4 bytes= int
ESP_TIME_ZONE 1229 //7 bytes= string
```

- Get/Set Check update at boot state which can be ON, OFF
`[ESP402]<state> json=<no> pwd=<admin password>`

- Get available AP list (limited to 30)
output is JSON or plain text according parameter
`[ESP410]json=<no> <pwd=admin/user>`

- Get current settings of ESP3D
Output is JSON or plain text according parameter
`[ESP420]json=<no> <pwd=admin/user>`

- Set ESP State
`cmd` can be `RESTART` to restart board or `RESET` to reset all setting to defaults values
`[ESP444]<cmd> json=<no> <pwd=admin>`

- Get available ESP3D list
output is JSON or plain text according parameter
`[ESP450]json=<no> <pwd=admin/user>`

- Change admin password
`[ESP550]<password> json=<no> pwd=<admin password>`

- Change user password
`[ESP555]<password> json=<no> pwd=<admin/user password>`

- Send Notification
`[ESP600]msg json=<no> pwd=<admin/user password>`

- Set/Get Notification settings
`[ESP610]type=<NONE/PUSHOVER/EMAIL/LINE/IFTTT> T1=<token1> T2=<token2> TS=<Settings> json=<no> [pwd=<admin password>]`
Get will give type and settings only, not the protected T1/T2

- Send Notification using URL
`[ESP620]URL=<encoded url> json=<no> pwd=<admin/user password>`

- Read / Stream / Process FS file
`[ESP700]<filename> json=<no> pwd=<admin/user password>`

- Query and Control ESP700 stream
`[ESP701]action=<PAUSE/RESUME/ABORT> json=<no> pwd=<admin/user password>`

- Format ESP Filesystem
`[ESP710]FORMATFS json=<no> pwd=<admin password>`

- Format SD Filesystem
`[ESP715]FORMATSD json=<no> pwd=<admin password>`

- List ESP Filesystem
`[ESP720]<Root> json=<no> pwd=<admin password>`

- Action on ESP Filesystem
Action can be `rmdir` to remove empty directory / `remove` to delete file / `mkdir` to create directory / `exists` to check if file or directory exists / `create` create an empty file
`[ESP730]<Action>=<path> json=<no> pwd=<admin password>`

- List SD Filesystem
`[ESP740]<Root> json=<no> pwd=<admin password>`

- Action on SD Filesystem
Action can be `rmdir` to remove empty directory / `remove` to delete file / `mkdir` to create directory / `exists` to check if file or directory exists / `create` create an empty file
`[ESP750]<Action>=<path> json=<no> pwd=<admin password>`

- List Global Filesystem
`[ESP780]<Root> json=<no> pwd=<admin password>`

- Action on Global Filesystem
Action can be `rmdir` to remove empty directory / `remove` to delete file / `mkdir` to create directory / `exists` to check if file or directory exists / `create` create an empty file
`[ESP790]<Action>=<path> json=<no> pwd=<admin password>`

- FW Informations
`[ESP800]json=<no> pwd=<admin password> <time=YYYY-MM-DDTHH:mm:ss> <version=3.0.0-a11> <setup=0/1>`

- Get state / Set Enable / Disable Serial Communication
`[ESP900]<ENABLE/DISABLE> json=<no> pwd=<admin/user password>`
- Get / Set Serial Baud Rate
`[ESP901]<BAUD RATE> json=<no> pwd=<admin/user password>`

- Get state / Set Enable / Disable buzzer
`[ESP910]<ENABLE/DISABLE> json=<no> pwd=<admin/user password>`

- Get state / Set state of output message clients
`[ESP920]<SERIAL / SCREEN / REMOTE_SCREEN/ WEBSOCKET / TELNET /BT / ALL>=<ON/OFF> json=<no> pwd=<admin/user password>`

- Get state / Set Enable / Disable Serial Bridge Communication
`[ESP930]<ENABLE/DISABLE> json=<no> pwd=<admin/user password>`
- Get / Set Serial Bridge Baud Rate
`[ESP931]<BAUD RATE> json=<no> pwd=<admin/user password>`

- Set quiet boot if strapping pin is High
`[ESP999]QUIETBOOT pwd=<admin/user password>`
102 changes: 102 additions & 0 deletions Memo/ESP3D [ESP400] format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# ESP3D [ESP400] format

Only sent in JSON format

```
{"cmd":"400","status":"ok","data":[
{"F":"network/network","P":"130","T":"S","V":"esp3d","H":"hostname","S":"32","M":"1"},
{"F":"network/network","P":"0","T":"B","V":"1","H":"radio mode","O":[{"none":"0"},
{"sta":"1"},
{"ap":"2"}]},
{"F":"network/sta","P":"1","T":"S","V":"WIFI_OFFICE_B2G","S":"32","H":"SSID","M":"1"},
{"F":"network/sta","P":"34","T":"S","N":"1","V":"********","S":"64","H":"pwd","M":"8"},
{"F":"network/sta","P":"99","T":"B","V":"1","H":"ip mode","O":[{"dhcp":"1"},
{"static":"0"}]},
{"F":"network/sta","P":"100","T":"A","V":"192.168.0.1","H":"ip"},
{"F":"network/sta","P":"108","T":"A","V":"192.168.0.1","H":"gw"},
{"F":"network/sta","P":"104","T":"A","V":"255.255.255.0","H":"msk"},
{"F":"network/ap","P":"218","T":"S","V":"ESP3D","S":"32","H":"SSID","M":"1"},
{"F":"network/ap","P":"251","T":"S","N":"1","V":"********","S":"64","H":"pwd","M":"8"},
{"F":"network/ap","P":"316","T":"A","V":"192.168.0.1","H":"ip"},
{"F":"network/ap","P":"118","T":"B","V":"11","H":"channel","O":[{"1":"1"},
{"2":"2"},
{"3":"3"},
{"4":"4"},
{"5":"5"},
{"6":"6"},
{"7":"7"},
{"8":"8"},
{"9":"9"},
{"10":"10"},
{"11":"11"},
{"12":"12"},
{"13":"13"},
{"14":"14"}]},
{"F":"service/http","P":"328","T":"B","V":"1","H":"enable","O":[{"no":"0"},
{"yes":"1"}]},
{"F":"service/http","P":"121","T":"I","V":"80","H":"port","S":"65001","M":"1"},
{"F":"service/telnetp","P":"329","T":"B","V":"1","H":"enable","O":[{"no":"0"},
{"yes":"1"}]},
{"F":"service/telnetp","P":"125","T":"I","V":"23","H":"port","S":"65001","M":"1"},
{"F":"service/ftp","P":"1208","T":"B","V":"1","H":"enable","O":[{"no":"0"},
{"yes":"1"}]},
{"F":"service/ftp","P":"1196","T":"I","V":"21","H":"control port","S":"65001","M":"1"},
{"F":"service/ftp","P":"1200","T":"I","V":"20","H":"active port","S":"65001","M":"1"},
{"F":"service/ftp","P":"1204","T":"I","V":"55600","H":"passive port","S":"65001","M":"1"},
{"F":"service/notification","P":"1191","T":"B","V":"1","H":"auto notif","O":[{"no":"0"},
{"yes":"1"}]},
{"F":"service/notification","P":"116","T":"B","V":"0","H":"notification","O":[{"none":"0"},
{"pushover":"1"},
{"email":"2"},
{"line":"3"}]},
{"F":"service/notification","P":"332","T":"S","V":"********","S":"250","H":"t1","M":"0"},
{"F":"service/notification","P":"583","T":"S","V":"********","S":"63","H":"t2","M":"0"},
{"F":"service/notification","P":"1042","T":"S","V":" ","S":"127","H":"ts","M":"0"},
{"F":"system/system","P":"648","T":"B","V":"40","H":"targetfw","O":[{"repetier":"50"},
{"marlin":"20"},
{"smoothieware":"40"},
{"grbl":"10"},
{"unknown":"0"}]},
{"F":"system/system","P":"112","T":"I","V":"115200","H":"baud","O":[{"9600":"9600"},
{"19200":"19200"},
{"38400":"38400"},
{"57600":"57600"},
{"74880":"74880"},
{"115200":"115200"},
{"230400":"230400"},
{"250000":"250000"},
{"500000":"500000"},
{"921600":"921600"}]},
{"F":"system/system","P":"320","T":"I","V":"10000","H":"bootdelay","S":"40000","M":"0"},
]}
```

1 - key : `Settings`
2 - value: array of data formated like this
{"F":"network/network","P":"130","T":"S","V":"esp3d","H":"hostname","S":"32","M":"1"}
or
{"F":"service/notification","P":"1191","T":"B","V":"1","H":"auto notif","O":[{"no":"0"},{"yes":"1"}]}

- F: is filter formated as section/sub-section, if section is same as sub-section, it means no sub-section
- P: is id (also position reference so it is unique)
- T: is type of data which can be:
- S: for string
- I: for integer
- B: for Byte
- A: for IP address / Mask
- F: for float (only grblHAL)
- M: for bits mask (only grblHAL)
- X: for exclusive bitsfield (only grblHAL)
- V: is current value, if type is string and value is `********`, (8 stars) then it is a password
- E: is integer for exactess / precision of float/double value (only grblHAL)
- U: is text unit of value (only grblHAL)
- H: is text label of value
- S: is max size if type is string, and max possible value if value is number (byte, integer)
- M: is min size if type is string, and min possible value if value is number (byte, integer)
- MS: is additionnal min size if type is string (e.g for password can be 0 or 8, so need additional min size), M should be the more minimal value
so MS value must be between M and S
- O: is an array of {label:value} used for possible values in selection or bits labels list
- R: need restart to be applied

Note: if Type `M` and `X` use `O` entry to define the label / position, if `O` is `[]` then axis label are used according need `X`, `Y`, `Z`, `A`, `B`, `C`
Note2 : the 2.1 Flag type is no more used, several entries are used instead grouped by sub-section
22 changes: 22 additions & 0 deletions Memo/ESP3D [ESP401] format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# ESP3D [ESP401] format

WebUI need use json format to get propelry formated answer
As described in Commands.md:

## Conventions

1 - add space to separate parameters
2 - if parameter has space add \\ in front of space to not be seen as separator
3 - json json=YES json=TRUE json=1 are paremeters to switch output to json
By default output is plain text, to get json formated output
add json or json=yes after main parameters
The json format is {
cmd:"<401>", //the id of requested command
status:"<ok/error>" //give if it is success or an failure
data:"the position of setting"
}

Example
`[ESP401]P=1 T=S V=My\ SSID json`
you will get the following if ok
`{"cmd":"401","status":"ok","data":"1"}`
34 changes: 34 additions & 0 deletions Memo/ESP3D [ESP410] format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# ESP3D [ESP410] format

This command list all AP available, limited to 30 by API, if signal is too low, AP is not listed to avoid connection problems.

WebUI need use json format to get propelry formated answer
As described in Commands.md:

Example
`[ESP410]json`
you will get the following if ok

```
{
"cmd": "410",
"status": "ok",
"data": [
{
"SSID": "GRBL",
"SIGNAL": "100",
"IS_PROTECTED": "1"
},
{
"SSID": "luc-ext1",
"SIGNAL": "64",
"IS_PROTECTED": "1"
},
{
"SSID": "TP-Link_Luc",
"SIGNAL": "62",
"IS_PROTECTED": "1"
}
]
}
```
121 changes: 121 additions & 0 deletions Memo/ESP3D [ESP800] format.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# ESP3D [ESP800] format

can be in JSON or plain text

## Input

`[ESP800]<time=YYYY-MM-DDTHH:mm:ss> <version=3.0.0-a11> <setup=0/1> json=<no> pwd=<admin password>`

* json=yes
the output format
* time=
to set ESP3D time using ISO 8601 format : `YYYY`-`MM`-`DD`T`HH`:`minutes`:`seconds`
* tz=
to set ESP3D time zone using ISO 8601 format : `+`/`-` `HH`:`MM`
* version
version of webUI
* setup flag
Enable / Disable the setup flag

## Output

- In json format

```
{
"cmd":"800",
"status":"ok",
"data":{
"FWVersion":"bugfix-2.0.x-3.0.0.a200",
"FWTarget":"marlin",
"FWTargetID":"30",
"Setup":"Enabled",
"SDConnection":"shared",
"SerialProtocol":"Socket",
"Authentication":"Disabled",
"WebCommunication":"Synchronous",
"WebSocketIP":"192.168.2.117",
"WebSocketPort":"81",
"Hostname":"esp3d",
"WiFiMode":"STA",
"WebUpdate":"Enabled",
"FlashFileSystem":"LittleFS",
"HostPath":"www",
"Time":"none"
}
}
```

* `cmd`
Id of requested command, should be `800`

* `status`
status of command, should be `ok`

* `data`
content of response:
* `FWVersion`
Version of ESP3D firmware or targeted FW (Marlin with ESP3DLib / grblHal)
* `FWTarget`
name of targeted Firmware
* `FWTargetID`
numerical ID of targeted FW as same name can have several Ids
* `Setup`
Should be `Enabled` or `Disabled` according flag in EEPROM/Preferences, this allows to WedUI to start wizard automaticaly (or not)

* `SDConnection`
This is SD capability, SD can be
* `shared`
ESP does share access to SD card reader with main board or Firmware (Marlin with ESP3Dlib, ESP3D with hardware SD share solution)
* `direct`
ESP does have direct access to SD card reader (e.g: ESP3D, grblHal)
* `none`
ESP does not have direct access to SD card reader, (e.g: ESP3D with only serial connection)
* `SerialProtocol`
It define how ESP3D FW communicate with main FW
* `Socket`
ESP and main FW use same FW (e.g: Marlin with ESP3DLib, grblHal)
* `Raw`
Classic serial connection
* `MKS`
Serial connection using MKS protocol
* `Authentication`
Can be `Enabled` or `Disabled`
* `WebCommunication`
currently only `Synchronous`, because `Asychronous` has been put in hold
* `WebSocketIP`
Ip address for the websocket terminal `192.168.2.117`
* `WebSocketPort`
Port for the web socket terminal `81`
* `Hostname`
Hostname of ESP3D or main Baord `esp3d`
* `WiFiMode`
Current wiFi mode in use can be `AP` or `STA`
* `WebUpdate`
Inform webUI the feature is available or not, can be `Enabled` or `Disabled`
* `FlashFileSystem` (currently `FileSystem`, to be updated soon )
The file system used by ESP board can be `LittleFS`, `SPIFFS`, `Fat`, `none`
* `HostPath`
Path where the preferences.json and index.html.gz are stored and can be updated (e.g: `www`)
* `Time`
Type of time support
* `none`
Time is not supported
* `Auto`
Board use internet to sync time and it is successful
* `Failed to set`
Board use internet to sync time and it is failed
* `Manual`
Board use time of ESP800 to set the time and it is successful
* `Not set`
Board use time of ESP800 to set the time and command did not sent it (time may have been set by previous command)
* `CameraID`
if ESP has camera it contain the camera ID
* `CameraName`
if ESP has camera it contain the camera name
* `Axisletters`
Currently only used for grbHAL
can be :
- XYZABC
- XYZUVZ (supported soon)
- XYZABCUVZ (supported soon)
Binary file added Memo/ESP3D-WebUI-features.xls
Binary file not shown.
76 changes: 76 additions & 0 deletions Memo/Features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
# V3 Features

## Global Features

- Firmware update
- WebUI update
- List of enabled features /capabilities
- Wifi configuration
- Features configuration
- WebUI features configuration
- Haptic feedback
- Audio feedback
- Terminal commands
- Emmergency stop
- Pluggins support
- Themes support (CSS)
- Language packs support
- Macro commands
- Local FS listing / content management
- External pages/panel support
- PC / Tablet / phone UI
- IP Camera & ESP32 Camera display support
- Import / Export settings
- Restart board support
- Monolitic small footprint
- Single user management support (auto close if not latest connected)
- Authentication support (admin / user)
- Configuration wizard (TBD)
- Firmware supported (3DPrinter / CNC / SandTable):
- ESP3D V3.x:
- Marlin (1.x / 2.x)
- Smoothieware (1.x / 2.x)
- Repetier (1.x / 2.x)
- GRBL (1.1h)
- ESP3D-TFT (ESP3D)
- ESP3DLib
- Marlin (2.x) - currently need custom version of Marlin : https://github.com/luc-github/Marlin/tree/ESP3DLibV3.0
- grblHAL (ongoing)
- Makerbase TFT (ESP3D)
- Bigtreetech TFT (ESP3D)
- Firmware NOT yet supported:
- Reprap

## 3D Printer Features

- Target firmware configuration
- Jog control / monitoring
- Temperatures control / monitoring
- Additionnal sensors support
- Chart support for temperatures / sensors
- Multiple extruder support
- Target Firmware SD listing / content management (if supported)
- TFT SD/USB listing / content management (if supported)
- Fan control / monitoring (if supported)
- Flow rate control / monitoring (if supported)
- Feed rate control / monitoring (if supported)
- Print control / monitoring
- More to come...

## CNC Features

- Target firmware configuration
- Jog control / monitoring
- Laser control
- Spindle control
- Status monitoring
- Probing control / monitoring
- Code streaming using ESP3D V3
- More to come...

## Sand Table Features

- Target firmware configuration
- Jog control / monitoring
- Status monitoring
- More to come...
175 changes: 175 additions & 0 deletions Memo/Handlers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Web Handlers

### /

root is the default handler where all files will be served, if no file is defined, it looks for index.html or index.html.gz (compressed)
if you call specific file, it will look for the filename and filename.gz (compressed)
if no file is defined and there is not index.html(.gz) it will display embedded page
another way to show the embedded page is /?forcefallback=yes

### /sd/

it will serve any file from SD card if there is one, it is only a wrapper to read SD card, no upload

### /files

this handler handle all commands for FS, including upload on FS.
possible options/arguments are:

- `quiet=yes` can be used when you don't want list files but just upload them
- `path=...` define the path to the file
- `action=...` define the action to execute which can be:
- delete
delete the file defined by `filename=...` it will also use `path=...` to do full path
- deletedir
delete the directory defined by `filename=...` it will also use `path=...` to do full path
- createdir
create the directory defined by `filename=...` it will also use `path=...` to do full path
- `createPath=yes` when doing upload and the path do not exists, it will create it, POST only
- `<filename>S=...` give the size of uploaded file with <filename> name, need to be set before file is set in upload, POST only

the output is a json file:

```
{
"files":[ //the files list
{
"name":"index.html.gz", //the name of the file
"size":"83.46 KB", //the formated size of the file
"time":"2022-09-04 11:56:05" //the time when the file was modified last time, this one is optional and depend on (FILESYSTEM_TIMESTAMP_FEATURE)
},
{
"name":"subdir", //the name of the file / directory
"size":"-1", //the size is -1 because it is a directory
"time":"" //no time for directories optional as depend on (FILESYSTEM_TIMESTAMP_FEATURE)
}
],
"path":"/", //current path
"occupation":"52", //% of occupation
"status":"subdir created", //status
"total":"192.00 KB", //Formated total space of Filesystem
"used":"100.00 KB" //Formated used space of Filesystem
}
```

### /sdfiles

this handler handle all commands for SD, including upload on SD (only shared and direct SD)
this handler handle all commands for FS, including upload on FS.
possible options/arguments are:

- `quiet=yes` can be used when you don't want list files but just upload them
- `path=...` define the path to the file
- `action=...` define the action to execute which can be:
- list
Will refresh the stats of the files - delete
delete the file defined by `filename=...` it will also use `path=...` to do full path
- deletedir
delete the directory defined by `filename=...` it will also use `path=...` to do full path
- createdir
create the directory defined by `filename=...` it will also use `path=...` to do full path
- `createPath=yes` when doing upload and the path do not exists, it will create it, POST only
- `<filename>S=...` give the size of uploaded file with <filename> name, need to be set before file is set in upload, POST only

the output is a json file:

```
{
"files":[ //the files list
{
"name":"3Oc-pika2.gco",//the name of the file
"shortname":"3Oc-pika2.gco", //the 8.3 shortname if available, if not the name of the file
"size":"83.46 KB", //the formated size of the file
"time":"2022-09-04 11:56:05" //the time when the file was modified last time, this one is optional and depend on (SD_TIMESTAMP_FEATURE)
},
{
"name":"subdir", //the name of the file / directory
"size":"-1", //the size is -1 because it is a directory
"time":"" //no time for directories optional as depend on (SD_TIMESTAMP_FEATURE)
}
],
"path":"/", //current path
"occupation":"52", //% of occupation
"status":"subdir created", //status
"total":"192.00 KB", //Formated total space of Filesystem
"used":"100.00 KB" //Formated used space of Filesystem
}
```

### /upload

this handler is for MKS boards using MKS communication protocol if enabled, it handle only upload on SD

### /command

this handler is for all commands the parameter is `cmd=...`
if it is an `[ESPXXX]` command the answer is the `[ESPXXX]` response
if it is not an `[ESPXXX]` command the answer is `ESP3D says: command forwarded` and can be ignored

### /login

this handler is for authentication function if enabled
possible options/arguments are:
- `DISCONNECT=YES`
it will clear current session, remove authentication cookie, set status to `disconnected` and response code to 401 - `SUBMIT=YES`
to login it will need also `PASSWORD=...` and `USER=...`, the answer will be 200 if success and 401 if failed
if user is already authenticated it can use `NEWPASSWORD=...` instead of `PASSWORD=...` to change his password, if successful answer will be returned with code 200, otherwise code will be 500 if change failed or if password format is invalid

Output:

- if authentified and no submission:
`{"status":"Identified","authentication_lvl":"admin"}` and code 200
- if not authenticated and no submission:
`{"status":"Wrong authentication!","authentication_lvl":"guest"}` and code 401

### /config

this handler is a shortcut to [ESP420] command in text mode, to get output in json add `json=yes`

### /updatefw

this handler is for FW upload and update
Answer output is :
`{"status":"..."}` if upload is successful the ESP will restart

### /snap

this handler is on esp32cam with camera enabled to capture a Frame
it answer by sending a jpg image

### /description.xml

this handler is for SSDP if enabled to present device informations

```
<root xmlns="urn:schemas-upnp-org:device-1-0">
<specVersion>
<major>1</major>
<minor>0</minor>
</specVersion>
<URLBase>http://192.168.2.178:80/</URLBase>
<device>
<deviceType>urn:schemas-upnp-org:device:upnp:rootdevice:1</deviceType>
<friendlyName>esp3d</friendlyName>
<presentationURL>/</presentationURL>
<serialNumber>52332</serialNumber>
<modelName>ESP Board</modelName>
<modelDescription/>
<modelNumber>ESP3D 3.0</modelNumber>
<modelURL>https://www.espressif.com/en/products/devkits</modelURL>
<manufacturer>Espressif Systems</manufacturer>
<manufacturerURL>https://www.espressif.com</manufacturerURL>
<UDN>uuid:38323636-4558-4dda-9188-cda0e600cc6c</UDN>
<serviceList/>
<iconList/>
</device>
</root>
```

### Captive portal bypass handlers

to avoid a redirect to index.html and so a refresh of the page, some classic handler have been added so they all go to / handler actually

- /generate_204
- /gconnectivitycheck.gstatic.com
- /fwlink/
16 changes: 16 additions & 0 deletions Memo/Notes.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
* Fix dev websocket server cannot work under Linux
> sudo apt-get install libcap2-bin
> sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

* Fix ‘ and “ need space to be displayed under Linux
> setxkbmap -layout us

* Fix for sass div warning
>npm install -g sass-migrator
>sass-migrator division **/*.scss
Note:
on windows need change script policy first:
> Get-ExecutionPolicy -List
>Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
then when done, put back default (the one got by initial Get-ExecutionPolicy -List)
>Set-ExecutionPolicy -ExecutionPolicy Restricted -Scope CurrentUser
20 changes: 20 additions & 0 deletions Memo/TargetFW.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Firmware names, ids, usages

- grblhal
grblhal -80 - grblHAL Fw
- reprap
reprap -70 - NA
- fluidnc
fluidnc -60 - NA
- repetier
repetier - 50 - ESP3D Fw
- smoothieware
smoothieware- 40 - ESP3D Fw
- marlin_embedded
marlin - 30 - ESP3DLib/Marlin
- marlin
marlin - 20 - ESP3D Fw
- grbl
grbl - 10 - ESP3D Fw
- unknown
unknown - 0 - ESP3D Fw
Binary file added Memo/data structure.odt
Binary file not shown.
62 changes: 62 additions & 0 deletions Memo/languagepack.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# Language packs

## Generate template files

Use the script `npm run template` to geenrate up todate template files for all packs

Currently:

- CNC GRBL in `languages/cncgrblpack`
- CNC grblHAL `languages/cncgrblhalpack`
- 3D Printers (all) `languages/printerpack`
- Sand Table (all) `languages/sandtablepack`

## Generate language pack files

- Rename the template file according the language code http://www.lingoes.net/en/translator/langcode.htm using `_` instead of `-` and add `lang-` in from of name.
so for example :

- for french language pack, `en.json` file would be renamed to `lang-fr.json`
- for simplified chinese language pack, `en.json` file would be renamed to `lang-zh_cn.json`
- for simplified chinese language pack, `en.json` file would be renamed to `lang-zh_cn.json`
- for german language pack, `en.json` file would be renamed to `lang-de.json`

- Modify the language pack file according to the language and test it against the WebUI

- Compress the final pack
use the following command to compress the final pack targeting the file :
`npm run package target=languages/<target pack>/lang-<target language>.json`

so for French language pack for example:
`npm run package target=languages/printerpack/lang-fr.json`

## Compare template pack with language pack file

This script is used to compare current language pack content against the template language pack to see if the language pack need to be updated.

`npm run check reference=<template path file> target=<not compressed language pack>`

```
npm run check target=languages/printerpack/lang-fr.json reference=languages/printerpack/en.json
> ESP3D-WEBUI@3.0.0 check
> node ./config/checkpack.js "target=languages/printerpack/lang-fr.json" "reference=languages/printerpack/en.json"
Comparing files
Checking extra entries...
S724 : Fermer l'application
...done, found 1 extra entries
Checking missing entries...
S14 : Settings
S24 : Close
...done, found 2 missing entries
Comparaison done
```

## Propose / update language pack files

Please do a PR to webUI 3.0 github branch or submit ticket with compressed and clear version of the language pack file
if submitting PR please keep the clear version in `languages/<target pack>` and compressed version in `dist/<target pack>`
796 changes: 796 additions & 0 deletions Memo/preferences.md

Large diffs are not rendered by default.

133 changes: 133 additions & 0 deletions Memo/realtimecmd.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
# Real time commands variables

## grbl

- 0x18 (ctrl-x) : Soft-Reset : #SOFTRESET#
- 0x84 : Safety Door #SAFETYDOOR#
- 0x85 : Jog Cancel #JOGCANCEL#

Feed Overrides

- 0x90 : Set 100% of programmed rate. #FO100#
- 0x91 : Increase 10% #FO+10#
- 0x92 : Decrease 10% #FO-10#
- 0x93 : Increase 1% #FO+1#
- 0x94 : Decrease 1% #FO-1#

Rapid Overrides

- 0x95 : Set to 100% full rapid rate. #RO100#
- 0x96 : Set to 50% of rapid rate. #RO50#
- 0x97 : Set to 25% of rapid rate. #RO25#

Spindle Speed Overrides 10%->200%

- 0x99 : Set 100% of programmed spindle speed #SSO100#
- 0x9A : Increase 10% #SSO+10#
- 0x9B : Decrease 10% #SSO-10#
- 0x9C : Increase 1% #SSO+1#
- 0x9D : Decrease 1% #SSO-1#

Toggle commands

- 0x9E : Toggle Spindle Stop #T-SPINDLESTOP#
- 0xA0 : Toggle Flood Coolant #T-FLOODCOOLANT#
- 0xA1 : Toggle Mist Coolant #T-MISTCOOLANT#

```
[{name:"#SOFTRESET#", value:"\x18"},
{name:"#SAFETYDOOR#", value:"\x84"},
{name:"#JOGCANCEL#", value:"\x85"},
{name:"#FO100#", value:"\x90"},
{name:"#FO+10#", value:"\x91"},
{name:"#FO-10#", value:"\x92"},
{name:"#FO+1#", value:"\x93"},
{name:"#FO-1#", value:"\x94"},
{name:"#RO100#", value:"\x95"},
{name:"#RO50#", value:"\x96"},
{name:"#RO25#", value:"\x97"},
{name:"#SSO100#", value:"\x99"},
{name:"#SSO+10#", value:"\x9A"},
{name:"#SSO-10#", value:"\x9B"},
{name:"#SSO+1#", value:"\x9C"},
{name:"#SSO-1#", value:"\x9D"},
{name:"#T-SPINDLESTOP#", value:"\x9E"},
{name:"#T-FLOODCOOLANT#", value:"\xA0"},
{name:"#T-MISTCOOLANT#", value:"\xA1"}
]
```

## grblHAL

- 0x18 (ctrl-x) : Soft-Reset : #SOFTRESET#
- 0x80 : Instead of ? for requesting a real-time report #STATUSREPORT#
- 0x81 : Instead of ~ for requesting cycle start #CYCLESTART#
- 0x82 : Instead of ! for requesting feed hold "#FEEDHOLD#
- 0x83 : Request parser state report #PARSERREPORT#
- 0x84 : Safety Door #SAFETYDOOR#
- 0x85 : Jog Cancel #JOGCANCEL#
- 0x87 : Request a complete real-time report #COMPLETEREPORT#
- 0x88 : Toggle the virtual optional stop switch #T-STOPSWITCH#

Feed Overrides

- 0x90 : Set 100% of programmed rate. #FO100#
- 0x91 : Increase 10% #FO+10#
- 0x92 : Decrease 10% #FO-10#
- 0x93 : Increase 1% #FO+1#
- 0x94 : Decrease 1% #FO-1#

Rapid Overrides

- 0x95 : Set to 100% full rapid rate. #RO100#
- 0x96 : Set to 50% of rapid rate. #RO50#
- 0x97 : Set to 25% of rapid rate. #RO25#

Spindle Speed Overrides 10%->200%

- 0x99 : Set 100% of programmed spindle speed #SSO100#
- 0x9A : Increase 10% #SSO+10#
- 0x9B : Decrease 10% #SSO-10#
- 0x9C : Increase 1% #SSO+1#
- 0x9D : Decrease 1% #SSO-1#

Toggles and extras

- 0x9E : Toggle Spindle Stop #T-SPINDLESTOP#
- 0xA0 : Toggle Flood Coolant #T-FLOODCOOLANT#
- 0xA1 : Toggle Mist Coolant #T-MISTCOOLANT#
- 0xA2 : Request a PID report #PIDREPORT#
- 0xA3 : Acknowledge a tool change request #TOOLCHANGE#
- 0xA4 : Toggle the virtual optional probe connected switch #T-PROBE#

```
{ name: "#SOFTRESET#", value: "\x18" },
{ name: "#STATUSREPORT#", value: "\x80"},
{ name: "#CYCLESTART#", value: "\x81" },
{ name: "#FEEDHOLD#", value: "\x82" },
{ name: "#PARSERREPORT#", value: "\x83" },
{ name: "#SAFETYDOOR#", value: "\x84" },
{ name: "#JOGCANCEL#", value: "\x85" },
{ name: "#COMPLETEREPORT#", value: "\x87" },
{ name: "#T-STOPSWITCH#", value: "\x88" },
{ name: "#FO100#", value: "\x90" },
{ name: "#FO+10#", value: "\x91" },
{ name: "#FO-10#", value: "\x92" },
{ name: "#FO+1#", value: "\x93" },
{ name: "#FO-1#", value: "\x94" },
{ name: "#RO100#", value: "\x95" },
{ name: "#RO50#", value: "\x96" },
{ name: "#RO25#", value: "\x97" },
{ name: "#SSO100#", value: "\x99" },
{ name: "#SSO+10#", value: "\x9A" },
{ name: "#SSO-10#", value: "\x9B" },
{ name: "#SSO+1#", value: "\x9C" },
{ name: "#SSO-1#", value: "\x9D" },
{ name: "#T-SPINDLESTOP#", value: "\x9E" },
{ name: "#T-FLOODCOOLANT#", value: "\xA0" },
{ name: "#T-MISTCOOLANT#", value: "\xA1" },
{ name: "#PIDREPORT#", value: "\xA2" },
{ name: "#TOOLCHANGE#", value: "\xA3" },
{ name: "#T-PROBE#", value: "\xA4" },
];
```
38 changes: 38 additions & 0 deletions Memo/sizetracker.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@

printer(Marlin) size in 3.0 (Marlin)
Base code : 3.0.0.a1 : 21.2KB | | 27KB
WS/Http/Auth/Menu : 3.0.0.a2 : 28.4KB | | 34.15KB
Icons & Mobile view : 3.0.0.a3 : 29.8KB | |
UI update : 3.0.0.a4 : 30.6KB | | 35.7KB
Features : 3.0.0.a5 : 36KB | | 41.2KB
Interface : 3.0.0.a6 : 36.6KB | | 42KB
UI language pack : 3.0.0.a7 : 37.3KB | | 42.6KB
Theme pack : 3.0.0.a8 : 37.5KB | | N/A
Extra Panels / Macros / : : | |
Terminal : 3.0.0.a.12 : 50.4KB | | 42.6KB + 10.2KB + 1.1KB = 53.9KB
File panel : 3.0.0.a.13 : 53.3KB | | 53.9KB + 3.2KB = 57.1KB
Code Refactoring : 3.0.0.a.14 : 53.0KB | | 53.9KB + 3.2KB = 57.1KB
Machine Settings + Audio : 3.0.0.a.15 : 54.7KB | | 57.1KB + 3.7KB = 58.8KB
Machine Settings(1 btn save): 3.0.0.a.16 : 55.0KB | | 58.8KB
Jog Panel : 3.0.0.a.17 : 61.2KB | | 58.8KB+9.4KB = 68.1KB
Temperature Panel + : : | |
notifications : : 68.6KB | | 68.1 + 4.1 + 4.6= 76.8KB
Extruders Panel : : 70.2KB | | 76.8 + 4.5 = 81.3KB
Charts Panel : : 75.0KB | | 81.3 + 6.2 = 87.5KB
Extra controls Panel : : 78.3KB | | 87.5 + 3.6 = 91.1KB
Print status : : 78.5KB | | 91.1 + 0.6 = 91.4Kb
Mixed extruder bug fixes : : | |
Variables API : : | |
Multiples Commands bug fix : : | |
ProgressBar bug fix : : | |
Libraries version bump : : | |
More dependcies allowed : : | |
Add Color in notifications : : | |
Extra SD for ESP32Cam : : 81.2KB | |
Panels fixed order : : 82.2KB | |


grbl size in 3.0
Base code : 3.0.0.a1 : 21.2KB | | 27KB
CNC UI : : 74.1KB | | 91.4Kb
Panels fixed order : : 74.8KB | |
23 changes: 23 additions & 0 deletions Memo/variablesList.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Variables list

- From output:

- [PRB:0.000,0.000,0.000:0]
#prb_x#, #prb_y#,#prb_z#
optional according axis definition #prb_a#,#prb_b#,#prb_c#

- from ? report MPos:0.000,0.000,0.000,0.000,0.000,0.000
#pos_x#, #pos_y#, #pos_z#, #pos_a#, #pos_b#, #pos_c#,
#pos_wx#, #pos_wy#, #pos_wz#, #pos_wa#, #pos_wb#, #pos_wc#,
optional according axis definition #pos_u#,#pos_v#,#pos_w#, #pos_wu#,#pos_wv#,#pos_ww#

Note: if variable is unknown, then it is set to `0`

- From UI

- Probe Panel
Probe thickness : #probe_thickness#
Selected axis : #selected_axis#

- Laser CNC Panel
Maximum value of laser: #laser_max#
68 changes: 68 additions & 0 deletions Memo/websocket.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# Websocket

there are 2

- terminal websocket
used to stream data to webUIand exchange internal data

- data websocket
used to exchange data

## Terminal websocket

subprotocol: `webui-v3`

port: webport number + 1

### <u>text mode</u>

Reserved
messages between webui / ESP
Format: `<label>:<message>`

- from ESP to WebUI

- `currentID:<id>`
Sent when client is connecting, it is the last ID used and become the active ID

- `activeID:<id>`
Broadcast current active ID, when new client is connecting, client without this is <id> should close, ESP WS Server close all open WS connections but this one also

- `PING:<time left>:<time out>`
It is a response to PING from client to inform the time left if no activity (see below)

- `ERROR:<code>:<message>`
If an error raise when doing upload, it informs client it must stop uploading because sometimes the http answer is not possible,
or cannot cancel the upload, this is a workaround as there is no API in current webserver to cancel active upload

- `NOTIFICATION:<message>`
Forward the message sent by [ESP600] to webUI toast system

- `SENSOR: <value>[<unit>] <value2>[<unit2>] ...`
The sensor connected to ESP like DHT22

- from WebUI to ESP
- `PING:<current cookiesessionID / none >` if any, or "none" if none

### <u>binary mode</u>

Reserved

- from ESP to WebUI
stream data from ESP to WebUI

- from WEBUI to ESP
[-> File transfert from WebUI to ESP : not implemented yet]

## Data websocket

protocol: `arduino`
port: configurable in settings

### <u>text mode</u>

Free to use

### <u>binary mode</u>

Free to use
161 changes: 79 additions & 82 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,79 @@
# ESP3D-WEBUI
[Latest stable release ![Release Version](https://img.shields.io/github/v/release/luc-github/ESP3D-WEBUI?color=green&include_prereleases&style=plastic) ![Release Date](https://img.shields.io/github/release-date/luc-github/ESP3D-WEBUI.svg?style=plastic)](https://github.com/luc-github/ESP3D-WEBUI/releases/latest/) ![Travis (.org) branch](https://img.shields.io/travis/luc-github/ESP3D-WEBUI/2.1?style=plastic)

[Latest development version ![Development Version](https://img.shields.io/badge/Devt-v3.0-yellow?style=plastic) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/luc-github/ESP3D-WEBUI/3.0?style=plastic)](https://github.com/luc-github/ESP3D-WEBUI/tree/3.0) ![Travis (.org) branch](https://img.shields.io/travis/luc-github/ESP3D-WEBUI/3.0?style=plastic)

## What is that ?
A web configuration tool for ESP3D 2.1
Originaly based on great UI from Jarek Szczepanski (imrahil): [smoothieware-webui](http://imrahil.github.io/smoothieware-webui/) to get a multi firmware support for [Repetier](https://github.com/repetier/Repetier-Firmware), [Repetier for Davinci printer](https://github.com/luc-github/Repetier-Firmware-0.92), (Marlin)[https://github.com/MarlinFirmware], [Marlin Kimbra](https://github.com/MagoKimbra/MarlinKimbra) and of course [Smoothieware](https://github.com/Smoothieware/Smoothieware)

## Why doing it ?
Original I ported [smoothieware-webui](http://imrahil.github.io/smoothieware-webui/) to support [ESP3D firmware](https://github.com/luc-github/ESP3D) and it was working pretty well and gave :[smoothieware-webui-for-ESP3D](https://github.com/luc-github/smoothieware-webui-for-ESP3D)
But this UI has a 2 big limitations:
1 - you need internet access to get all libraries available to download, which may not happen when ESP is in AP mode for configuration if you do not have all js/css in your browser cache, or if you want to use in local environement, in that case not only ESP AP mode is not displaying UI properly but also STA mode - so it make the ESP useless

2 - it rely on server availability and certificat check, I got several certificat failure for unknown reason that made the UI not working

So the solution was to make all resources available - easy no ?

Yes but! ESP webserver is a convenient but it is also a very light webserver, allowing no more than 5 active connections at once and with a pretty limited filesystem space, so even concatenated all resources like bootstrap icon, angular and others libraries do not work as expected and do not fit the available space.

So I came with a full rewrite using pure javascript and resized resources:
1 - a compressed css based on [bootstrap](http://getbootstrap.com/css/)
2 - a local limited version of svg based of [Glyphicons Halflings](http://glyphicons.com/) to get a small footprint.
3 - a customized version of [smoothiecharts](http://smoothiecharts.org/) is used to display temperatures charts, it is simple and perfectly sized for the current purpose

and the result is a monolitic file with a size less than 70Kb allowing almost full control of ESP3D board and your 3D printer

## Features
- It supports several firmwares based on Repetier, Marlin and Smoothieware.
- It allows to fully configure ESP wifi
- It has a macro support to add custom commands in UI by adding buttons launching some GCODE files from SD or ESP
- It supports currently English, French, German (thanks @leseaw) and Spanish languages
- It allows to display a web camera in UI or detached
- It allows to edit the Repetier EEPROM, Smoothieware config file, Marlin and GRBL settings
- It allows to update the ESP3D by uploading the FW
- it allows to control and monitor your 3D printer in every aspect (position, temperature, print, SD card content, custom command

Please look at screenshots:
Main tab and menu:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Full1.PNG'/>
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Full2.PNG'/>
Control panel:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/controls.PNG'/>
Macro dialog:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Macro.PNG'/>
Temperatures panel:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/temperatures.PNG'/>
Extruder panel:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/esxtruders.PNG'/>
SD card panel:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/SD1.PNG'/>
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/SD1.5.PNG'/>
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/SD2.PNG'/>
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/SD-Dir.PNG'/>
Camera Tab:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Camera.PNG'/>
Repetier EEPROM Editor tab:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Repetier.PNG'/>
Smoothieware config Editor tab:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/smoothieware.PNG'/>
Marlin config Editor tab:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/Marlin.PNG'/>
GRBL config Editor tab:
<img src='https://user-images.githubusercontent.com/8822552/37540735-60bada08-2958-11e8-92ee-69aee4b83e7a.png'/>
ESP3D settings Editor:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/ESP3D1.PNG'/>
ESP3D Status:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/status.PNG'/>
ESP3D SPIFFS:
<img src='https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/master/images/SPIFFS.PNG'/>


## Installation
Please use the latest [ESP3D firmware](https://github.com/luc-github/ESP3D/tree/2.1) and copy the index.html.gz file on root of SPIFFS, in theory ESP3D have a version of web-ui but it may not be the latest one

## Contribution / development
Check wiki section [Contribution/Development](https://github.com/luc-github/ESP3D-WEBUI/wiki/Compilation---Development)

## Issues / Questions
You can submit ticket [here](https://github.com/luc-github/ESP3D-WEBUI/issues)


# ESP3D-WEBUI 3.0 ![ESP3D-WEBUI](https://img.shields.io/badge/dynamic/json?label=ESP3D-WEBUI&query=$.version&url=https://raw.githubusercontent.com/luc-github/ESP3D-WEBUI/refs/heads/3.0/info.json)

using Preact per @aganov suggestion
Rewrite per @alxblog suggestion to use proper Preactjs API and lighter css code: use spectre.css instead of bootstrap 4.x

## Beta stage / Ready to test

Only compatible with [ESP3DLib 3.0](https://github.com/luc-github/ESP3DLib/tree/3.0) , [ESP3D 3.0](https://github.com/luc-github/ESP3D/tree/3.0), [grblHAL](https://github.com/grblHAL), [ESP3D_TFT 1.0](https://github.com/luc-github/ESP3D-TFT/tree/main)

[Latest development version ![Development Version](https://img.shields.io/badge/Devt-v3.0-yellow?style=plastic)](https://github.com/luc-github/ESP3D-WEBUI/tree/3.0) ![GitHub last commit (branch)](https://img.shields.io/github/last-commit/luc-github/ESP3D-WEBUI/3.0?style=plastic) [![github-ci](https://github.com/luc-github/ESP3D-WeBUI/workflows/build-ci/badge.svg)](https://github.com/luc-github/ESP3D-WEBUI/actions/workflows/build-ci.yml) [![Project Page ESP3D 3.0](https://img.shields.io/badge/Project%20page-ESP3D%203.0-blue?style=plastic)](https://github.com/users/luc-github/projects/1/views/1)

> [!WARNING]
>### Disclaimer
> The software is provided 'as is,' without any warranty of any kind, expressed or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose, and non-infringement. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability, whether in an action of contract, tort, or otherwise, arising from, out of, or in connection with the software or the use or other dealings in the software.
>It is essential that you carefully read and understand this disclaimer before using this software and its components. If you do not agree with any part of this disclaimer, please refrain from using the software.
### Setup development tools

1 - Install current nodejs LTS (currently using v20.8.0)

```
node -v
v20.8.0
npm -v
10.2.0
```

2 - Download all necessary packages in ESP3D-WEBUI directory (repository root)

```
npm install
```

### Start dev server

in ESP3D-WEBUI directory (repository root)

```
npm run dev-<system>-<firmware>
```

- where `<system>` is `cnc` (CNC system, laser, spindle..) , `printer` (3D printer), `sand` (Sand Table)
- where `<firmware>` is :
- `grbl`, `grblhal` for `cnc`
- `marlin`, `marlin-embedded` (esp3dlib), `repetier`, `smoothieware` for `printer`
- `grbl` for `sand`

will open http://localhost:8088 which display the webUI using a local test server

### Build index.html.gz to /dist folder

in ESP3D-WEBUI directory (repository root)

```
npm run buildall
```

Will generate production version for each target and firmware in dist directory

to build specific index.html.gz

```
npm run <system>-<firmware>
```

- where `<system>` is `cnc` (CNC system, laser, spindle..) , `printer` (3D printer), `sand` (Sand Table)
- where `<firmware>` is :
- `grbl`, `grblhal` for `cnc`
- `marlin`, `marlin-embedded` (esp3dlib), `repetier`, `smoothieware` for `printer`
- `grbl` for `sand`

# Chat

ESP3D is now on discord https://discord.gg/Z4ujTwE

# Need more information ESP3D-WEBUI and ESP3D related projects ?

Go to https://esp3d.io
3 changes: 0 additions & 3 deletions build.bat

This file was deleted.

33 changes: 0 additions & 33 deletions buildLanguagePacks.bat

This file was deleted.

135 changes: 135 additions & 0 deletions config/buildtemplate.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
/*
buildtemplate.js - ESP3D WebUI package file
Copyright (c) 2021 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
const chalk = require("chalk")
const path = require("path")
const fs = require("fs")
const { Console } = require("console")
const targetPath = path.normalize(__dirname + "/../languages/")
const readable = true // process.argv.length == 3 && process.argv[2] == "readable" ? true : false

const cncgrblpack = [
{ id: "globals", path: "src/targets/translations/en.json" },
{
id: "CNC",
path: "src/targets/CNC/translations/en.json",
},
{
id: "GRBL",
path: "src/targets/CNC/GRBL/translations/en.json",
},
]
const cncgrblhalpack = [
{ id: "globals", path: "src/targets/translations/en.json" },
{
id: "CNC",
path: "src/targets/CNC/translations/en.json",
},
{
id: "grblHAL",
path: "src/targets/CNC/grblHAL/translations/en.json",
},
]
const printerpack = [
{ id: "globals", path: "src/targets/translations/en.json" },

{
id: "printers3D",
path: "src/targets/Printer3D/translations/en.json",
},
{
id: "Marlin",
path: "src/targets/Printer3D/Marlin/translations/en.json",
},
{
id: "Marlin-embedded",
path: "src/targets/Printer3D/Marlin-embedded/translations/en.json",
},
{
id: "Repetier",
path: "src/targets/Printer3D/Repetier/translations/en.json",
},
{
id: "Smoothieware",
path: "src/targets/Printer3D/Smoothieware/translations/en.json",
},
]
const sandtablepack = [
{ id: "globals", path: "src/targets/translations/en.json" },
{
id: "SandTable",
path: "src/targets/SandTable/translations/en.json",
},
{
id: "GRBL",
path: "src/targets/SandTable/GRBL/translations/en.json",
},
]

const processList = [
{ targetPath: "cncgrblpack", files: cncgrblpack },
{ targetPath: "cncgrblhalpack", files: cncgrblhalpack },
{ targetPath: "printerpack", files: printerpack },
{ targetPath: "sandtablepack", files: sandtablepack },
]
if (readable) console.log(chalk.green("Processing in readable mode"))
else console.log(chalk.green("Processing in production mode"))
processList.map((element) => {
let resultfile = {}

const finalFilePath = path.join(targetPath, element.targetPath)
console.log(chalk.green("Starting to merge:", element.targetPath))
element.files.forEach((item) => {
console.log(chalk.green("Processing:", item.id))
const sourcepath = path.normalize(__dirname + "/../" + item.path)
const file = fs.readFileSync(sourcepath, "UTF-8")
const currentFile = JSON.parse(file.toString())
Object.keys(currentFile).map((key) => {
if (!resultfile[key] && typeof currentFile[key] != "undefined") {
resultfile[key] = currentFile[key]
} else {
if (resultfile[key] != currentFile[key]) {
console.log(chalk.red("In " + sourcepath))
console.log(
chalk.red(
key,
":" + currentFile[key] + " vs " + resultfile[key]
)
)
} else {
console.log(
chalk.yellow(
"Ignoring duplicate: " + key,
"=" + currentFile[key]
)
)
}
}
})
})
fs.mkdirSync(finalFilePath, { recursive: true })
console.log(
chalk.green("Saving result to :" + path.join(finalFilePath, "en.json"))
)
fs.writeFileSync(
path.join(finalFilePath, "en.json"),
JSON.stringify(resultfile, "", readable ? " " : ""),
"UTF-8"
)
})

console.log(chalk.green("Processing done"))
108 changes: 108 additions & 0 deletions config/checkpack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
chekpack.js - ESP3D WebUI package file
Copyright (c) 2021 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
const chalk = require("chalk")
const path = require("path")
const fs = require("fs")
const { exit } = require("process")
//const targetPath = path.normalize(__dirname + "/../languages/")
let referencePath = ""
let targetPath = ""

function raiseError() {
console.log(chalk.red("Invalid parameters, please use:"))
console.log(
chalk.yellow(
"npm run check reference=<template path file> target=<not compressed language pack>"
)
)
exit(0)
}

if (process.argv.length == 4) {
if (process.argv[2].startsWith("reference=")) {
referencePath = process.argv[2].replace("reference=", "")
}
if (process.argv[2].startsWith("target=")) {
targetPath = process.argv[2].replace("target=", "")
}
if (process.argv[3].startsWith("reference=")) {
referencePath = process.argv[3].replace("reference=", "")
}
if (process.argv[3].startsWith("target=")) {
targetPath = process.argv[3].replace("target=", "")
}
if (referencePath.length == 0 || targetPath == 0) {
raiseError()
}
} else {
raiseError()
}
let count = 0
const referenceFile = path.join(
path.normalize(__dirname + "/../"),
referencePath
)
const targetFile = path.join(path.normalize(__dirname + "/../"), targetPath)

if (!fs.existsSync(referenceFile)) {
console.log(chalk.red("Cannot open:"))
console.log(chalk.yellow(referenceFile))
exit(0)
}

if (!fs.existsSync(targetFile)) {
console.log(chalk.red("Cannot open:"))
console.log(chalk.yellow(targetFile))
exit(0)
}
console.log(chalk.cyan("Comparing files"))
const fileTarget = JSON.parse(fs.readFileSync(targetFile, "UTF-8").toString())
const fileReference = JSON.parse(
fs.readFileSync(referenceFile, "UTF-8").toString()
)
console.log("")
console.log(chalk.green("Checking extra entries..."))
Object.keys(fileTarget).map((key) => {
if (typeof fileReference[key] == "undefined") {
console.log(chalk.yellow(key + " : " + fileTarget[key]))
count++
}
})
console.log(
chalk.green(
"...done, found ",
count ? chalk.yellow(count + " extra entries") : ""
)
)
count = 0
console.log("")
console.log(chalk.green("Checking missing entries..."))
Object.keys(fileReference).map((key) => {
if (typeof fileTarget[key] == "undefined") {
count++
console.log(chalk.red(key + " : " + fileReference[key]))
}
})
console.log(
chalk.green(
"...done, found ",
count ? chalk.red(count + " missing entries") : ""
)
)
console.log("")
console.log(chalk.cyan("Comparaison done"))
89 changes: 89 additions & 0 deletions config/pack.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/*
package.js - ESP3D WebUI package file
Copyright (c) 2021 Luc Lebosse. All rights reserved.
This code is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with This code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
const chalk = require("chalk")
const path = require("path")
const fs = require("fs")
const { Compress } = require("gzipper")
const minify = require("html-minifier").minify
const { exit } = require("process")
console.log(chalk.cyan("Running Package 1.0"))
//Sanity check for command line
const arg = process.argv[process.argv.length > 1 ? 2 : 0]
if (process.argv.length < 3 || !arg.startsWith("target=")) {
console.log(
chalk.red(
"Error!\nSyntax: npm run package target=<relative path to file>"
)
)
exit(0)
}
//Sanity check for file creation
const sourcepath = path.normalize(
__dirname + "/../" + arg.replace("target=", "")
)
console.log("Checking ", sourcepath)
const sourcedir = path.dirname(sourcepath)
if (!fs.existsSync(sourcepath)) {
console.log(chalk.red("Error!\nCannot find file"))
exit(0)
}
//Start minify
console.log(chalk.green("Processing"))
const source = fs.readFileSync(sourcepath, "UTF-8")
const result = minify(source, {
removeComments: true,
collapseWhitespace: true,
minifyJS: true,
minifyCSS: true,
})
const minifiedFile = sourcepath + ".minified.html"
fs.writeFileSync(minifiedFile, result)
//Compress minified file
const compressedDir = sourcepath
console.log(
chalk.blue(
"Minify: " + source.length + " Bytes => ",
result.length,
"Bytes"
)
)
//it seems it is ok for css but json is not really minimified
//space are still present => Need to fix that
let gzipper = new Compress(minifiedFile, sourcedir, { verbose: true })
gzipper
.run()
.then((files) => {
//remove temp minified file
fs.unlinkSync(minifiedFile)
//rename compressed file to match original filename
fs.renameSync(minifiedFile + ".gz", sourcepath + ".gz")
const finalSize = fs.lstatSync(sourcepath + ".gz").size
//Show report
console.log(
chalk.green(
"\n\nMinify + Compression: ",
source.length,
"Bytes =>",
finalSize,
"Bytes = compression ",
(100 - 100 * (finalSize / source.length)).toFixed(2),
"%\n"
)
)
})
.catch((err) => console.error(err))
326 changes: 326 additions & 0 deletions config/server.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,326 @@
const express = require("express")
const expressStaticGzip = require("express-static-gzip")
const chalk = require("chalk")
let path = require("path")
const fs = require("fs")
const port = 8080
/*
* Web Server for development
* Web Socket server for development
*/
const wscolor = chalk.cyan
const expresscolor = chalk.green
const commandcolor = chalk.white
const WebSocket = require("ws")
let currentID = 0
const app = express()
const fileUpload = require("express-fileupload")
let sensorInterval = -1

//const serverpath = path.normalize(__dirname + "/../server/public/");

const subtarget = process.env.SUBTARGET_ENV
? process.env.SUBTARGET_ENV
: "Marlin"
const target = process.env.TARGET_ENV ? process.env.TARGET_ENV : "Printer3D"

const serverpath =
path.normalize(__dirname + "/../server/" + target + "/" + subtarget) + "/"
if (!fs.existsSync(serverpath + "Flash")) {
fs.mkdirSync(serverpath + "Flash", { recursive: true })
}
if (!fs.existsSync(serverpath + "SD")) {
fs.mkdirSync(serverpath + "SD", { recursive: true })
}

const {
commandsQuery,
configURI,
getLastconnection,
hasEnabledAuthentication,
} = require(
path.normalize(
__dirname + "/targets/" + target + "/" + subtarget + "/index.js"
)
)

const WebSocketServer = require("ws").Server,
wss = new WebSocketServer({ port: 8089 })
app.use("/", express.static(serverpath + "Flash"))
app.use("/sd", express.static(serverpath + "sd"))
app.use("/", expressStaticGzip(serverpath + "Flash"))
app.use(fileUpload({ preserveExtension: true, debug: false }))

app.listen(port, () => console.log("Env:", subtarget, ":", target))
app.timeout = 2000

//app.use(express.urlencoded({ extended: false }));

function SendWS(text, isbinary = true, isNotification = true) {
if (typeof isbinary === "undefined") isbinary = true
if (isbinary) {
const array = new Uint8Array(text.length)
for (let i = 0; i < array.length; ++i) {
array[i] = text.charCodeAt(i)
}
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(array)
}
})
} else {
const notif = (isNotification ? "NOTIFICATION:" : "") + text
console.log(wscolor("[ws] send:", notif))
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(notif)
}
})
}
}

app.post("/login", function (req, res) {
loginURI(req, res)
})

app.get("/config", function (req, res) {
configURI(req, res)
})

app.get("/command", function (req, res) {
commandsQuery(req, res, SendWS)
})

/*app.get("/sdfiles", function (req, res) {
res.status(200);
res.send(
'{"files":[{"name":"LOST.DIR","shortname":"LOST.DIR","size":"-1"},{"name":".android_secure","shortname":"ANDROI~1","size":"-1"},{"name":"app","shortname":"APP","size":"-1"},{"name":"framework","shortname":"FRAMEW~1","size":"-1"},{"name":"lib","shortname":"LIB","size":"-1"},{"name":"permissions","shortname":"PERMIS~1","size":"-1"},{"name":".Trash-1000","shortname":"TRASH-~1","size":"-1"},{"name":".FileExpert","shortname":"FILEEX~1","size":"-1"},{"name":"download","shortname":"DOWNLOAD","size":"-1"},{"name":"Android","shortname":"ANDROID","size":"-1"},{"name":".mmsyscache","shortname":"MMSYSC~1","size":"-1"},{"name":"clockworkmod","shortname":"CLOCKW~1","size":"-1"},{"name":"Evernote","shortname":"EVERNOTE","size":"-1"},{"name":"data","shortname":"DATA","size":"-1"},{"name":".estrongs","shortname":"ESTRON~1","size":"-1"},{"name":"DCIM","shortname":"DCIM","size":"-1"},{"name":"backups","shortname":"BACKUPS","size":"-1"},{"name":".zdworks","shortname":"ZDWORK~1","size":"-1"},{"name":"toolbox-stericson","shortname":"TOOLBO~1","size":"75.54 KB"},{"name":"SystemROMToolbox","shortname":"SYSTEM~1","size":"-1"},{"name":"busybox-stericson","shortname":"BUSYBO~1","size":"843.20 KB"},{"name":"recovery.img","shortname":"RECOVERY.IMG","size":"6.00 MB"},{"name":"preloader.img","shortname":"PRELOA~1.IMG","size":"128.00 KB"},{"name":"nvram.img","shortname":"NVRAM.IMG","size":"3.00 MB"},{"name":"seccnfg.img","shortname":"SECCNFG.IMG","size":"128.00 KB"},{"name":"uboot.img","shortname":"UBOOT.IMG","size":"384.00 KB"},{"name":"boot.img","shortname":"BOOT.IMG","size":"6.00 MB"},{"name":"secstatic.img","shortname":"SECSTA~1.IMG","size":"1.12 MB"},{"name":"system.img","shortname":"SYSTEM.IMG","size":"170.00 MB"},{"name":"misc.img","shortname":"MISC.IMG","size":"384.00 KB"},{"name":"cache.img","shortname":"CACHE.IMG","size":"60.00 MB"},{"name":"logo.img","shortname":"LOGO.IMG","size":"3.00 MB"},{"name":"expdb.img","shortname":"EXPDB.IMG","size":"640.00 KB"},{"name":"userdata.img","shortname":"USERDATA.IMG","size":"261.25 MB"},{"name":"recovery2.img","shortname":"RECOVE~1.IMG","size":"6.00 MB"},{"name":"touchrec.img","shortname":"TOUCHREC.IMG","size":"4.00 MB"},{"name":"restart.gcode","shortname":"RESTAR~1.GCO","size":"1 B"},{"name":"M3.G","shortname":"M3.G","size":"75 B"},{"name":"WeChat Image_20210108102318.jpg","shortname":"WECHAT~1.JPG","size":"876.47 KB"},{"name":"test.txt","shortname":"test.txt","size":"0 B"},{"name":"foo.txt","shortname":"foo.txt","size":"13 B"},{"name":"myfile.txt","shortname":"myfile.txt","size":"0 B"},{"name":"update.zip","shortname":"update.zip","size":"1.29 MB"},{"name":"luc","shortname":"luc","size":"-1"}],"path":"/","occupation":"22","status":"ok","total":"3.67 GB","used":"833.38 MB"}'
);
console.log(commandcolor(`[server]/sdfiles)`));
return;
});*/

function fileSizeString(size) {
if (size === -1) return ""
const units = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"]
let i = 0
while (size >= 1024) {
size /= 1024
++i
}
return `${size.toFixed(2)} ${units[i]}`
}

function filesList(mypath, destination) {
const currentPath = path.normalize(serverpath + destination + mypath)
console.log("[path]" + currentPath)
const totalUsed = getTotalSize(serverpath + destination)
const total = (destination == "SD" ? 4096 : 1.31) * 1024 * 1024
const occupation = ((100 * totalUsed) / total).toFixed(0)

const files = fs.readdirSync(currentPath).map((file) => {
const fullpath = path.normalize(currentPath + "/" + file)
const fst = fs.statSync(fullpath)
const fsize = fst.isFile() ? fileSizeString(fst.size) : "-1"
return { name: file, size: fsize }
})

const response = {
files,
path: mypath,
occupation,
status: "ok",
total: fileSizeString(total),
used: fileSizeString(totalUsed),
}

return JSON.stringify(response)
}

const getAllFiles = function (dirPath, arrayOfFiles = []) {
let files = fs.readdirSync(dirPath) || []
const newFiles = files.reduce((acc, file) => {
const fullpath = dirPath + "/" + file
return fs.statSync(fullpath).isDirectory()
? getAllFiles(fullpath, acc)
: [...acc, fullpath]
}, [])
return [...arrayOfFiles, ...newFiles]
}

const getTotalSize = function (directoryPath) {
const allFiles = getAllFiles(directoryPath)
console.log("allFiles", allFiles)
return allFiles.reduce(
(acc, currFile) => acc + fs.statSync(currFile).size,
0
)
}

function deleteFolderRecursive(path) {
if (fs.existsSync(path) && fs.lstatSync(path).isDirectory()) {
fs.readdirSync(path).forEach(function (file, index) {
let curPath = path + "/" + file

if (fs.lstatSync(curPath).isDirectory()) {
// recurse
deleteFolderRecursive(curPath)
} else {
// delete file
fs.unlinkSync(curPath)
}
})

console.log(`[server]Deleting directory "${path}"...`)
if (fs.existsSync(path)) fs.rmdirSync(path)
} else console.log(`[server]No directory "${path}"...`)
}

app.all("/updatefw", function (req, res) {
res.send("ok")
})

app.all("/files", function (req, res) {
let mypath = req.query.path
let url = req.originalUrl
let filepath = path.normalize(
serverpath + "Flash" + mypath + "/" + req.query.filename
)
if (url.indexOf("action=deletedir") != -1) {
console.log("[server]delete directory " + filepath)
deleteFolderRecursive(filepath)
fs.readdirSync(mypath)
} else if (url.indexOf("action=delete") != -1) {
console.log("[server]delete file " + filepath)
fs.unlinkSync(filepath)
}
if (url.indexOf("action=createdir") != -1) {
fs.mkdirSync(filepath)
console.log("[server]new directory " + filepath)
}
if (typeof mypath == "undefined") {
if (typeof req.body.path == "undefined") {
console.log("[server]path is not defined")
mypath = "/"
} else {
mypath = (req.body.path == "/" ? "" : req.body.path) + "/"
}
}
console.log("[server]path is " + mypath)
if (!req.files || Object.keys(req.files).length === 0) {
return res.send(filesList(mypath, "Flash"))
}
let myFile = req.files.myfiles
if (typeof myFile.length == "undefined") {
let fullpath = path.normalize(
serverpath + "Flash" + mypath + myFile.name
)
console.log("[server]one file:" + fullpath)
myFile.mv(fullpath, function (err) {
if (err) return res.status(500).send(err)
res.send(filesList(mypath, "Flash"))
})
return
} else {
console.log(myFile.length + " files")
for (let i = 0; i < myFile.length; i++) {
let fullpath = path.normalize(
serverpath + "Flash" + mypath + myFile[i].name
)
console.log(fullpath)
myFile[i].mv(fullpath).then(() => {
if (i == myFile.length - 1) res.send(filesList(mypath, "Flash"))
})
}
}
})

app.all("/sdfiles", function (req, res) {
let mypath = req.query.path
let url = req.originalUrl
let filepath = path.normalize(
serverpath + "SD" + mypath + "/" + req.query.filename
)
if (url.indexOf("action=deletedir") != -1) {
console.log("[server]delete directory " + filepath)
deleteFolderRecursive(filepath)
fs.readdirSync(mypath)
} else if (url.indexOf("action=delete") != -1) {
fs.unlinkSync(filepath)
console.log("[server]delete file " + filepath)
}
if (url.indexOf("action=createdir") != -1) {
fs.mkdirSync(filepath)
console.log("[server]new directory " + filepath)
}
if (typeof mypath == "undefined") {
if (typeof req.body.path == "undefined") {
console.log("[server]path is not defined")
mypath = "/"
} else {
mypath = (req.body.path == "/" ? "" : req.body.path) + "/"
}
}
console.log("[server]path is " + mypath)
if (!req.files || Object.keys(req.files).length === 0) {
return res.send(filesList(mypath, "SD"))
}
let myFile = req.files.myfiles
if (typeof myFile.length == "undefined") {
let fullpath = path.normalize(serverpath + "SD" + mypath + myFile.name)
console.log("[server]one file:" + fullpath)
myFile.mv(fullpath, function (err) {
if (err) return res.status(500).send(err)
res.send(filesList(mypath, "SD"))
})
return
} else {
console.log(myFile.length + " files")
for (let i = 0; i < myFile.length; i++) {
let fullpath = path.normalize(
serverpath + "SD" + mypath + myFile[i].name
)
console.log(fullpath)
myFile[i].mv(fullpath).then(() => {
if (i == myFile.length - 1) res.send(filesList(mypath, "SD"))
})
}
}
})

wss.on("connection", (socket, request) => {
console.log(wscolor("[ws] New connection"))
console.log(wscolor(`[ws] currentID:${currentID}`))
socket.send(`currentID:${currentID}`)
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(`activeID:${currentID}`)
}
})
if (sensorInterval != -1) {
clearInterval(sensorInterval)
sensorInterval = setInterval(() => {
const sensorTxt = "SENSOR:10[C] 15[%]"
SendWS(sensorTxt, false, false)
}, 3000)
}
currentID++
socket.on("message", (message) => {
console.log(wscolor("[ws] received:", message))
if (hasEnabledAuthentication() && message.startsWith("PING:")) {
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
let t = hasEnableAuthentication()
? sessiontTime - (Date.now() - getLastconnection())
: 60000
let remainingtime = t < 0 ? 0 : t
console.log("remain:", remainingtime, "millisec")
client.send(`PING:${remainingtime}:60000`)
}
})
}
})
})
wss.on("error", (error) => {
console.log(wscolor("[ws] Error:", error))
})
669 changes: 669 additions & 0 deletions config/targets/CNC/GRBL/index.js

Large diffs are not rendered by default.

3,005 changes: 3,005 additions & 0 deletions config/targets/CNC/grblHAL/index.js

Large diffs are not rendered by default.

861 changes: 861 additions & 0 deletions config/targets/Printer3D/Marlin-embedded/index.js

Large diffs are not rendered by default.

1,011 changes: 1,011 additions & 0 deletions config/targets/Printer3D/Marlin/index.js

Large diffs are not rendered by default.

894 changes: 894 additions & 0 deletions config/targets/Printer3D/Repetier/index.js

Large diffs are not rendered by default.

1,154 changes: 1,154 additions & 0 deletions config/targets/Printer3D/Smoothieware/index.js

Large diffs are not rendered by default.

594 changes: 594 additions & 0 deletions config/targets/SandTable/GRBL/index.js

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions config/webpack.dev.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const path = require("path")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
let target = process.env.TARGET_ENV ? process.env.TARGET_ENV : "Printer3D"
let subtarget = process.env.SUBTARGET_ENV ? process.env.SUBTARGET_ENV : "Marlin"
console.log("Target:", target, " Subtarget:", subtarget)
module.exports = {
resolve: {
alias: {
TargetDir: path.resolve(__dirname, "../src/targets", target),
SubTargetDir: path.resolve(
__dirname,
"../src/targets",
target,
subtarget
),
},
},
mode: "development", // this will trigger some webpack default stuffs for dev
entry: path.resolve(__dirname, "../src/index.js"), // if not set, default path to './src/index.js'. Accepts an object with multiple key-value pairs, with key as your custom bundle filename(substituting the [name]), and value as the corresponding file path
output: {
filename: "[name].bundle.js", // [name] will take whatever the input filename is. defaults to 'main' if only a single entry value
path: path.resolve(__dirname, "../dist"), // the folder containing you final dist/build files. Default to './dist'
},
devServer: {
historyApiFallback: true, // to make our SPA works after a full reload, so that it serves 'index.html' when 404 response
open: true,
static: {
directory: path.resolve(__dirname, "server", "public"),
},
port: 8088,
proxy: {
context: () => true,
target: "http://localhost:8080",
},
},
stats: "minimal", // default behaviour spit out way too much info. adjust to your need.
devtool: "source-map", // a sourcemap type. map to original source with line number
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// all options are optional
filename: "[name].css",
chunkFilename: "[id].css",
ignoreOrder: false, // Enable to remove warnings about conflicting order
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, "../src/index.html"),
inlineSource: ".(js|css)$",
inject: true,
}),
], // automatically creates a 'index.html' for us with our <link>, <style>, <script> tags inserted! Visit https://github.com/jantimon/html-webpack-plugin for more options
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /(node_modules)/,
use: {
loader: "babel-loader",
options: {
presets: ["preact"],
},
},
},
{
test: /\.(sa|sc|c)ss$/,
use: [
{ loader: "style-loader" },
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
],
},
}
110 changes: 110 additions & 0 deletions config/webpack.prod.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
const path = require("path")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const { CleanWebpackPlugin } = require("clean-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin")
const HtmlMinimizerPlugin = require("html-minimizer-webpack-plugin")
const HtmlInlineScriptPlugin = require("html-inline-script-webpack-plugin")
const HTMLInlineCSSWebpackPlugin =
require("html-inline-css-webpack-plugin").default
const Compression = require("compression-webpack-plugin")
let target = process.env.TARGET_ENV ? process.env.TARGET_ENV : "Printer3D"
let subtarget = process.env.SUBTARGET_ENV ? process.env.SUBTARGET_ENV : "Marlin"

module.exports = {
resolve: {
alias: {
TargetDir: path.resolve(__dirname, "../src/targets", target),
SubTargetDir: path.resolve(
__dirname,
"../src/targets",
target,
subtarget
),
},
},
mode: "production", // this trigger webpack out-of-box prod optimizations
entry: path.resolve(__dirname, "../src/index.js"),
output: {
filename: `[name].[hash].js`, // [hash] is useful for cache busting!
path: path.resolve(__dirname, "../build"),
},
module: {
rules: [
{
test: /\.(sa|sc|c)ss$/,
use: [
{ loader: MiniCssExtractPlugin.loader },
{
loader: "css-loader",
options: {
sourceMap: false,
},
},
{
loader: "sass-loader",
options: {
sourceMap: false,
},
},
],
},
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: {
presets: ["preact"],
},
},
],
},
],
},
plugins: [
// always deletes the dist folder first in each build run.
new CleanWebpackPlugin(),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
new HtmlWebpackPlugin({
template: path.join(__dirname, "../src/index.html"),
inlineSource: ".(js|css)$",
inject: "body",
}),

new HtmlInlineScriptPlugin({
scriptMatchPattern: [/.+[.]js$/],
htmlMatchPattern: [/index.html$/],
}),
new HTMLInlineCSSWebpackPlugin(),
new Compression({
test: /\.(html)$/,
filename:
"[path]../dist/" + target + "/" + subtarget + "/[base].gz",
algorithm: "gzip",
exclude: /.map$/,
deleteOriginalAssets: "keep-source-map",
}),
],
optimization: {
minimize: true,
minimizer: [
new HtmlMinimizerPlugin({
minimizerOptions: {
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
},
minify: (data, minimizerOptions) => {
const htmlMinifier = require("html-minifier-terser")
const [[filename, input]] = Object.entries(data)
return htmlMinifier.minify(input, minimizerOptions)
},
}),
],
},
devtool: "source-map", // supposedly the ideal type without bloating bundle size
}
Binary file added dist/CNC/GRBL/index.html.gz
Binary file not shown.
Binary file added dist/CNC/GRBLHal/index.html.gz
Binary file not shown.
Binary file added dist/Plotter/HP-GL/index.html.gz
Binary file not shown.
Binary file added dist/Printer3D/Marlin-embedded/index.html.gz
Binary file not shown.
Binary file added dist/Printer3D/Marlin/index.html.gz
Binary file not shown.
Binary file added dist/Printer3D/Repetier/index.html.gz
Binary file not shown.
Binary file added dist/Printer3D/Smoothieware/index.html.gz
Binary file not shown.
Binary file added dist/SandTable/GRBL/index.html.gz
Binary file not shown.
Binary file removed docs/images/ESP3D-UPLOAD1a.png
Binary file not shown.
Binary file removed docs/images/ESP3D-UPLOAD1b.png
Binary file not shown.
Binary file removed docs/images/ESP3D-UPLOAD2.png
Binary file not shown.
3 changes: 3 additions & 0 deletions extensions/click2go/.babel.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"presets": ["@babel/preset-env"]
}
37 changes: 37 additions & 0 deletions extensions/click2go/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
{
"printWidth": 80,
"tabWidth": 4,
"useTabs": false,
"semi": false,
"singleQuote": false,
"trailingComma": "es5",
"bracketSpacing": true,
"bracketSameLine": false,
"arrowParens": "always",
"requirePragma": false,
"insertPragma": false,
"proseWrap": "preserve",
"overrides": [
{
"files": "*.js",
"options": {
"parser": "babel"
}
},
{"files": "*.css",
"options": {
"parser": "css"
}
},
{"files": "*.scss",
"options": {
"parser": "scss"
}
},
{"files": "*.json",
"options": {
"printWidth": 120,
}
}
]
}
6 changes: 3 additions & 3 deletions gpl.txt → extensions/click2go/LICENSE
Original file line number Diff line number Diff line change
@@ -631,8 +631,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:

<program> Copyright (C) <year> <name of author>
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
8 changes: 8 additions & 0 deletions extensions/click2go/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
This ESP3D-WebUI extension allows you to visualize and interact with a represention of the workspace of your machine. It offers the following features:

* Display the workspace with X and Y axes, along with customizable graduations.
* Support for mouse and touch interactions, providing intuitive control.
* Real-time display of the machine coordinates of the cursor or touch point.
* Customizable UI styles using CSS variables.
* Customisable travel command to send to the machine.
* Customizable precision of the coordinates.
Binary file added extensions/click2go/dist/click2go.html.gz
Binary file not shown.
25 changes: 25 additions & 0 deletions extensions/click2go/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"name": "clicktogo",
"version": "1.0.0",
"description": "ESP3D-WEBUI extension",
"main": "click2go.html",
"scripts": {
"build": "webpack --mode production"
},
"keywords": [],
"author": "Luc LEBOSSE",
"license": "LGPL",
"devDependencies": {
"@babel/core": "^7.24.7",
"@babel/preset-env": "^7.24.7",
"babel-loader": "^9.1.3",
"compression-webpack-plugin": "^11.1.0",
"css-loader": "^7.1.2",
"filemanager-webpack-plugin": "^8.0.0",
"html-loader": "^5.0.0",
"html-webpack-plugin": "^5.6.0",
"style-loader": "^4.0.0",
"webpack": "^5.92.0",
"webpack-cli": "^5.1.4"
}
}
Loading