feat: add mqtt screenshot image #133
This commit is contained in:
@@ -94,6 +94,7 @@ const init = async () => {
|
||||
initLastActive();
|
||||
|
||||
// Init client diagnostic
|
||||
initScreenshot();
|
||||
initHeartbeat();
|
||||
initErrors();
|
||||
initVersion();
|
||||
@@ -116,6 +117,7 @@ const init = async () => {
|
||||
updateDisplay();
|
||||
updateLastActive();
|
||||
});
|
||||
EVENTS.on("updateScreenshot", updateScreenshot);
|
||||
EVENTS.on("consoleLog", updateErrors);
|
||||
})
|
||||
.on("error", (error) => {
|
||||
@@ -452,10 +454,12 @@ const initDisplay = () => {
|
||||
unique_id: `${INTEGRATION.node}_display`,
|
||||
command_topic: `${root}/power/set`,
|
||||
state_topic: `${root}/power/state`,
|
||||
supported_color_modes: ["onoff"],
|
||||
icon: "mdi:monitor-shimmer",
|
||||
platform: "light",
|
||||
device: INTEGRATION.device,
|
||||
...(HARDWARE.support.displayBrightness && {
|
||||
supported_color_modes: ["brightness"],
|
||||
brightness_command_topic: `${root}/brightness/set`,
|
||||
brightness_state_topic: `${root}/brightness/state`,
|
||||
brightness_scale: 100,
|
||||
@@ -1050,6 +1054,33 @@ const updateLastActive = async () => {
|
||||
publishAttributes("last_active", tracker);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the page screenshot.
|
||||
*/
|
||||
const initScreenshot = () => {
|
||||
const root = `${INTEGRATION.root}/screenshot`;
|
||||
const config = {
|
||||
name: "Screenshot",
|
||||
unique_id: `${INTEGRATION.node}_screenshot`,
|
||||
image_topic: `${root}/state`,
|
||||
image_encoding: "b64",
|
||||
content_type: "image/png",
|
||||
entity_category: "diagnostic",
|
||||
icon: "mdi:image-area",
|
||||
device: INTEGRATION.device,
|
||||
};
|
||||
publishConfig("image", config);
|
||||
updateScreenshot();
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates the page screenshot via the mqtt connection.
|
||||
*/
|
||||
const updateScreenshot = async () => {
|
||||
const screenshot = WEBVIEW.tracker.screenshot;
|
||||
publishState("screenshot", screenshot);
|
||||
};
|
||||
|
||||
/**
|
||||
* Initializes the heartbeat sensor.
|
||||
*/
|
||||
|
||||
+58
-7
@@ -29,6 +29,7 @@ global.WEBVIEW = global.WEBVIEW || {
|
||||
widget: {
|
||||
focused: null,
|
||||
},
|
||||
screenshot: null,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -314,6 +315,11 @@ const updateView = () => {
|
||||
WEBVIEW.status.webContents.send("text-content", { id: "title", content: title });
|
||||
WEBVIEW.window.setTitle(title);
|
||||
|
||||
// Hide all other webviews and show only the active one
|
||||
WEBVIEW.views.forEach((view, i) => {
|
||||
view.setVisible(i === WEBVIEW.viewActive);
|
||||
});
|
||||
|
||||
// Update stored theme and zoom
|
||||
cookieStore("web-theme").then((value) => {
|
||||
if (value && value !== WEBVIEW.theme.get()) {
|
||||
@@ -326,9 +332,9 @@ const updateView = () => {
|
||||
}
|
||||
});
|
||||
|
||||
// Hide all other webviews and show only the active one
|
||||
WEBVIEW.views.forEach((view, i) => {
|
||||
view.setVisible(i === WEBVIEW.viewActive);
|
||||
// Update webview screenshot
|
||||
captureView(1000).then(() => {
|
||||
EVENTS.emit("updateScreenshot");
|
||||
});
|
||||
EVENTS.emit("updatePage");
|
||||
update();
|
||||
@@ -711,6 +717,11 @@ const resizeView = () => {
|
||||
theme: WEBVIEW.navigationTheme,
|
||||
});
|
||||
}
|
||||
|
||||
// Update webview screenshot
|
||||
captureView(1000).then(() => {
|
||||
EVENTS.emit("updateScreenshot");
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -802,8 +813,8 @@ const windowEvents = async () => {
|
||||
historyForward();
|
||||
});
|
||||
|
||||
// Check for window touch events (1s)
|
||||
setInterval(() => {
|
||||
// Check for window touch events (every full 1s)
|
||||
interval(() => {
|
||||
if (APP.exiting) {
|
||||
return;
|
||||
}
|
||||
@@ -1231,8 +1242,18 @@ const appEvents = async () => {
|
||||
console.error(`${details.type} Process ${details.reason} (code ${details.exitCode}): ${name}`);
|
||||
});
|
||||
|
||||
// Check latest release (2h)
|
||||
setInterval(() => {
|
||||
// Update latest screenshot (every full 1min)
|
||||
interval(() => {
|
||||
if (APP.exiting) {
|
||||
return;
|
||||
}
|
||||
captureView(5000).then(() => {
|
||||
EVENTS.emit("updateScreenshot");
|
||||
});
|
||||
}, 60 * 1000);
|
||||
|
||||
// Check latest release (every full 2h)
|
||||
interval(() => {
|
||||
if (APP.exiting) {
|
||||
return;
|
||||
}
|
||||
@@ -1341,6 +1362,22 @@ const cookieStore = async (key, value, view = WEBVIEW.views[WEBVIEW.viewActive])
|
||||
return !isNaN(Number(cookie.value)) ? Number(cookie.value) : cookie.value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Captures a webview screenshot as a base64 image.
|
||||
*
|
||||
* @param {number} wait - The time to wait before capturing in milliseconds.
|
||||
* @param {WebContentsView} view - The webview that captures the page.
|
||||
* @returns {Promise<string|null>} The base64 image of the captured page or null if failed.
|
||||
*/
|
||||
const captureView = async (wait, view = WEBVIEW.views[WEBVIEW.viewActive]) => {
|
||||
await new Promise((r) => setTimeout(r, wait));
|
||||
const image = await view.webContents.capturePage();
|
||||
const dataUrl = image.toDataURL();
|
||||
const dataString = dataUrl.replace(/^data:image\/\w+;base64,/, "").trim();
|
||||
WEBVIEW.tracker.screenshot = dataString || WEBVIEW.tracker.screenshot;
|
||||
return WEBVIEW.tracker.screenshot;
|
||||
};
|
||||
|
||||
/**
|
||||
* Generates a html template for a spinning loader.
|
||||
*
|
||||
@@ -1439,6 +1476,20 @@ const errorHtml = (code, text, url, theme) => {
|
||||
return `data:text/html;charset=utf-8,${encodeURIComponent(html)}`;
|
||||
};
|
||||
|
||||
/**
|
||||
* Interval function that runs at interval boundaries.
|
||||
*
|
||||
* @param {Function} callback - The function to execute.
|
||||
* @param {number} ms - The interval time in milliseconds.
|
||||
*/
|
||||
const interval = (callback, ms) => {
|
||||
const delay = ms - (Date.now() % ms);
|
||||
setTimeout(() => {
|
||||
callback();
|
||||
setInterval(callback, ms);
|
||||
}, delay);
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
init,
|
||||
update,
|
||||
|
||||
Reference in New Issue
Block a user