Moin zusammen, ich habe mir ein Script geschrieben, welches periodisch die moonraker api nach den wichtigsten Infos abfragt und in iobroker Javascript States schreibt. Das wäre mit Hilfe der moonraker API-Dokumentation auch recht einfach erweiterbar.
Falls es jemand gebrauchen kann (ohne Gewähr):
const printerName = 'VORON'; // Replace with your actual printer name
const printerBaseUrl = 'http://192.168.2.32'; // Replace with your actual moonraker ip
const updateInterval = 20000; // 20 seconds
// Function to make an HTTP request and return a promise
function getPrinterStatus(url) {
return new Promise((resolve, reject) => {
const request = require('request');
request(url, { json: true }, (err, res, body) => {
if (err) {
reject(err);
} else {
resolve(body);
}
});
});
}
// Function to get metadata for the given filename
function getFileMetadata(filename) {
const metadataUrl = printerBaseUrl + `/server/files/metadata?filename=${encodeURIComponent(filename)}`;
return getPrinterStatus(metadataUrl); // Reusing the HTTP request function
}
// Function to convert seconds to HH:MM:SS
function toHHMMSS(seconds) {
const hours = Math.floor(seconds / 3600);
const minutes = Math.floor((seconds % 3600) / 60);
const sec = Math.floor(seconds % 60);
return [hours, minutes, sec]
.map(v => v < 10 ? "0" + v : v)
.join(":");
}
// Function to update the online status of the printer
function updatePrinterOnlineStatus(isOnline) {
const onlineStateName = `${printerName}.onlineStatus`;
createOrUpdateState(onlineStateName, isOnline);
}
// Function to create or update ioBroker states
function createOrUpdateState(fullStateName, value, key='') {
// Check if the key contains 'duration' and format it if it does
if (key.includes('duration')) {
value = toHHMMSS(value);
}
// Check if the key contains 'progress' and multiply by 100 and round it if it does
if (key.includes('progress')) {
value = Math.round(value * 100); // Converts to percentage and rounds to the nearest integer
}
if (!existsState(fullStateName)) {
createState(fullStateName, {
type: typeof value,
read: true,
write: false,
desc: 'Printer status value'
}, () => {
setState(fullStateName, value, true);
});
} else {
setState(fullStateName, value, true);
}
}
// Function to process the printer status and update the ioBroker states
function processPrinterStatus(printerData, parentKey = '') {
Object.keys(printerData).forEach(key => {
const value = printerData[key];
let fullStateName = `${printerName}`;
if (parentKey) {
fullStateName += `.${parentKey}`;
}
fullStateName += `.${key}`;
if (value !== null && typeof value === 'object' && !(value instanceof Array)) {
// It's a nested object, so we need to recurse
processPrinterStatus(value, key);
} else {
// It's a value, so we create or update the state
createOrUpdateState(fullStateName, value, key);
}
});
}
// Function to nullify file metadata states in ioBroker
function nullifyFileMetadataStates() {
var states = $(`*.${printerName}.file_metadata.*`/*Printer file metadata*/);
states.each(function(id, i){
setState(id, {val: null, ack: true});
});
}
// Polling function
function startPolling() {
setInterval(() => {
getPrinterStatus(printerBaseUrl + '/printer/objects/query?display_status&print_stats&extruder&heater_bed&system_stats')
.then(response => {
if (response && response.result) {
const printStats = response.result.status.print_stats || {};
const filename = printStats.filename;
// Update printer status
processPrinterStatus(response.result);
// If there is a filename, get and process the file metadata
if (filename) {
getFileMetadata(filename).then(metadataResponse => {
if (metadataResponse && metadataResponse.result) {
processPrinterStatus(metadataResponse.result, 'file_metadata');
}
}).catch(error => {
console.error('Error fetching file metadata:', error);
});
} else {
// If filename is empty, nullify all file_metadata states
nullifyFileMetadataStates();
}
updatePrinterOnlineStatus(true); // Printer is online
}
})
.catch(error => {
console.log('Error fetching printer status... setting Printer offline');
updatePrinterOnlineStatus(false); // Printer is offline
});
}, updateInterval);
}
// Start the polling process
startPolling();