Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/cloud.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
---
title: 3D Printing Clouds
---

3D printing cloud providers offer a wide range of tools for 3D printing.

## OctoEverywhere

**Available in: Extended firmware only**

[OctoEverywhere.com](https://octoeverywhere.com) is a community project that enables:

- Free & unlimited full Fluidd/Mainsail remote access.
- Free & unlimited AI print failure detection.
- Real-time print notifications to Email, SMS, Discord, etc.
- Remote access for iPhone & Android apps like Mobileraker and OctoApp.
- Multi-printer dashboard with quick access to snapshots, status, remote access, and print time completions.
- Live streaming, shared printer access, and more!


### Enabling OctoEverywhere

OctoEverywhere is **disabled by default**.

#### Using firmware-config Web UI

Navigate to the firmware-config interface and select `octoeverywhere` under Cloud Provider. This will automatically download and install the OctoEverywhere plugin.

> **After enabling OctoEverywhere, you must link your account! (see below)**

#### Manual Setup

**Step 1:** Download OctoEverywhere (requires internet connection):
```bash
ssh root@<printer-ip>
octoeverywhere-pkg download
```

**Step 2:** Edit `extended/extended2.cfg`, set the `cloud` to `octoeverywhere`:
```ini
[remote_access]
cloud: octoeverywhere
```

**Step 3:** Start the OctoEverywhere plugin service:
```bash
/etc/init.d/S99octoeverywhere restart
```

### OctoEverywhere Account Linking

Once the OctoEverywhere plug-in is running, you need to link it with your OctoEverywhere.com account. Simply find the account linking URL in the `octoeverywhere.log` file.

#### Using Fluidd

- Open the Fluidd web interface
- Click the `{...}` Configuration icon on the side menu bar.
- In the `Other Files` section, under the `Logs` tab, find `octoeverywhere.log` and click to edit/open it.
- Look for the account linking URL; it will be near the top.
- Open the URL in your browser, name your printer, and you're done!

#### Using Mainsail

- Open the Mainsail web interface
- Click the `Machine` option in the side menu bar.
- In the `Config Files` section, set the `root` dropdown box to `logs`
- Find `octoeverywhere.log` file and click to open it.
- Look for the account linking URL; it will be near the top.
- Open the URL in your browser, name your printer, and you're done!
11 changes: 11 additions & 0 deletions docs/firmware_config.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ Toggle settings directly from the web interface:
| Remote Screen | Enabled, Disabled | Enable remote screen access |
| Klipper Metrics Exporter | Enabled, Disabled | Enable Prometheus metrics |
| VPN Provider | None, Tailscale | Enable VPN remote access (Experimental) |
| Cloud | None, OctoEverywhere | Enable support for [OctoEverywhere](cloud.md) |

Changes are applied immediately and relevant services are restarted.

Expand Down Expand Up @@ -160,6 +161,12 @@ Note: Remote screen requires additional Moonraker configuration. See [Remote Scr

See [VPN Remote Access](vpn.md) for setup instructions.

**cloud**
- `none` (default) - No cloud providers enabled.
- `octoeverywhere` - [OctoEverywhere.com](https://octoeverywhere.com) enables free & unlimited remote access, AI print failure detection, notifications, and more.

See the [3D Printing Clouds](cloud.md) for setup instructions.

#### [monitoring]

**klipper_exporter** - Enable Prometheus metrics exporter for Klipper
Expand Down Expand Up @@ -194,6 +201,10 @@ ssh: false
# VPN provider for remote access: none, tailscale
# Must SSH and run "tailscale up" to complete login flow
vpn: none
# Cloud: none, octoeverywhere
# - none - No cloud services enabled.
# - octoeverywhere - OctoEverywhere.com remote access, AI print failure detection, notifications, and more.
cloud: none

[monitoring]
# Enable Klipper Prometheus exporter on specified address
Expand Down
1 change: 1 addition & 0 deletions docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ Heavily expanded firmware with extensive features and customization. Includes al
- Moonraker Adaptive Mesh Support - Object processing for adaptive mesh features
- Moonraker Apprise Notifications - Send print notifications to Discord, Telegram, Slack, and 90+ services
- [Timelapse Recovery Tool](https://github.com/horzadome/snapmaker-u1-timelapse-recovery) - Recover unplayable timelapse videos
- [OctoEverywhere](cloud.md) - Free & unlimited secure remote access, AI print failure detection, notifications, and more

## Support

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ ssh: false
# VPN provider for remote access: none, tailscale
# Must SSH and run "tailscale up" to complete login flow
vpn: none
# Cloud: none, octoeverywhere
# - none - No cloud services enabled.
# - octoeverywhere - OctoEverywhere.com free & unlimited remote access, AI print failure detection, notifications, and more.
cloud: none

[monitoring]
# Enable Klipper Prometheus exporter on specified address
Expand Down
97 changes: 97 additions & 0 deletions overlays/firmware-extended/23-cloud/root/etc/init.d/S99cloud
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/bin/sh

#
# OctoEverywhere Cloud Config
#

OCTOEVERYWHERE_PIDFILE="/var/run/octoeverywhere.pid"

start_octoeverywhere() {
if [ -f "$OCTOEVERYWHERE_PIDFILE" ] && kill -0 "$(cat "$OCTOEVERYWHERE_PIDFILE")" 2>/dev/null; then
echo "OctoEverywhere already running, no need to start."
return 0
fi

# These paths are referenced in the pkg script
OE_INSTALL_DIR="/oem/apps/octoeverywhere"
OE_VENV_DIR="/oem/apps/octoeverywhere-env"

# These must match the paths in the config json.
OCTOEVERYWHERE_STORAGE_DIR="/home/lava/printer_data/octoeverywhere-store"
# OCTOEVERYWHERE_ARGS is the following json base64 encoded:
# {"ConfigFolder": "/home/lava/printer_data/config", "LogFolder": "/home/lava/printer_data/logs", "LocalFileStoragePath": "/home/lava/printer_data/octoeverywhere-store",
# "ServiceName": "octoeverywhere", "VirtualEnvPath": "/oem/apps/octoeverywhere-env", "RepoRootFolder": "/oem/apps/octoeverywhere", "IsCompanion": false,
# "MoonrakerConfigFile": "/home/lava/printer_data/config/moonraker.conf"}
OCTOEVERYWHERE_ARGS="eyJDb25maWdGb2xkZXIiOiAiL2hvbWUvbGF2YS9wcmludGVyX2RhdGEvY29uZmlnIiwgIkxvZ0ZvbGRlciI6ICIvaG9tZS9sYXZhL3ByaW50ZXJfZGF0YS9sb2dzIiwgIkxvY2FsRmlsZVN0b3JhZ2VQYXRoIjogIi9ob21lL2xhdmEvcHJpbnRlcl9kYXRhL29jdG9ldmVyeXdoZXJlLXN0b3JlIiwgIlNlcnZpY2VOYW1lIjogIm9jdG9ldmVyeXdoZXJlIiwgIlZpcnR1YWxFbnZQYXRoIjogIi9vZW0vYXBwcy9vY3RvZXZlcnl3aGVyZS1lbnYiLCAiUmVwb1Jvb3RGb2xkZXIiOiAiL29lbS9hcHBzL29jdG9ldmVyeXdoZXJlIiwgIklzQ29tcGFuaW9uIjogZmFsc2UsICJNb29ucmFrZXJDb25maWdGaWxlIjogIi9ob21lL2xhdmEvcHJpbnRlcl9kYXRhL2NvbmZpZy9tb29ucmFrZXIuY29uZiJ9"

printf "Starting OctoEverywhere..."
mkdir -p "$OCTOEVERYWHERE_STORAGE_DIR"

# Tune malloc for embedded systems, so PY doesn't each so much memory.
export MALLOC_TRIM_THRESHOLD_=65536
export MALLOC_ARENA_MAX=2

PYTHON="${OE_VENV_DIR}/bin/python3"
cd "$OE_INSTALL_DIR"
start-stop-daemon -S -b -m \
-p "$OCTOEVERYWHERE_PIDFILE" \
-x "$PYTHON" -- \
-m moonraker_octoeverywhere "$OCTOEVERYWHERE_ARGS"

echo "OctoEverywhere started!"
}

#
# Cloud Common
#

# Load config from user extended config file
EXTENDED_CFG="/home/lava/printer_data/config/extended/extended2.cfg"
CLOUD_PROVIDER=$(/usr/local/bin/extended-config.py get "$EXTENDED_CFG" remote_access cloud none)

start() {
case "$CLOUD_PROVIDER" in
octoeverywhere)
start_octoeverywhere
;;
*)
echo "No cloud is enabled in the extended configuration, not starting any cloud service."
exit 0
;;
esac
}

stop() {
# Stop all cloud services, if any are running.
printf "Stopping OctoEverywhere: "
if [ -f "$OCTOEVERYWHERE_PIDFILE" ]; then
start-stop-daemon -K -p "$OCTOEVERYWHERE_PIDFILE" -s TERM
rm -f "$OCTOEVERYWHERE_PIDFILE"
echo "OK"
else
echo "not running"
fi
}

case "$1" in
start)
start
;;

stop)
stop
;;

restart|reload)
stop
sleep 1
start
;;

*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac

exit $?
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import re
from typing import Optional


def does_file_exist(file_path:str) -> bool:
try:
with open(file_path, 'r'):
return True
except FileNotFoundError:
return False


def get_account_link_url(log_file_path:str) -> Optional[str]:
try:
with open(log_file_path, 'r') as log_file:
for line in log_file:
match = re.search(r'account-linking-url:<(https://octoeverywhere\.com/getstarted\?printerid=[^>]+)>', line)
if match:
return match.group(1)
except FileNotFoundError:
return None
return None


if __name__ == "__main__":
log_file_path = '/home/lava/printer_data/logs/octoeverywhere.log'

print('')
print('')

accountLinkUrl = get_account_link_url(log_file_path)
if accountLinkUrl is not None:
print('Use this URL to link this printer with your OctoEverywhere account:')
print(accountLinkUrl)
else:
logFileExists = does_file_exist(log_file_path)
if not logFileExists:
print("The OctoEverywhere Plugin Is Not Running.")
print("Enable it using the firmware config page under in Remote Access.")
else:
print("!! The OctoEverywhere Account Link URL Was Not Found In The Log File !!")
print("Contact Support: https://octoeverywhere.com/support")
print('')
print('If you need help, follow this guide:')
print('https://octoeverywhere.com/s/snapmaker-u1')
print('')
print('')
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
octoeverywhere-pkg
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/bin/bash


#
# OctoEverywhere package manager
# Downloads and installs a pinned version of OctoEverywhere from GitHub
#

GIT_TAG_VERSION="4.6.6"
EXPECTED_TAG_SHA256="8fedea60d50adc5763269cec47a46d81e534ea0066b790176fc819abea1b8db5"

REPO_URL="https://github.com/QuinnDamerell/OctoPrint-OctoEverywhere/archive/refs/tags/${GIT_TAG_VERSION}.zip"
TMP_DIR="/oem/apps/octoeverywhere.tmp"

# These paths are referenced in the init.d script
INSTALL_DIR="/oem/apps/octoeverywhere"
VENV_DIR="/oem/apps/octoeverywhere-env"

check() {
if [[ -d "$INSTALL_DIR" && -d "$VENV_DIR" && -f "$INSTALL_DIR/moonraker_octoeverywhere.py" ]]; then
echo "OctoEverywhere is installed."
return 0
else
echo "OctoEverywhere is not installed."
return 1
fi
}

download() {
rm -rf "$TMP_DIR"
mkdir -p "$TMP_DIR"

echo "Downloading OctoEverywhere ${GIT_TAG_VERSION} From GitHub..."
if ! /usr/local/bin/curl -sfSL -o "$TMP_DIR/octoeverywhere.zip" "$REPO_URL"; then
echo "Download failed"
return 1
fi

echo "Verifying SHA256 checksum..."
ACTUAL_SHA256=$(sha256sum "$TMP_DIR/octoeverywhere.zip" | awk '{print $1}')
if [[ "$ACTUAL_SHA256" != "$EXPECTED_TAG_SHA256" ]]; then
echo "SHA256 mismatch!"
echo " Expected: $EXPECTED_TAG_SHA256"
echo " Actual: $ACTUAL_SHA256"
return 1
fi
echo "Checksum verified."

echo "Extracting..."
if ! unzip -q "$TMP_DIR/octoeverywhere.zip" -d "$TMP_DIR"; then
echo "Extraction failed"
return 1
fi
echo "Extraction successful."

rm -rf "$INSTALL_DIR"

# GitHub archives extract to OctoPrint-OctoEverywhere-<tag>
EXTRACT_DIR="$TMP_DIR/OctoPrint-OctoEverywhere-${GIT_TAG_VERSION}"
if ! mv "$EXTRACT_DIR" "$INSTALL_DIR"; then
echo "Failed to move OctoEverywhere to $INSTALL_DIR"
return 1
fi

rm -rf "$TMP_DIR"

echo "Setting up Python virtual environment (this can take up to 60 seconds)..."
if ! python3 -m venv "$VENV_DIR"; then
echo "Failed to create virtual environment"
return 1
fi

echo "Installing dependencies (this can also take a bit)..."
if ! "$VENV_DIR/bin/pip" install --disable-pip-version-check --quiet -r "$INSTALL_DIR/requirements.txt"; then
echo "Failed to install dependencies"
return 1
fi

echo "Trying to install the optional zstdstandard package for better performance..."
if ! "$VENV_DIR/bin/pip" install --disable-pip-version-check --quiet zstandard; then
echo "Failed to install zstandard, continuing without it."
fi

echo "OctoEverywhere installed successfully to $INSTALL_DIR"
}

case "$1" in
check)
check
;;
download)
if check; then
echo "OctoEverywhere is already installed."
exit 0
fi
if ! download; then
rm -rf "$TMP_DIR"
exit 1
fi
;;
update)
echo "Updating OctoEverywhere..."
if ! download; then
rm -rf "$TMP_DIR"
exit 1
fi
;;
clean)
echo "Removing OctoEverywhere installation..."
rm -rf "$INSTALL_DIR" "$VENV_DIR"
echo "Removed."
;;
*)
echo "Usage: $0 check|download|update|clean"
exit 1
;;
esac
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
../bin/octoeverywhere-pkg
Loading
Loading