Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
aed79ab519 | ||
|
|
e2397bad65 | ||
|
|
e7622bef17 | ||
|
|
2553f52983 | ||
|
|
30b5ec2d8b | ||
|
|
94c7e34706 | ||
|
|
09dda65333 | ||
|
|
99f465a044 | ||
|
|
02d1309345 | ||
|
|
3142606d12 | ||
|
|
51189e8595 | ||
|
|
71a9d4c1de | ||
|
|
f022db9478 | ||
|
|
fcc0e5813e | ||
|
|
6d23efd713 |
+10
-5
@@ -1,20 +1,20 @@
|
|||||||
# Supported Hardware
|
# Supported Hardware
|
||||||
This document contains an incomplete list of device and display hardware combinations that are either intended to be tested or have already been tested.
|
This document contains an incomplete list of device and display hardware combinations that have already been tested.
|
||||||
|
|
||||||
The [release](https://github.com/leukipp/touchkio/releases) page has builds exclusively for **arm64** and **x64**, but custom builds for other architectures can be made (see [development](https://github.com/leukipp/touchkio?tab=readme-ov-file#development)), allowing the application to operate on any hardware.
|
The [release](https://github.com/leukipp/touchkio/releases) page has builds exclusively for **arm64** and **x64**, but custom builds for other architectures can be made (see [development](https://github.com/leukipp/touchkio?tab=readme-ov-file#development)), allowing the application to operate on any hardware.
|
||||||
At least the **minimal** features, such as displaying a **kiosk window** (which doesn't necessarily need to be Home Assistant) will work.
|
At least the **minimal** features, such as displaying a **kiosk window** (which doesn't necessarily need to be Home Assistant) will work.
|
||||||
|
|
||||||
## Hardware
|
## Hardware
|
||||||
If you are running Linux with a graphical user interface (Wayland or X11), you should be well equipped to use the application. Additionally, any single board computer (SBC) clones of the Raspberry Pi that operate on Raspberry Pi OS **(64-bit)** are likely to function properly as well.
|
If you are running Linux with a graphical user interface (Wayland or X11), you should be well equipped to use the application. Additionally, any single board computer (SBC) clones of the Raspberry Pi that operate on Raspberry Pi OS **(64-bit)** are likely to function as well.
|
||||||
|
|
||||||
| | Status | Notes |
|
| | Status | Notes |
|
||||||
| --- | --------------------- | ------------------------------------------------------------------------- |
|
| --- | --------------------- | ------------------------------------------------------------------------- |
|
||||||
| ⬜ | Unknown | Who knows. |
|
|
||||||
| 🟩 | Fully operational | Working display power, brightness and keyboard control via MQTT. |
|
| 🟩 | Fully operational | Working display power, brightness and keyboard control via MQTT. |
|
||||||
| 🟨 | Partially operational | Display brightness control is not available via MQTT. |
|
| 🟨 | Partially operational | Display brightness control is not available via MQTT. |
|
||||||
| 🟧 | Partially operational | Display brightness and keyboard control is not available via MQTT. |
|
| 🟧 | Partially operational | Display brightness and keyboard control is not available via MQTT. |
|
||||||
| 🟥 | Partially operational | Display power, brightness and keyboard control is not available via MQTT. |
|
| 🟥 | Partially operational | Display power, brightness and keyboard control is not available via MQTT. |
|
||||||
| ⬛ | Crashed | The house is on fire. |
|
| ⬜ | Somehow operational | Issues can occur and the overall performance is very slow. |
|
||||||
|
| ⬛ | Not operational | The house is on fire. |
|
||||||
|
|
||||||
### DSI
|
### DSI
|
||||||
| Device | System | Display | Status |
|
| Device | System | Display | Status |
|
||||||
@@ -28,9 +28,14 @@ If you are running Linux with a graphical user interface (Wayland or X11), you s
|
|||||||
|
|
||||||
### HDMI
|
### HDMI
|
||||||
| Device | System | Display | Status |
|
| Device | System | Display | Status |
|
||||||
| ---------------------- | -------------------------------------- | -------------------------------------------------------------------------------- | ------ |
|
| ------------------------ | -------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------ |
|
||||||
| Raspberry Pi 4 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [LAFVIN 5" Touch Display (800x480)](https://www.amazon.de/gp/product/B0BWJ8YP7S) | 🟨 |
|
| Raspberry Pi 4 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [LAFVIN 5" Touch Display (800x480)](https://www.amazon.de/gp/product/B0BWJ8YP7S) | 🟨 |
|
||||||
|
| Raspberry Pi 4 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [Waveshare 8" CAPLCD (768x1024)](https://www.waveshare.com/wiki/8inch_768x1024_LCD) | 🟨 |
|
||||||
|
| Raspberry Pi 4 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [Waveshare 7" 7EP-CAPLCD (1280x800)](https://www.waveshare.com/7ep-caplcd.htm) | 🟨 |
|
||||||
|
| Raspberry Pi 4 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [Hannspree HT225 21.5" (1920x1080)](https://www.hannspree.eu/product/HT-225-HPB) | 🟨 |
|
||||||
|
| Raspberry Pi 400 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [UPerfect Vertical Touch 15.6" (1920x1080)](https://uperfect.com/products/uperfect-y-vertical-monitor-15-6) | 🟨 |
|
||||||
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [GeeekPi 10.1" Capacitive Touch (1280x800)](https://www.amazon.nl/dp/B0DHV6DZC1) | 🟨 |
|
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [GeeekPi 10.1" Capacitive Touch (1280x800)](https://www.amazon.nl/dp/B0DHV6DZC1) | 🟨 |
|
||||||
|
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | [Portable Touch 18.5" FHD (1920x1080)](https://www.amazon.de/dp/B0CT2KLDBQ) | 🟨 |
|
||||||
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | Generic Non-Touch | 🟨 |
|
| Raspberry Pi 5 (arm64) | Raspberry Pi OS (64-bit), Wayland, X11 | Generic Non-Touch | 🟨 |
|
||||||
| Generic PC (x64) | Ubuntu (64-bit), X11 | Generic Non-Touch | 🟧 |
|
| Generic PC (x64) | Ubuntu (64-bit), X11 | Generic Non-Touch | 🟧 |
|
||||||
| Generic PC (x64) | Ubuntu (64-bit), Wayland | Generic Non-Touch | 🟥 |
|
| Generic PC (x64) | Ubuntu (64-bit), Wayland | Generic Non-Touch | 🟥 |
|
||||||
|
|||||||
@@ -48,11 +48,19 @@ If your hardware is [supported](https://github.com/leukipp/touchkio/blob/main/HA
|
|||||||
|
|
||||||
#### Option 1 - The easy way
|
#### Option 1 - The easy way
|
||||||
Run this command to download and install the latest **.deb** (arm64 or x64) release.
|
Run this command to download and install the latest **.deb** (arm64 or x64) release.
|
||||||
It will also create a systemd file for auto-startup and will guide you through the setup process:
|
It will also create a systemd user file for auto-startup and will guide you through the setup process:
|
||||||
```bash
|
```bash
|
||||||
bash <(wget -qO- https://raw.githubusercontent.com/leukipp/touchkio/main/install.sh)
|
bash <(wget -qO- https://raw.githubusercontent.com/leukipp/touchkio/main/install.sh)
|
||||||
```
|
```
|
||||||
|
Make sure that you run this with your **standard user** and not with root (sudo).
|
||||||
If you are paranoid, or smart, or both, have a look into the [install.sh](https://github.com/leukipp/touchkio/blob/main/install.sh) script before executing external code on your machine.
|
If you are paranoid, or smart, or both, have a look into the [install.sh](https://github.com/leukipp/touchkio/blob/main/install.sh) script before executing external code on your machine.
|
||||||
|
The script can also be re-run to **update** an existing installation to the latest version.
|
||||||
|
|
||||||
|
The systemd **user service** is enabled by default and the kiosk application should start automatically the next time you boot.
|
||||||
|
If you need manual control use:
|
||||||
|
```bash
|
||||||
|
systemctl --user start|stop|status|restart touchkio.service
|
||||||
|
```
|
||||||
|
|
||||||
<details><summary>Alternatives</summary><div>
|
<details><summary>Alternatives</summary><div>
|
||||||
|
|
||||||
@@ -72,7 +80,7 @@ The [install.sh](https://github.com/leukipp/touchkio/blob/main/install.sh) scrip
|
|||||||
Pre-built release files are available for arm64 and x64 Linux systems.
|
Pre-built release files are available for arm64 and x64 Linux systems.
|
||||||
If you are using a different architecture, you can still utilize this repository to build your own application.
|
If you are using a different architecture, you can still utilize this repository to build your own application.
|
||||||
|
|
||||||
For more information, please refer to the [development](https://github.com/leukipp/touchkio?tab=readme-ov-file#development) section, however this will do the job:
|
For more information please refer to the [development](https://github.com/leukipp/touchkio?tab=readme-ov-file#development) section, however this will do the job:
|
||||||
```bash
|
```bash
|
||||||
yarn build
|
yarn build
|
||||||
```
|
```
|
||||||
@@ -128,7 +136,7 @@ If you connect to your device via SSH, you may have to export display variables
|
|||||||
export DISPLAY=":0"
|
export DISPLAY=":0"
|
||||||
export WAYLAND_DISPLAY="wayland-0"
|
export WAYLAND_DISPLAY="wayland-0"
|
||||||
```
|
```
|
||||||
To make this permanent, consider adding the export variables to the `~/.bashrc` file.
|
To make this permanent, consider adding the export variables into the `~/.bashrc` file.
|
||||||
|
|
||||||
### Extensions
|
### Extensions
|
||||||
|
|
||||||
@@ -181,7 +189,7 @@ I managed to achieve this for the `brightness` file by implementing a simple `fs
|
|||||||
However, I found that it **never triggered** for the `bl_power` file.
|
However, I found that it **never triggered** for the `bl_power` file.
|
||||||
Although the file content changes, none of the filesystem listeners where fired.
|
Although the file content changes, none of the filesystem listeners where fired.
|
||||||
This could be due to `swayidle`/`wlopm` performing write actions at a deeper level that are not detectable by file listeners.
|
This could be due to `swayidle`/`wlopm` performing write actions at a deeper level that are not detectable by file listeners.
|
||||||
As a result, I went for a **polling solution**, checking the state of the file every **500 milliseconds** for any changes.
|
As a result, I went for a **polling solution**, checking the state of the file **every second** for any changes.
|
||||||
While I understand this is not ideal, it's necessary to ensure proper functionality.
|
While I understand this is not ideal, it's necessary to ensure proper functionality.
|
||||||
|
|
||||||
The display power status and brightness can be adjusted via the MQTT integration.
|
The display power status and brightness can be adjusted via the MQTT integration.
|
||||||
|
|||||||
@@ -7,6 +7,16 @@ const hardware = require("./src/hardware");
|
|||||||
const webview = require("./src/webview");
|
const webview = require("./src/webview");
|
||||||
const { app } = require("electron");
|
const { app } = require("electron");
|
||||||
|
|
||||||
|
global.ARGS = global.ARGS || {};
|
||||||
|
|
||||||
|
if (!process.env.DISPLAY) {
|
||||||
|
console.error(`$DISPLAY variable not set to run the GUI application, are you connected via SSH?`);
|
||||||
|
console.error(`If you have installed the service use:`);
|
||||||
|
console.error(` systemctl --user start touchkio.service`);
|
||||||
|
console.error(`Alternatively export the variables first:`);
|
||||||
|
console.error(` export DISPLAY=":0" && export WAYLAND_DISPLAY="wayland-0" && touchkio\n`);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This promise resolves when the app has finished initializing,
|
* This promise resolves when the app has finished initializing,
|
||||||
* allowing to safely create browser windows and perform other
|
* allowing to safely create browser windows and perform other
|
||||||
@@ -34,14 +44,15 @@ app.whenReady().then(async () => {
|
|||||||
} else if (!argsProvided && argsFileExists) {
|
} else if (!argsProvided && argsFileExists) {
|
||||||
args = readArgs(argsFilePath);
|
args = readArgs(argsFilePath);
|
||||||
}
|
}
|
||||||
|
global.ARGS = args;
|
||||||
|
|
||||||
// Show used arguments
|
// Show used arguments
|
||||||
console.log(`Arguments: ${JSON.stringify(args, null, 2)}`);
|
console.log(`Arguments: ${JSON.stringify(global.ARGS, null, 2)}`);
|
||||||
|
|
||||||
// Chained init functions
|
// Chained init functions
|
||||||
const chained = [webview.init, hardware.init, integration.init];
|
const chained = [webview.init, hardware.init, integration.init];
|
||||||
for (const init of chained) {
|
for (const init of chained) {
|
||||||
if (!(await init(args))) {
|
if (!(await init())) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -227,4 +238,6 @@ const decrypt = (value) => {
|
|||||||
* @param {number} ms - Sleep time in milliseconds.
|
* @param {number} ms - Sleep time in milliseconds.
|
||||||
* @returns {Promise} A promise resolving after the timeout.
|
* @returns {Promise} A promise resolving after the timeout.
|
||||||
*/
|
*/
|
||||||
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
const sleep = (ms) => {
|
||||||
|
return new Promise((r) => setTimeout(r, ms));
|
||||||
|
};
|
||||||
|
|||||||
@@ -102,4 +102,7 @@ read -p "Start touchkio setup? (Y/n) " answer
|
|||||||
if [[ ${answer:-y} == [Yy]* ]]; then
|
if [[ ${answer:-y} == [Yy]* ]]; then
|
||||||
echo "/usr/bin/touchkio --setup"
|
echo "/usr/bin/touchkio --setup"
|
||||||
/usr/bin/touchkio --setup
|
/usr/bin/touchkio --setup
|
||||||
|
else
|
||||||
|
echo "/usr/bin/touchkio"
|
||||||
|
/usr/bin/touchkio
|
||||||
fi
|
fi
|
||||||
|
|||||||
+1
-1
@@ -3,7 +3,7 @@
|
|||||||
"description": "Home Assistant Touch Kiosk",
|
"description": "Home Assistant Touch Kiosk",
|
||||||
"homepage": "https://github.com/leukipp/touchkio",
|
"homepage": "https://github.com/leukipp/touchkio",
|
||||||
"author": "leukipp",
|
"author": "leukipp",
|
||||||
"version": "1.1.1",
|
"version": "1.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
+35
-15
@@ -1,11 +1,12 @@
|
|||||||
const os = require("os");
|
const os = require("os");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const process = require("child_process");
|
const fsp = require("fs/promises");
|
||||||
|
const cpr = require("child_process");
|
||||||
|
|
||||||
global.HARDWARE = global.HARDWARE || {
|
global.HARDWARE = global.HARDWARE || {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
status: "invalid",
|
status: null,
|
||||||
session: {},
|
session: {},
|
||||||
support: {},
|
support: {},
|
||||||
display: {
|
display: {
|
||||||
@@ -29,10 +30,9 @@ global.HARDWARE = global.HARDWARE || {
|
|||||||
/**
|
/**
|
||||||
* Initializes the hardware with the provided arguments.
|
* Initializes the hardware with the provided arguments.
|
||||||
*
|
*
|
||||||
* @param {Object} args - The command-line arguments to customize the initialization process.
|
|
||||||
* @returns {boolean} Returns true if the initialization was successful.
|
* @returns {boolean} Returns true if the initialization was successful.
|
||||||
*/
|
*/
|
||||||
const init = async (args) => {
|
const init = async () => {
|
||||||
if (!compatibleDevice()) {
|
if (!compatibleDevice()) {
|
||||||
console.warn("Device not supported");
|
console.warn("Device not supported");
|
||||||
return false;
|
return false;
|
||||||
@@ -48,7 +48,7 @@ const init = async (args) => {
|
|||||||
HARDWARE.display.brightness.max = getDisplayBrightnessMax();
|
HARDWARE.display.brightness.max = getDisplayBrightnessMax();
|
||||||
HARDWARE.support.keyboardVisibility = processRuns("squeekboard");
|
HARDWARE.support.keyboardVisibility = processRuns("squeekboard");
|
||||||
HARDWARE.initialized = true;
|
HARDWARE.initialized = true;
|
||||||
HARDWARE.status = "valid";
|
HARDWARE.status = "Supported";
|
||||||
|
|
||||||
// Show supported features
|
// Show supported features
|
||||||
console.log(`Supported: ${JSON.stringify(HARDWARE.support, null, 2)}`);
|
console.log(`Supported: ${JSON.stringify(HARDWARE.support, null, 2)}`);
|
||||||
@@ -91,7 +91,7 @@ const init = async (args) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Check for display changes
|
// Check for display changes
|
||||||
setInterval(update, 500);
|
interval(update, 1000);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
@@ -99,14 +99,14 @@ const init = async (args) => {
|
|||||||
/**
|
/**
|
||||||
* Updates the shared hardware properties.
|
* Updates the shared hardware properties.
|
||||||
*/
|
*/
|
||||||
const update = () => {
|
const update = async () => {
|
||||||
if (!HARDWARE.initialized) {
|
if (!HARDWARE.initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display status has changed
|
// Display status has changed
|
||||||
if (HARDWARE.support.displayStatus) {
|
if (HARDWARE.support.displayStatus) {
|
||||||
const status = fs.readFileSync(`${HARDWARE.display.status.path}/dpms`, "utf8").trim();
|
const status = (await fsp.readFile(`${HARDWARE.display.status.path}/dpms`, "utf8")).trim();
|
||||||
if (status !== HARDWARE.display.status.value) {
|
if (status !== HARDWARE.display.status.value) {
|
||||||
console.log("Update Display Status:", getDisplayStatus());
|
console.log("Update Display Status:", getDisplayStatus());
|
||||||
HARDWARE.display.status.value = status;
|
HARDWARE.display.status.value = status;
|
||||||
@@ -118,7 +118,7 @@ const update = () => {
|
|||||||
|
|
||||||
// Display brightness has changed
|
// Display brightness has changed
|
||||||
if (HARDWARE.support.displayBrightness) {
|
if (HARDWARE.support.displayBrightness) {
|
||||||
const brightness = fs.readFileSync(`${HARDWARE.display.brightness.path}/brightness`, "utf8").trim();
|
const brightness = (await fsp.readFile(`${HARDWARE.display.brightness.path}/brightness`, "utf8")).trim();
|
||||||
if (brightness !== HARDWARE.display.brightness.value) {
|
if (brightness !== HARDWARE.display.brightness.value) {
|
||||||
console.log("Update Display Brightness:", getDisplayBrightness());
|
console.log("Update Display Brightness:", getDisplayBrightness());
|
||||||
HARDWARE.display.brightness.value = brightness;
|
HARDWARE.display.brightness.value = brightness;
|
||||||
@@ -533,7 +533,7 @@ const rebootSystem = (callback = null) => {
|
|||||||
*/
|
*/
|
||||||
const processRuns = (name) => {
|
const processRuns = (name) => {
|
||||||
try {
|
try {
|
||||||
return !!process.execSync(`pidof ${name}`, { encoding: "utf8" });
|
return !!cpr.execSync(`pidof ${name}`, { encoding: "utf8" });
|
||||||
} catch {}
|
} catch {}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -546,7 +546,7 @@ const processRuns = (name) => {
|
|||||||
*/
|
*/
|
||||||
const commandExists = (name) => {
|
const commandExists = (name) => {
|
||||||
try {
|
try {
|
||||||
return !!process.execSync(`which ${name}`, { encoding: "utf8" });
|
return !!cpr.execSync(`which ${name}`, { encoding: "utf8" });
|
||||||
} catch {}
|
} catch {}
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
@@ -560,7 +560,7 @@ const commandExists = (name) => {
|
|||||||
*/
|
*/
|
||||||
const execSyncCommand = (cmd, args = []) => {
|
const execSyncCommand = (cmd, args = []) => {
|
||||||
try {
|
try {
|
||||||
const output = process.execSync([cmd, ...args].join(" "), { encoding: "utf8" });
|
const output = cpr.execSync([cmd, ...args].join(" "), { encoding: "utf8" });
|
||||||
return output.trim().replace(/\0/g, "");
|
return output.trim().replace(/\0/g, "");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Execute Sync:", error.message);
|
console.error("Execute Sync:", error.message);
|
||||||
@@ -579,7 +579,7 @@ const execSyncCommand = (cmd, args = []) => {
|
|||||||
const execAsyncCommand = (cmd, args = [], callback = null) => {
|
const execAsyncCommand = (cmd, args = [], callback = null) => {
|
||||||
let errorOutput = "";
|
let errorOutput = "";
|
||||||
let successOutput = "";
|
let successOutput = "";
|
||||||
let proc = process.spawn(cmd, args);
|
let proc = cpr.spawn(cmd, args);
|
||||||
proc.stderr.on("data", (data) => {
|
proc.stderr.on("data", (data) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
errorOutput += data.toString();
|
errorOutput += data.toString();
|
||||||
@@ -623,7 +623,7 @@ const dbusCall = (path, method, values, callback = null) => {
|
|||||||
const dest = `${iface} ${path} ${iface}.${method} ${values.join(" ")}`;
|
const dest = `${iface} ${path} ${iface}.${method} ${values.join(" ")}`;
|
||||||
const args = ["--print-reply", "--type=method_call", `--dest=${dest}`];
|
const args = ["--print-reply", "--type=method_call", `--dest=${dest}`];
|
||||||
try {
|
try {
|
||||||
const output = process.execSync([cmd, ...args].join(" "), { encoding: "utf8" });
|
const output = cpr.execSync([cmd, ...args].join(" "), { encoding: "utf8" });
|
||||||
if (typeof callback === "function") {
|
if (typeof callback === "function") {
|
||||||
callback(output.trim().replace(/\0/g, ""), null);
|
callback(output.trim().replace(/\0/g, ""), null);
|
||||||
}
|
}
|
||||||
@@ -645,7 +645,7 @@ const dbusCall = (path, method, values, callback = null) => {
|
|||||||
const dbusMonitor = (path, callback) => {
|
const dbusMonitor = (path, callback) => {
|
||||||
const cmd = "dbus-monitor";
|
const cmd = "dbus-monitor";
|
||||||
const args = [`interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='${path}'`];
|
const args = [`interface='org.freedesktop.DBus.Properties',member='PropertiesChanged',path='${path}'`];
|
||||||
const proc = process.spawn(cmd, args);
|
const proc = cpr.spawn(cmd, args);
|
||||||
proc.stdout.on("data", (data) => {
|
proc.stdout.on("data", (data) => {
|
||||||
try {
|
try {
|
||||||
const signal = data.toString();
|
const signal = data.toString();
|
||||||
@@ -681,6 +681,26 @@ const dbusMonitor = (path, callback) => {
|
|||||||
return proc;
|
return proc;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper function for asynchronous interval calls.
|
||||||
|
*
|
||||||
|
* @param {function} callback - An async callback function.
|
||||||
|
* @param {number} ms - Sleep time in milliseconds.
|
||||||
|
*/
|
||||||
|
const interval = (callback, ms) => {
|
||||||
|
const run = () => {
|
||||||
|
setTimeout(async () => {
|
||||||
|
try {
|
||||||
|
await callback();
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Interval Callback:", error.message);
|
||||||
|
}
|
||||||
|
run();
|
||||||
|
}, ms);
|
||||||
|
};
|
||||||
|
run();
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
init,
|
init,
|
||||||
update,
|
update,
|
||||||
|
|||||||
+13
-12
@@ -4,27 +4,26 @@ const { app } = require("electron");
|
|||||||
|
|
||||||
global.INTEGRATION = global.INTEGRATION || {
|
global.INTEGRATION = global.INTEGRATION || {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
status: "offline",
|
status: null,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the integration with the provided arguments.
|
* Initializes the integration with the provided arguments.
|
||||||
*
|
*
|
||||||
* @param {Object} args - The command-line arguments to customize the initialization process.
|
|
||||||
* @returns {boolean} Returns true if the initialization was successful.
|
* @returns {boolean} Returns true if the initialization was successful.
|
||||||
*/
|
*/
|
||||||
const init = async (args) => {
|
const init = async () => {
|
||||||
if (!args.mqtt_url) {
|
if (!ARGS.mqtt_url) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!/^mqtts?:\/\//.test(args.mqtt_url)) {
|
if (!/^mqtts?:\/\//.test(ARGS.mqtt_url)) {
|
||||||
console.error("Please provide the '--mqtt-url' parameter with mqtt(s)");
|
console.error("Please provide the '--mqtt-url' parameter with mqtt(s)");
|
||||||
return app.quit();
|
return app.quit();
|
||||||
}
|
}
|
||||||
const url = new URL(args.mqtt_url);
|
const url = new URL(ARGS.mqtt_url);
|
||||||
const user = args.mqtt_user ? args.mqtt_user : null;
|
const user = ARGS.mqtt_user ? ARGS.mqtt_user : null;
|
||||||
const password = args.mqtt_password ? args.mqtt_password : null;
|
const password = ARGS.mqtt_password ? ARGS.mqtt_password : null;
|
||||||
const discovery = args.mqtt_discovery ? args.mqtt_discovery : "homeassistant";
|
const discovery = ARGS.mqtt_discovery ? ARGS.mqtt_discovery : "homeassistant";
|
||||||
|
|
||||||
const model = hardware.getModel();
|
const model = hardware.getModel();
|
||||||
const vendor = hardware.getVendor();
|
const vendor = hardware.getVendor();
|
||||||
@@ -81,11 +80,11 @@ const init = async (args) => {
|
|||||||
|
|
||||||
// Integration initialized
|
// Integration initialized
|
||||||
INTEGRATION.initialized = true;
|
INTEGRATION.initialized = true;
|
||||||
INTEGRATION.status = "online";
|
INTEGRATION.status = "Online";
|
||||||
})
|
})
|
||||||
.on("error", (error) => {
|
.on("error", (error) => {
|
||||||
console.error("MQTT:", error);
|
console.error("MQTT:", error);
|
||||||
INTEGRATION.status = "offline";
|
INTEGRATION.status = "Offline";
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update sensor states from notifiers
|
// Update sensor states from notifiers
|
||||||
@@ -118,7 +117,7 @@ const init = async (args) => {
|
|||||||
/**
|
/**
|
||||||
* Updates the shared integration properties.
|
* Updates the shared integration properties.
|
||||||
*/
|
*/
|
||||||
const update = () => {
|
const update = async () => {
|
||||||
if (!INTEGRATION.initialized) {
|
if (!INTEGRATION.initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -308,10 +307,12 @@ const initDisplay = (client) => {
|
|||||||
const status = message.toString();
|
const status = message.toString();
|
||||||
console.log("Set Display Status:", status);
|
console.log("Set Display Status:", status);
|
||||||
hardware.setDisplayStatus(status);
|
hardware.setDisplayStatus(status);
|
||||||
|
hardware.update();
|
||||||
} else if (topic === `${root}/brightness/set`) {
|
} else if (topic === `${root}/brightness/set`) {
|
||||||
const brightness = parseInt(message, 10);
|
const brightness = parseInt(message, 10);
|
||||||
console.log("Set Display Brightness:", brightness);
|
console.log("Set Display Brightness:", brightness);
|
||||||
hardware.setDisplayBrightness(brightness);
|
hardware.setDisplayBrightness(brightness);
|
||||||
|
hardware.update();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.subscribe(`${root}/set`)
|
.subscribe(`${root}/set`)
|
||||||
|
|||||||
+17
-12
@@ -5,7 +5,7 @@ const { app, screen, nativeTheme, ipcMain, BaseWindow, WebContentsView } = requi
|
|||||||
|
|
||||||
global.WEBVIEW = global.WEBVIEW || {
|
global.WEBVIEW = global.WEBVIEW || {
|
||||||
initialized: false,
|
initialized: false,
|
||||||
status: "offline",
|
status: null,
|
||||||
locked: false,
|
locked: false,
|
||||||
pointer: {
|
pointer: {
|
||||||
position: {},
|
position: {},
|
||||||
@@ -16,22 +16,22 @@ global.WEBVIEW = global.WEBVIEW || {
|
|||||||
/**
|
/**
|
||||||
* Initializes the webview with the provided arguments.
|
* Initializes the webview with the provided arguments.
|
||||||
*
|
*
|
||||||
* @param {Object} args - The command-line arguments to customize the initialization process.
|
|
||||||
* @returns {boolean} Returns true if the initialization was successful.
|
* @returns {boolean} Returns true if the initialization was successful.
|
||||||
*/
|
*/
|
||||||
const init = async (args) => {
|
const init = async () => {
|
||||||
if (!args.web_url) {
|
if (!ARGS.web_url) {
|
||||||
console.error("Please provide the '--web-url' parameter");
|
console.error("Please provide the '--web-url' parameter");
|
||||||
return app.quit();
|
return app.quit();
|
||||||
}
|
}
|
||||||
if (!/^https?:\/\//.test(args.web_url)) {
|
if (!/^https?:\/\//.test(ARGS.web_url)) {
|
||||||
console.error("Please provide the '--web-url' parameter with http(s)");
|
console.error("Please provide the '--web-url' parameter with http(s)");
|
||||||
return app.quit();
|
return app.quit();
|
||||||
}
|
}
|
||||||
const url = new URL(args.web_url);
|
const url = new URL(ARGS.web_url);
|
||||||
const theme = ["light", "dark"].includes(args.web_theme) ? args.web_theme : "dark";
|
const theme = ["light", "dark"].includes(ARGS.web_theme) ? ARGS.web_theme : "dark";
|
||||||
const zoom = !isNaN(parseFloat(args.web_zoom)) ? parseFloat(args.web_zoom) : 1.25;
|
const zoom = !isNaN(parseFloat(ARGS.web_zoom)) ? parseFloat(ARGS.web_zoom) : 1.25;
|
||||||
const widget = args.web_widget ? args.web_widget === "true" : true;
|
const widget = ARGS.web_widget ? ARGS.web_widget === "true" : true;
|
||||||
|
const fullscreen = ARGS.app_debug !== "true";
|
||||||
|
|
||||||
// Init global layout
|
// Init global layout
|
||||||
WEBVIEW.viewZoom = zoom;
|
WEBVIEW.viewZoom = zoom;
|
||||||
@@ -46,7 +46,10 @@ const init = async (args) => {
|
|||||||
icon: path.join(__dirname, "..", "img", "icon.png"),
|
icon: path.join(__dirname, "..", "img", "icon.png"),
|
||||||
});
|
});
|
||||||
WEBVIEW.window.setMenuBarVisibility(false);
|
WEBVIEW.window.setMenuBarVisibility(false);
|
||||||
WEBVIEW.window.setFullScreen(true);
|
WEBVIEW.window.setFullScreen(fullscreen);
|
||||||
|
if (!fullscreen) {
|
||||||
|
WEBVIEW.window.maximize();
|
||||||
|
}
|
||||||
|
|
||||||
// Init global webview
|
// Init global webview
|
||||||
WEBVIEW.view = new WebContentsView({
|
WEBVIEW.view = new WebContentsView({
|
||||||
@@ -83,7 +86,7 @@ const init = async (args) => {
|
|||||||
/**
|
/**
|
||||||
* Updates the shared webview properties.
|
* Updates the shared webview properties.
|
||||||
*/
|
*/
|
||||||
const update = () => {
|
const update = async () => {
|
||||||
if (!WEBVIEW.initialized) {
|
if (!WEBVIEW.initialized) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -288,7 +291,9 @@ const domEvents = () => {
|
|||||||
|
|
||||||
// Webview fully loaded
|
// Webview fully loaded
|
||||||
WEBVIEW.view.webContents.on("did-finish-load", () => {
|
WEBVIEW.view.webContents.on("did-finish-load", () => {
|
||||||
// view.webContents.openDevTools();
|
if (ARGS.app_debug === "true") {
|
||||||
|
WEBVIEW.view.webContents.openDevTools();
|
||||||
|
}
|
||||||
WEBVIEW.initialized = true;
|
WEBVIEW.initialized = true;
|
||||||
update();
|
update();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user