Compare commits

...

2 Commits

Author SHA1 Message Date
Bram Kragten
756a456c01 add test scanner 2024-04-08 14:09:04 +02:00
Bram Kragten
cfdbaac5d6 Update external barcode scanning API 2024-04-08 14:04:03 +02:00
4 changed files with 149 additions and 5 deletions

View File

@@ -9,7 +9,19 @@ import { fireEvent } from "../common/dom/fire_event";
import { mainWindow } from "../common/dom/get_main_window";
import { showAutomationEditor } from "../data/automation";
import { HomeAssistantMain } from "../layouts/home-assistant-main";
import type { EMIncomingMessageCommands } from "./external_messaging";
import type {
EMIncomingMessageBarCodeScanAborted,
EMIncomingMessageBarCodeScanResult,
EMIncomingMessageCommands,
} from "./external_messaging";
const barCodeListeners = new Set<
(
msg:
| EMIncomingMessageBarCodeScanResult
| EMIncomingMessageBarCodeScanAborted
) => boolean
>();
export const attachExternalToApp = (hassMainEl: HomeAssistantMain) => {
window.addEventListener("haptic", (ev) =>
@@ -24,6 +36,19 @@ export const attachExternalToApp = (hassMainEl: HomeAssistantMain) => {
);
};
export const addExternalBarCodeListener = (
listener: (
msg:
| EMIncomingMessageBarCodeScanResult
| EMIncomingMessageBarCodeScanAborted
) => boolean
) => {
barCodeListeners.add(listener);
return () => {
barCodeListeners.delete(listener);
};
};
const handleExternalMessage = (
hassMainEl: HomeAssistantMain,
msg: EMIncomingMessageCommands
@@ -88,6 +113,22 @@ const handleExternalMessage = (
success: true,
result: null,
});
} else if (msg.command === "bar_code/scan_result") {
barCodeListeners.forEach((listener) => listener(msg));
bus.fireMessage({
id: msg.id,
type: "result",
success: true,
result: null,
});
} else if (msg.command === "bar_code/aborted") {
barCodeListeners.forEach((listener) => listener(msg));
bus.fireMessage({
id: msg.id,
type: "result",
success: true,
result: null,
});
} else {
return false;
}

View File

@@ -37,9 +37,11 @@ interface EMOutgoingMessageConfigGet extends EMMessage {
interface EMOutgoingMessageBarCodeScan extends EMMessage {
type: "bar_code/scan";
title: string;
description: string;
alternative_option_label?: string;
payload: {
title: string;
description: string;
alternative_option_label?: string;
};
}
interface EMOutgoingMessageBarCodeClose extends EMMessage {
@@ -48,7 +50,9 @@ interface EMOutgoingMessageBarCodeClose extends EMMessage {
interface EMOutgoingMessageBarCodeNotify extends EMMessage {
type: "bar_code/notify";
message: string;
payload: {
message: string;
};
}
interface EMOutgoingMessageMatterCommission extends EMMessage {

View File

@@ -0,0 +1,98 @@
import "@material/mwc-ripple";
import { LitElement, html } from "lit";
import { customElement, state } from "lit/decorators";
import "../../../components/ha-card";
import { HomeAssistant } from "../../../types";
import { addExternalBarCodeListener } from "../../../external_app/external_app_entrypoint";
@customElement("test-scanner-card")
export class TestScannerCard extends LitElement {
public hass!: HomeAssistant;
@state() private _result: string[] = [];
private _removeListener?: () => void;
public getCardSize(): number {
return 4;
}
public setConfig(_config): void {}
protected render() {
if (!this.hass.auth.external?.config.hasBarCodeScanner) {
return html`
<ha-card>
<div class="card-content">
Barcode scanner not available, use a mobile app that has barcode
scanning support.
</div>
</ha-card>
`;
}
return html`
<ha-card>
<div class="card-content"><pre>${this._result.join("\r\n")}</pre></div>
<div class="card-actions">
<mwc-button @click=${this._openScanner}>Open scanner</mwc-button>
</div>
</ha-card>
`;
}
private _openScanner() {
this._removeListener = addExternalBarCodeListener((msg) => {
if (msg.command === "bar_code/scan_result") {
this._result = [
...this._result,
`Result: ${JSON.stringify(msg.payload)}`,
];
if (msg.payload.format !== "qr_code") {
this._notifyScanner(
`Wrong barcode scanned! ${msg.payload.format}: ${msg.payload.rawValue}, we need a QR code.`
);
} else {
this._closeScanner();
}
} else if (msg.command === "bar_code/aborted") {
this._removeListener!();
this._result = [
...this._result,
`Aborted: ${JSON.stringify(msg.payload)}`,
];
}
return true;
});
this.hass.auth.external!.fireMessage({
type: "bar_code/scan",
payload: {
title: "Scan test barcode",
description: "Scan a barcode to test the scanner.",
alternative_option_label: "Click to manually enter the test barcode",
},
});
}
private _closeScanner() {
this._removeListener!();
this.hass.auth.external!.fireMessage({
type: "bar_code/close",
});
}
private _notifyScanner(message: string) {
this.hass.auth.external!.fireMessage({
type: "bar_code/notify",
payload: {
message,
},
});
}
}
declare global {
interface HTMLElementTagNameMap {
"test-scanner-card": TestScannerCard;
}
}

View File

@@ -76,6 +76,7 @@ import { showSaveDialog } from "./editor/show-save-config-dialog";
import { isLegacyStrategyConfig } from "./strategies/legacy-strategy";
import { LocalizeKeys } from "../../common/translations/localize";
import { getLovelaceStrategy } from "./strategies/get-strategy";
import "./cards/test-scanner";
@customElement("hui-root")
class HUIRoot extends LitElement {