Skip to content

Instantly share code, notes, and snippets.

@CopeTypes
Created July 6, 2024 18:20
Show Gist options
  • Save CopeTypes/d322c54ca53ecdce714143546a914069 to your computer and use it in GitHub Desktop.
Save CopeTypes/d322c54ca53ecdce714143546a914069 to your computer and use it in GitHub Desktop.
Windows script to set up a USB drive for installing Klipper firmware on the FlashForge Adventurer 5M/Pro
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName Microsoft.VisualBasic
function CopyFile {
param (
[Parameter(Mandatory=$true)]
[string]$Source,
[Parameter(Mandatory=$true)]
[string]$Dest
)
if (-Not (Test-Path -Path $Source -PathType Leaf)) {
Write-Error "Unable to copy file, file does not exist: $Source"
return
}
$dest = Split-Path -Parent $Dest
if (-Not (Test-Path -Path $destinationDir -PathType Container)) {
Write-Host "Destination directory does not exist. Creating: $dest"
New-Item -ItemType Directory -Path $dest
}
try {
Copy-Item -Path $Source -Destination $Dest -Force
} catch {
Write-Error "Unable to copy file from $Source to $Dest"
Write-Error "Error: $_"
}
}
function DeleteByExtension {
param (
[Parameter(Mandatory = $true)]
[string]$FolderPath,
[Parameter(Mandatory = $true)]
[string]$FileExtension
)
if (-not (Test-Path -Path $FolderPath -PathType Container)) {
Write-Error "Folder path '$FolderPath' not found."
return
}
$SearchPattern = "*$FileExtension"
$Files = Get-ChildItem -Path $FolderPath -File -Filter $SearchPattern -ErrorAction SilentlyContinue
if ($Files.Count -eq 0) {
#Write-Warning "No files with extension '$FileExtension' found in '$FolderPath'."
return
}
# Delete each file
foreach ($File in $Files) {
Remove-Item -Path $File.FullName -Force
#Write-Output "Deleted file: $($File.FullName)"
}
#Write-Output "Deleted all files with extension '$FileExtension' from '$FolderPath'."
}
function CheckFolder {
param (
[Parameter(Mandatory=$true)]
[string]$path
)
if (-Not (Test-Path -Path $path -PathType Container)) {
New-Item -ItemType Directory $path
}
}
function Download {
param (
[Parameter(Mandatory=$true)]
[string]$url,
[Parameter(Mandatory=$true)]
[string]$path
)
$fileName = Split-Path -Path $url -Leaf
$outPath = Join-Path "$path" -ChildPath "$fileName"
try {
Invoke-WebRequest -Uri $url -OutFile $outPath
return $true
} catch {
Write-Error "Download error: $_"
return $false
}
}
function IsPro {
$result = [System.Windows.Forms.MessageBox]::Show(
"Select yes for 5M Pro, no for the standard 5M.", # message
"AD5M Klipper Setup", # title
[System.Windows.Forms.MessageBoxButtons]::YesNo,
[System.Windows.Forms.MessageBoxIcon]::Question
)
if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
return $true
} elseif ($result -eq [System.Windows.Forms.DialogResult]::No) {
return $false
}
}
function Inputbox {
param (
[Parameter(Mandatory=$true)]
[string]$msg
)
$result = [Microsoft.VisualBasic.Interaction]::InputBox(
"$msg",
"AD5M Klipper Setup",
"err"
)
return $result
}
function MakeWifiCfg { # create a wifi config to be used during installation. setting up wifi without a gui installed is not fun
param (
[Parameter(Mandatory=$true)]
[string]$ssid,
[Parameter(Mandatory=$true)]
[string]$pass,
[Parameter(Mandatory=$true)]
[string]$path
)
$kmRoot = Join-Path "$path" -ChildPath "klipper_mod"
CheckFolder -path $kmRoot # create folder if it doesn't exist
$iwdRoot = Join-Path "$kmRoot" -ChildPath "var/lib/iwd"
CheckFolder -path $iwdRoot
$outFile = Join-Path "$iwdRoot" -ChildPath "$ssid.psk"
# file needs to be compatible with linux - https://github.com/xblax/flashforge_ad5m_klipper_mod/blob/master/docs/WIFI.md#configure-via-usb
Set-Content -Path $outFile -Value "[Settings]`n"
Add-Content -Path $outFile -Value "AutoConnect=True`n"
Add-Content -Path $outFile -Value "`n"
Add-Content -Path $outFile -Value "[Security]`n"
Add-Content -Path $outFile -Value "Passphrase=$pass`n"
}
function CleanUsb {
param (
[Parameter(Mandatory=$true)]
[string]$path
)
DeleteByExtension -FolderPath $path -FileExtension ".tgz" # remove conflicting/old firmware zips
DeleteByExtension -FolderPath $path -FileExtension ".log" # remove old logs to avoid confusion if/when diagnosing issues
$kmr = Join-Path $path -ChildPath "klipper_mod"
if (Test-Path -Path $kmr -PathType Container) { # delete everything inside klipper_mod
Get-ChildItem -Path $kmr -Recurse | Remove-Item -force -recurse
Remove-Item $kmr -Force # delete klipper_mod folder
}
}
function HasLatestFw { # check if the latest fw is already present on the usb
param (
[Parameter(Mandatory=$true)]
[string]$usbDrive
)
$path = Join-Path "$usbDrive" -ChildPath "Adventurer5MPro-KlipperMod-v00.05-beta-lite.tgz"
if (Test-Path -Path $path -PathType Leaf) {
return $true
}
return $false
}
Write-Host "This script will prepare your usb for installing klipper onto the AD5M/Pro"
Write-Host "This will NOT guide you through installation, see https://github.com/xblax/flashforge_ad5m_klipper_mod/blob/master/docs/INSTALL.md"
Write-Warning "You will need to be on FlashForge firmware >= 2.4.5 to install/boot klipper"
Write-Host "This does NOT replace the stock firmware, to boot into FlashForge firmware, see https://github.com/xblax/flashforge_ad5m_klipper_mod/blob/master/docs/INSTALL.md#dual-boot"
$usbRoot = Inputbox -msg "Enter usb drive letter (e.g., E:)"
$isPro = IsPro
$fwType = Inputbox -msg "Enter desired firmware type (lite, klipperscreen, or guppyscreen)"
$wifiSsid = Inputbox -msg "Enter wifi SSID (case sensitive)"
$wifiPass = Inputbox -msg "Enter wifi password"
if ($fwType -contains "err" -or $wifiSsid -contains "err" -or $wifiPass -contains "err") {
Write-Host "Invalid input data (firmware choice, wifi ssid, or wifi password)"
exit
}
# 5M firmware urls
$s_liteFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5M-KlipperMod-v00.05-beta-lite.tgz"
$s_guppyScreenFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5M-KlipperMod-v00.05-beta-guppyscreen.tgz"
$s_klipperScreenFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5M-KlipperMod-v00.05-beta-klipperscreen.tgz"
# 5M Pro firmware urls
$p_liteFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5MPro-KlipperMod-v00.05-beta-lite.tgz"
$p_guppyScreenFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5MPro-KlipperMod-v00.05-beta-guppyscreen.tgz"
$p_klipperScreenFwUrl = "https://github.com/xblax/flashforge_ad5m_klipper_mod/releases/download/v00.05-beta/Adventurer5MPro-KlipperMod-v00.05-beta-klipperscreen.tgz"
$fwUrl = ""
$hasLatestFw = HasLatestFw -usbDrive $usbRoot
# select firmware url
if ($IsPro) {
switch ($fwType) {
"lite" { $fwUrl = $p_liteFwUrl }
"guppyscreen" { $fwUrl = $p_guppyScreenFwUrl }
"klipperscreen" { $fwUrl = $p_klipperScreenFwUrl }
default {
Write-Error "invalid firmware type choice"
exit
}
}} else {
switch ($fwType) {
"lite" { $fwUrl = $s_liteFwUrl }
"guppyscreen" { $fwUrl = $s_guppyScreenFwUrl }
"klipperscreen" { $fwUrl = $s_klipperScreenFwUrl }
default {
Write-Error "invalid firmware type choice"
exit
}
}
}
if ($hasLatestFw) {
Write-Host "Latest fw installer already present, skipping download"
} else {
Write-Host "Preparing usb..."
CleanUsb -path $usbRoot # remove any conflicting files
Write-Host "Downloading firmware..."
Download -path $usbRoot -url $fwUrl # download the klipper firmware
}
Write-Host "Creating wifi config"
MakeWifiCfg -path $usbRoot -ssid $wifiSsid -pass $wifiPass # create wifi ssid.psk config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment