feat: add mqtt screenshot image #133
This commit is contained in:
@@ -94,6 +94,7 @@ const init = async () => {
|
|||||||
initLastActive();
|
initLastActive();
|
||||||
|
|
||||||
// Init client diagnostic
|
// Init client diagnostic
|
||||||
|
initScreenshot();
|
||||||
initHeartbeat();
|
initHeartbeat();
|
||||||
initErrors();
|
initErrors();
|
||||||
initVersion();
|
initVersion();
|
||||||
@@ -116,6 +117,7 @@ const init = async () => {
|
|||||||
updateDisplay();
|
updateDisplay();
|
||||||
updateLastActive();
|
updateLastActive();
|
||||||
});
|
});
|
||||||
|
EVENTS.on("updateScreenshot", updateScreenshot);
|
||||||
EVENTS.on("consoleLog", updateErrors);
|
EVENTS.on("consoleLog", updateErrors);
|
||||||
})
|
})
|
||||||
.on("error", (error) => {
|
.on("error", (error) => {
|
||||||
@@ -452,10 +454,12 @@ const initDisplay = () => {
|
|||||||
unique_id: `${INTEGRATION.node}_display`,
|
unique_id: `${INTEGRATION.node}_display`,
|
||||||
command_topic: `${root}/power/set`,
|
command_topic: `${root}/power/set`,
|
||||||
state_topic: `${root}/power/state`,
|
state_topic: `${root}/power/state`,
|
||||||
|
supported_color_modes: ["onoff"],
|
||||||
icon: "mdi:monitor-shimmer",
|
icon: "mdi:monitor-shimmer",
|
||||||
platform: "light",
|
platform: "light",
|
||||||
device: INTEGRATION.device,
|
device: INTEGRATION.device,
|
||||||
...(HARDWARE.support.displayBrightness && {
|
...(HARDWARE.support.displayBrightness && {
|
||||||
|
supported_color_modes: ["brightness"],
|
||||||
brightness_command_topic: `${root}/brightness/set`,
|
brightness_command_topic: `${root}/brightness/set`,
|
||||||
brightness_state_topic: `${root}/brightness/state`,
|
brightness_state_topic: `${root}/brightness/state`,
|
||||||
brightness_scale: 100,
|
brightness_scale: 100,
|
||||||
@@ -1050,6 +1054,33 @@ const updateLastActive = async () => {
|
|||||||
publishAttributes("last_active", tracker);
|
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.
|
* Initializes the heartbeat sensor.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+58
-7
@@ -29,6 +29,7 @@ global.WEBVIEW = global.WEBVIEW || {
|
|||||||
widget: {
|
widget: {
|
||||||
focused: null,
|
focused: null,
|
||||||
},
|
},
|
||||||
|
screenshot: null,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -314,6 +315,11 @@ const updateView = () => {
|
|||||||
WEBVIEW.status.webContents.send("text-content", { id: "title", content: title });
|
WEBVIEW.status.webContents.send("text-content", { id: "title", content: title });
|
||||||
WEBVIEW.window.setTitle(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
|
// Update stored theme and zoom
|
||||||
cookieStore("web-theme").then((value) => {
|
cookieStore("web-theme").then((value) => {
|
||||||
if (value && value !== WEBVIEW.theme.get()) {
|
if (value && value !== WEBVIEW.theme.get()) {
|
||||||
@@ -326,9 +332,9 @@ const updateView = () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Hide all other webviews and show only the active one
|
// Update webview screenshot
|
||||||
WEBVIEW.views.forEach((view, i) => {
|
captureView(1000).then(() => {
|
||||||
view.setVisible(i === WEBVIEW.viewActive);
|
EVENTS.emit("updateScreenshot");
|
||||||
});
|
});
|
||||||
EVENTS.emit("updatePage");
|
EVENTS.emit("updatePage");
|
||||||
update();
|
update();
|
||||||
@@ -711,6 +717,11 @@ const resizeView = () => {
|
|||||||
theme: WEBVIEW.navigationTheme,
|
theme: WEBVIEW.navigationTheme,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update webview screenshot
|
||||||
|
captureView(1000).then(() => {
|
||||||
|
EVENTS.emit("updateScreenshot");
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -802,8 +813,8 @@ const windowEvents = async () => {
|
|||||||
historyForward();
|
historyForward();
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check for window touch events (1s)
|
// Check for window touch events (every full 1s)
|
||||||
setInterval(() => {
|
interval(() => {
|
||||||
if (APP.exiting) {
|
if (APP.exiting) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1231,8 +1242,18 @@ const appEvents = async () => {
|
|||||||
console.error(`${details.type} Process ${details.reason} (code ${details.exitCode}): ${name}`);
|
console.error(`${details.type} Process ${details.reason} (code ${details.exitCode}): ${name}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Check latest release (2h)
|
// Update latest screenshot (every full 1min)
|
||||||
setInterval(() => {
|
interval(() => {
|
||||||
|
if (APP.exiting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
captureView(5000).then(() => {
|
||||||
|
EVENTS.emit("updateScreenshot");
|
||||||
|
});
|
||||||
|
}, 60 * 1000);
|
||||||
|
|
||||||
|
// Check latest release (every full 2h)
|
||||||
|
interval(() => {
|
||||||
if (APP.exiting) {
|
if (APP.exiting) {
|
||||||
return;
|
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;
|
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.
|
* 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)}`;
|
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 = {
|
module.exports = {
|
||||||
init,
|
init,
|
||||||
update,
|
update,
|
||||||
|
|||||||
Reference in New Issue
Block a user