As I liked Jeff's and Chris's blogs, I decided to use one myself.
It's called Aether, and so far I'm pretty happy with it. It is easy to install (took me about 15 minutes), and especially easy to use. I like the fact that all you need is a browser to edit pages, and add new ones.
For those not familiar with blogs, it's kinda like a wiki, where you can change content online.. you should try it
Right now a lot of my attention (besides the EMC Project) goes to Photography, so you find the most stuff in there.
22 January 2010, 20:16 UTC in projectsradio
For a while I looked online for a radio to put in the kitchen. Nothing fancy, just a wireless connected streaming radio. I found quite a few, but neither was just about right for me (either you couldn't edit your own station URL's, or it was too expensive, or just a crazy colour...
So while googling around I stumbled across MightyOhm's report, and I decided to build my own..
11 September 2026, 14:51 UTC in projectsFixing Moses 3D to Cloos Robot Program Export via QTI API
If you work with Moses 3D simulation software and Cloos welding robots, you might encounter an issue where exporting robot programs (.L files) fails silently or throws initialization errors.
Here is a breakdown of why this happens and how to fix it by creating a custom API interceptor wrapper.
The Problem
When exporting a program (e.g., Rohr1), Moses creates a CSV file containing parameters and writes a configuration file named QTIApi.CFG inside C:\Cloos\QTI\:1;C:\Moses\Konfiguration\CLOOS\DRASS\ROB\CFG 2;C:\Moses\MSTEILE\PROGD\Rohr1 3;DE
Moses then triggers the Cloos command-line tool QTIAPI.exe with a single command:
QTIAPI.exe /CMD 5 Rohr1
Instead of generating Rohr1.L, the export fails. Checking the official Cloos log at %ProgramData%\Cloos Schweisstechnik\QTI\QTIAPI.log reveals the following error:
4 /CMD 5 Rohr1 QTI could not be initialized
Root Cause
QTIAPI.exe treats every execution as a stateless, isolated session. When invoked directly with /CMD 5, it does not automatically parse QTIApi.CFG on its own.Before running conversion commands, QTIAPI.exe expects two mandatory setup calls during runtime:
- /cfg 1 "<Robot Configuration Path>" to initialize the system configuration.
- /cfg 2 "<Working Directory Path>" to set where files should be read and written.
Because Moses calls QTIAPI.exe /CMD 5 directly without passing the /cfg flags first, QTIAPI.exe fails to initialize.
The Solution: A C# API Interceptor
To resolve this, rename the original executable to QTIAPI_real.exe and replace QTIAPI.exe with a lightweight custom C# wrapper.When Moses calls QTIAPI.exe /CMD 5 Rohr1, the wrapper intercepts the call and executes the full sequence:
Moses Export
│
▼
QTIAPI.exe (Custom Wrapper)
│
├── 1. Intercepts original parameters
├── 2. Reads and parses QTIApi.CFG
├── 3. Executes: QTIAPI_real.exe /cfg 1 "C:\Moses\Konfiguration\..."
├── 4. Executes: QTIAPI_real.exe /cfg 2 "C:\Moses\MSTEILE\..."
└── 5. Executes: QTIAPI_real.exe /CMD 5 Rohr1
│
▼
QTIAPI_real.exe ──► Successfully generates Rohr1.L
Implementation Steps
Step 1: Rename the Original Binary
Navigate to C:\Cloos\QTI\ and rename QTIAPI.exe to QTIAPI_real.exe.
Step 2: Compile the Wrapper Executable
Open PowerShell on your system and run the following script to compile the wrapper directly into C:\Cloos\QTI\QTIAPI.exe:
$code = @'
using System;
using System.Diagnostics;
using System.IO;
class Program {
static void Main(string[] args) {
string logFile = @"C:\Cloos\QTI\execution_trap.log";
string realExe = @"C:\Cloos\QTI\QTIAPI_real.exe";
string cfgFile = @"C:\Cloos\QTI\QTIApi.CFG";
// Step 1: Log intercepted call
string originalArgs = string.Join(" ", args);
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] Intercepted call: " + originalArgs + "\r\n");
if (!File.Exists(realExe)) {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] ERROR: QTIAPI_real.exe not found.\r\n");
return;
}
// Step 2: Read and parse QTIApi.CFG
if (File.Exists(cfgFile)) {
string[] lines = File.ReadAllLines(cfgFile);
foreach (string line in lines) {
if (string.IsNullOrWhiteSpace(line)) continue;
string[] parts = line.Split(';');
if (parts.Length >= 2) {
string id = parts[0].Trim();
string path = parts[1].Trim();
// Step 3 & 4: Issue /cfg 1 and /cfg 2 prior to command execution
if (id == "1" || id == "2") {
string cfgArgs = "/cfg " + id + " \"" + path + "\"";
ExecuteRealExe(realExe, cfgArgs, logFile);
}
}
}
} else {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] WARNING: QTIApi.CFG not found at " + cfgFile + "\r\n");
}
// Step 5: Execute original command
ExecuteRealExe(realExe, originalArgs, logFile);
}
static void ExecuteRealExe(string exePath, string arguments, string logFile) {
File.AppendAllText(logFile, "[" + DateTime.Now.ToString() + "] Executing: QTIAPI_real.exe " + arguments + "\r\n");
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.FileName = exePath;
startInfo.Arguments = arguments;
startInfo.UseShellExecute = false;
using (Process process = Process.Start(startInfo)) {
process.WaitForExit();
}
}
}
'@
Add-Type -TypeDefinition $code -OutputAssembly "C:\Cloos\QTI\QTIAPI.exe" -OutputType ConsoleApplication
Verification
- Run a program export inside Moses.
- Check C:\Cloos\QTI\execution_trap.log to confirm the sequence:
[11.09.2026 17:42:58] Intercepted call: /CMD 5 Rohr1
[11.09.2026 17:42:58] Executing: QTIAPI_real.exe /cfg 1 "C:\Moses\Konfiguration\CLOOS\DRASS\ROB\CFG"
[11.09.2026 17:43:00] Executing: QTIAPI_real.exe /cfg 2 "C:\Moses\MSTEILE\PROGD\Rohr1"
[11.09.2026 17:43:01] Executing: QTIAPI_real.exe /CMD 5 Rohr1
- Check %ProgramData%\Cloos Schweisstechnik\QTI\QTIAPI.log to confirm code 0 (Success):
0 /CMD 5 Rohr1
The target .L parameter file will now be successfully created in your project output folder.
23 December 2025, 21:12 UTC in projectsProxmox stuff
Warning.. ramblings follow, read at own risk.
The first upgrade
Switched from Pi4 + Docker to HP EliteDesk 800 G6 Mini PC (i5 10500, 32GB DDR4, 1 x SSD 512GB for proxmox, 2 x NVMe 1TB SSDs for VMs and Data).Very capable little machine, but I ran into some issues:
- Adding a second NVMe SSD made the BIOS complain about a missing chassis fan. Had to buy one (which is some laptop model, about 4mm high, fits under the SATA 2.5" tray) gets plugged into the MB into an 5pin header. My fan had only 4 wires, so had to reposition the pins (solution: 1-GND, 2-5v, 3-12V, 4-Sense (Tach),5-Control (PWM)
- no optimal solution to add faster networking to it: there is a FlexIO 2.5Gbit ethernet card, hard to find. Using a Thunderbolt to xxGbit adapter won't work without a Thunderbolt FlexIO card - also hard to find, and expensive. There is a FlexIO 10Gbit ethernet card - not officially supported on this platform. There are 2 versions, only one fits. Also expensive and hard to find. Using a m.2 e-key 2.5gbit network card instead of the wifi board - probably won't fit with the 2 x NVMe's, 1 x Sata Drive and Chassis fan
Install as follows:
- Proxmox 9.1.x installed on the Sata SSD
- Added one VM running HAOS
- Added another VM running debian 13 for dockers
- Portainer for docker administration / portainer/portainer-ee:latest
- Homepage for overview / install from here
- Iobroker / buanet/iobroker - had a bit of issue of mounting the folder for SMB backups on my ancient NAS. Ended up mounting the folder via NFS in proxmox, and passing the folder as a volume to the iobroker docker. Prevents using privileged containers like this
- Pihole / pihole/pihole:latest - selfexplanatory
- Immich / Install instructions
The next upgrade
2 weeks later ran out of space, after installing immich, and migrating fotos from google photos using immich-go.Next thought was to add an NAS for storage, as the current one was getting old. That presented an issue finding one (newer ones are more powerfull, but require expensive (at dec. 2025 prices) DDR5 ram), had an dell 3630 with 8th gen i7, 64GB ram laying around, with space for 3 HDDs that would make a great NAS.
after more thought, the new "server" can actually take over all the functions of the MiniPC, and include the additional storage, and get a 10Gbit Mellanox card.
Migrating Proxmox to the new machine
Was actually the easiest: move the SSD over, move the 2 x NVMe over, add the new 3 HDDs (12TB Ironwolf Red), and boot.The Mellanox 10Gbit card was the biggest issue: when inserted in the motherboard, the Dell wouldn't boot, and bring a 2-7 blinking error on the power led: Memory issues.
Memory was fine, the issue comes from the Mellanox card interfering with the SMBUS communication to the memory controller. The fix (as presented by Mark Furneaux on youtube) is quite simple: mask PCIe pins 5 & 6 with nonconductive tape.
Proxmox booted fine, had to change /etc/network/interfaces as the new motherboard presented the nic with a new name.
PS: don't change the vmbr0 interface name, as that one will be used by VMs, change the bridge-ports to the new interface name (for me it was eno1)
minor nags/fixes
- Had applied PVE-mods to display individual CPU core temperatures (with lm-sensors), which also displayed System Information like Manufacturer, Model and serial number in the Node Summary. This information was easiest to update by re-running the PVE-mods install script.
- After updating proxmox, had to reinstall the PVE-mods anyway.
Extensions / new stuff
Adding samba:
- Giving zamba-lxc-toolkit a spin. Configuration at: reddit.
- Alternative for samba - manual with cockpit for web config - youtube video / Alpard
26 December 2022, 20:14 UTC in projectsrpi4+docker stuff
Just some snippets so I remember what I did..
RPi OS
Raspberry Pi OS - 64bit, lite, installed from Imager 1.7.3.Installed to a SD card, configured user pi pass, and wifi credentials
sudo apt-get update
Since I got an error:
N: Repository 'http://deb.debian.org/debian bullseye InRelease' changed its 'Version' value from '11.5' to '11.6'
I had to:
sudo apt-get update --allow-releaseinfo-change then the regular sudo apt-get upgrade
docker
Using loosely the instructions from Raspi-docker
Download the right script and install Docker on the Raspberry Pi environment.
curl -fsSL https://get.docker.com -o get-docker.sh
Then run the script with the help of the below command:
sudo sh get-docker.sh
after an odd error, and a restart (iptables was not running because of a kernel upgrade, and docker-ce was failing configuration stage), running it again made it work
add user pi to the group docker: sudo usermod -aG docker pi
then log in again and check docker is running: docker version, docker info and docker run hello-world
Output
pi@rpi4:~ $ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
7050e35b49f5: Pull complete
Digest: sha256:c77be1d3a47d0caf71a82dd893ee61ce01f32fc758031a6ec4cf1389248bb833
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(arm64v8)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
portainer
First install portainer, to admin dockers via GUI
pi@rpi4:~ $ docker run -d -p 9000:9000 --name portainer --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /opt/docker_data/portainer_data:/data portainer/portainer-ce
then connect to ip:9000, and setup admin user with password > 12 chars
iobroker
follow the instruction from buanet
However, there are some caveats:
- Create new docker container / Portainer/Containers/Add container
- Name: "iobroker", Image: "buanet/iobroker:latest", Map additional port: 8081/8081, Advanced/Volumes - container: "/opt/iobroker", Bind, host: "/opt/docker_data/iobroker_data", Capabilities: enable SYS_ADMIN, enable DAC_READ_SEARCH
- + copy a backup manually into /opt/iobroker
- Deploy the container - this will restore the data from the backup if existing
- Takes a while to install and start, check the log
- Access "http://ip:8081". For me this failed, because the backup had a different IP. Had to stop the container, edit the config .js by hand, and restart the container
upgrades
- Iobroker updates: via webpage
- JS controller updates, via command line:
- start container cmd (via portainer)
- pkill -u iobroker
- iobroker update
- iobroker upgrade self
- restart container
9 March 2020, 20:27 UTC in projectsOpenVPN and certificate ramblings
Just some infos for me to remember what to do when certificates expire.
21 January 2020, 13:48 UTC in projectsWindows 10 1803 / 1903 and NT style domains..
30 December 2017, 21:07 UTC in projectsTasmota Fireplace on a witty cloud
13 December 2017, 9:35 UTCSenior Alfons de Brabanel
2 December 2017, 19:30 UTC in projectsSonoff Touch specifics
8 November 2017, 10:54 UTC in projectsFHEM + Sonoff + MQTT/mosquitto + Amazon echo/Alexa
21 April 2017, 5:22 UTC in projectsWindows Live Mail 2012
19 July 2015, 22:06 UTC in photographyAirshow 2015
28 January 2015, 11:10 UTC in projectsolder robot
17 January 2014, 8:20 UTC in projectsRunning EMC1 on windows
27 October 2013, 21:11 UTC in projectsThermal leaking?
