mirror of
https://github.com/ckaczor/HomeMonitor.git
synced 2026-01-13 17:22:54 -05:00
Kiosk improvements
This commit is contained in:
@@ -17,6 +17,7 @@
|
|||||||
"axios": "^1.7.9",
|
"axios": "^1.7.9",
|
||||||
"core-js": "^3.39.0",
|
"core-js": "^3.39.0",
|
||||||
"date-fns": "^3.6.0",
|
"date-fns": "^3.6.0",
|
||||||
|
"home-assistant-js-websocket": "^9.4.0",
|
||||||
"pinia": "^2.3.0",
|
"pinia": "^2.3.0",
|
||||||
"roboto-fontface": "^0.10.0",
|
"roboto-fontface": "^0.10.0",
|
||||||
"suncalc": "^1.9.0",
|
"suncalc": "^1.9.0",
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
"vite": "^5.4.11",
|
"vite": "^5.4.11",
|
||||||
"vite-plugin-vuetify": "^2.0.4",
|
"vite-plugin-vuetify": "^2.0.4",
|
||||||
"vue-router": "^4.5.0",
|
"vue-router": "^4.5.0",
|
||||||
"vue-tsc": "^2.1.10",
|
"vue-tsc": "^2.1.10"
|
||||||
"websocketstream-polyfill": "^1.0.1"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
16
WebDisplay/pnpm-lock.yaml
generated
16
WebDisplay/pnpm-lock.yaml
generated
@@ -32,6 +32,9 @@ importers:
|
|||||||
date-fns:
|
date-fns:
|
||||||
specifier: ^3.6.0
|
specifier: ^3.6.0
|
||||||
version: 3.6.0
|
version: 3.6.0
|
||||||
|
home-assistant-js-websocket:
|
||||||
|
specifier: ^9.4.0
|
||||||
|
version: 9.4.0
|
||||||
pinia:
|
pinia:
|
||||||
specifier: ^2.3.0
|
specifier: ^2.3.0
|
||||||
version: 2.3.0(typescript@5.6.2)(vue@3.5.13(typescript@5.6.2))
|
version: 2.3.0(typescript@5.6.2)(vue@3.5.13(typescript@5.6.2))
|
||||||
@@ -114,9 +117,6 @@ importers:
|
|||||||
vue-tsc:
|
vue-tsc:
|
||||||
specifier: ^2.1.10
|
specifier: ^2.1.10
|
||||||
version: 2.1.10(typescript@5.6.2)
|
version: 2.1.10(typescript@5.6.2)
|
||||||
websocketstream-polyfill:
|
|
||||||
specifier: ^1.0.1
|
|
||||||
version: 1.0.1
|
|
||||||
|
|
||||||
packages:
|
packages:
|
||||||
|
|
||||||
@@ -1310,6 +1310,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
home-assistant-js-websocket@9.4.0:
|
||||||
|
resolution: {integrity: sha512-312TuI63IfKf8G+iWvKmPYIdxWMNojwVk03o9OSpQFFDjSCNAYdCUfuPCFs73SuJ1Xpd4D1Eo11CB33MGMqZ+Q==}
|
||||||
|
|
||||||
ignore@5.3.2:
|
ignore@5.3.2:
|
||||||
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
|
||||||
engines: {node: '>= 4'}
|
engines: {node: '>= 4'}
|
||||||
@@ -2044,9 +2047,6 @@ packages:
|
|||||||
webpack-virtual-modules@0.6.2:
|
webpack-virtual-modules@0.6.2:
|
||||||
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
|
||||||
|
|
||||||
websocketstream-polyfill@1.0.1:
|
|
||||||
resolution: {integrity: sha512-SV0AG8yN3YDwCVCex/oBQli7vrezGQ0stgo5suKMTthjPQv2wuMsNvwUWDAvNmDGGb9VIm5WsW99x57GW06gLQ==}
|
|
||||||
|
|
||||||
whatwg-url@5.0.0:
|
whatwg-url@5.0.0:
|
||||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||||
|
|
||||||
@@ -3406,6 +3406,8 @@ snapshots:
|
|||||||
|
|
||||||
he@1.2.0: {}
|
he@1.2.0: {}
|
||||||
|
|
||||||
|
home-assistant-js-websocket@9.4.0: {}
|
||||||
|
|
||||||
ignore@5.3.2: {}
|
ignore@5.3.2: {}
|
||||||
|
|
||||||
immutable@5.0.3: {}
|
immutable@5.0.3: {}
|
||||||
@@ -4167,8 +4169,6 @@ snapshots:
|
|||||||
|
|
||||||
webpack-virtual-modules@0.6.2: {}
|
webpack-virtual-modules@0.6.2: {}
|
||||||
|
|
||||||
websocketstream-polyfill@1.0.1: {}
|
|
||||||
|
|
||||||
whatwg-url@5.0.0:
|
whatwg-url@5.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
tr46: 0.0.3
|
tr46: 0.0.3
|
||||||
|
|||||||
11
WebDisplay/src/models/calendar/calendar-day.ts
Normal file
11
WebDisplay/src/models/calendar/calendar-day.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import CalendarEntry from './calendar-entry';
|
||||||
|
|
||||||
|
export default class CalendarDay {
|
||||||
|
date: Date;
|
||||||
|
entries: CalendarEntry[];
|
||||||
|
|
||||||
|
constructor(date: Date, entries: CalendarEntry[]) {
|
||||||
|
this.date = date;
|
||||||
|
this.entries = entries;
|
||||||
|
}
|
||||||
|
}
|
||||||
6
WebDisplay/src/models/calendar/calendar-entry.ts
Normal file
6
WebDisplay/src/models/calendar/calendar-entry.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
export default interface CalendarEntry {
|
||||||
|
summary: string;
|
||||||
|
isAllDay: boolean;
|
||||||
|
start: Date;
|
||||||
|
end: Date;
|
||||||
|
}
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
let messageId: number = 1;
|
|
||||||
|
|
||||||
export enum MessageType {
|
|
||||||
auth_invalid = 'auth_invalid',
|
|
||||||
auth_ok = 'auth_ok',
|
|
||||||
auth_required = 'auth_required',
|
|
||||||
event = 'event',
|
|
||||||
pong = 'pong',
|
|
||||||
result = 'result'
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface OutgoingMessage {
|
|
||||||
id: number | undefined;
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IncomingMessage {
|
|
||||||
id: number | undefined;
|
|
||||||
type: string;
|
|
||||||
success: boolean | undefined;
|
|
||||||
result: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export class AuthMessage implements OutgoingMessage {
|
|
||||||
id = undefined;
|
|
||||||
type: string = 'auth';
|
|
||||||
access_token: string | null = null;
|
|
||||||
|
|
||||||
constructor(access_token: string) {
|
|
||||||
this.access_token = access_token;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export class SubscribeEntitiesMessage implements OutgoingMessage {
|
|
||||||
id = messageId++;
|
|
||||||
type = 'subscribe_entities';
|
|
||||||
entity_ids: string[] = [];
|
|
||||||
|
|
||||||
constructor(entity_ids: string[]) {
|
|
||||||
this.entity_ids = entity_ids;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EventMessage extends IncomingMessage {
|
|
||||||
event: StatesUpdates;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EntityState {
|
|
||||||
/** state */
|
|
||||||
s: string;
|
|
||||||
/** attributes */
|
|
||||||
a: { [key: string]: any };
|
|
||||||
/** last_changed; if set, also applies to lu */
|
|
||||||
lc: number;
|
|
||||||
/** last_updated */
|
|
||||||
lu: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface StatesUpdates {
|
|
||||||
/** add */
|
|
||||||
a?: Record<string, EntityState>;
|
|
||||||
/** remove */
|
|
||||||
r?: string[]; // remove
|
|
||||||
}
|
|
||||||
@@ -4,7 +4,13 @@
|
|||||||
import { useLaundryStore } from '@/stores/laundryStore';
|
import { useLaundryStore } from '@/stores/laundryStore';
|
||||||
import { usePowerStore } from '@/stores/powerStore';
|
import { usePowerStore } from '@/stores/powerStore';
|
||||||
import { useHomeAssistantStore } from '@/stores/homeAssistantStore';
|
import { useHomeAssistantStore } from '@/stores/homeAssistantStore';
|
||||||
import Environment from '@/environment';
|
import { useCalendarStore } from '@/stores/calendarStore';
|
||||||
|
import { format, startOfDay, endOfDay } from 'date-fns';
|
||||||
|
import CalendarDay from '@/models/calendar/calendar-day';
|
||||||
|
|
||||||
|
const calendarDayCount = 7;
|
||||||
|
|
||||||
|
const calendarReady = ref(false);
|
||||||
|
|
||||||
const weatherStore = useWeatherStore();
|
const weatherStore = useWeatherStore();
|
||||||
weatherStore.start();
|
weatherStore.start();
|
||||||
@@ -18,12 +24,61 @@
|
|||||||
const homeAssistantStore = useHomeAssistantStore();
|
const homeAssistantStore = useHomeAssistantStore();
|
||||||
homeAssistantStore.start();
|
homeAssistantStore.start();
|
||||||
|
|
||||||
|
const calendarStore = useCalendarStore();
|
||||||
|
|
||||||
const currentTime = ref(new Date());
|
const currentTime = ref(new Date());
|
||||||
|
const calendarDays = ref([] as CalendarDay[]);
|
||||||
|
|
||||||
const timeFormatter = new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit' });
|
const timeFormatter = new Intl.DateTimeFormat('en-US', { hour: 'numeric', minute: '2-digit' });
|
||||||
const dateFormatter = new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
|
const dateFormatter = new Intl.DateTimeFormat('en-US', { weekday: 'long', month: 'long', day: 'numeric' });
|
||||||
|
|
||||||
setInterval(() => (currentTime.value = new Date()), 1000);
|
function alarmState(state: string): string {
|
||||||
|
switch (state) {
|
||||||
|
case 'armed_home':
|
||||||
|
return 'Armed';
|
||||||
|
case 'armed_away':
|
||||||
|
return 'Armed';
|
||||||
|
case 'disarmed':
|
||||||
|
return 'Disarmed';
|
||||||
|
default:
|
||||||
|
return 'Unknown';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCalendar() {
|
||||||
|
const newCalendarDays = [] as CalendarDay[];
|
||||||
|
|
||||||
|
calendarStore.getUpcoming(calendarDayCount).then((upcoming) => {
|
||||||
|
const currentDay = startOfDay(currentTime.value);
|
||||||
|
|
||||||
|
for (let i = 0; i < calendarDayCount; i++) {
|
||||||
|
const day = new Date(currentDay);
|
||||||
|
day.setDate(day.getDate() + i);
|
||||||
|
|
||||||
|
const entries = upcoming.filter((entry) => {
|
||||||
|
const entryStart = startOfDay(entry.start);
|
||||||
|
const entryEnd = endOfDay(entry.end);
|
||||||
|
|
||||||
|
if (entry.isAllDay) {
|
||||||
|
return day > entryStart && day < entryEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
return day >= entryStart && day <= entryEnd;
|
||||||
|
});
|
||||||
|
|
||||||
|
newCalendarDays.push(new CalendarDay(day, entries));
|
||||||
|
}
|
||||||
|
|
||||||
|
calendarDays.value = newCalendarDays;
|
||||||
|
|
||||||
|
calendarReady.value = true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
loadCalendar();
|
||||||
|
|
||||||
|
setInterval(() => currentTime.value = new Date(), 1000);
|
||||||
|
setInterval(() => loadCalendar(), 60000);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -108,19 +163,38 @@
|
|||||||
class="kiosk-device-icon"
|
class="kiosk-device-icon"
|
||||||
icon="mdi-shield-home" />
|
icon="mdi-shield-home" />
|
||||||
<div class="kiosk-device-text">
|
<div class="kiosk-device-text">
|
||||||
{{ capitalize(homeAssistantStore.houseAlarmState) }}
|
{{ alarmState(homeAssistantStore.houseAlarmState) }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="kiosk-content" v-if="Environment.getCalendarEmbedUrl()">
|
<div class="kiosk-content">
|
||||||
<div class="kiosk-calendar">
|
<div
|
||||||
<iframe
|
class="kiosk-calendar"
|
||||||
:src="Environment.getCalendarEmbedUrl()"
|
v-if="calendarReady">
|
||||||
style="border-width: 0"
|
<div class="kiosk-calendar-header">
|
||||||
width="100%"
|
{{ 'Next ' + calendarDayCount + ' Days' }}
|
||||||
height="100%"
|
</div>
|
||||||
frameborder="0"
|
<ul class="kiosk-calendar-day-list">
|
||||||
scrolling="no"></iframe>
|
<li
|
||||||
|
class="kiosk-calendar-day-item"
|
||||||
|
v-for="calendarDay in calendarDays">
|
||||||
|
<div>
|
||||||
|
<span class="kiosk-calendar-day-item-number">
|
||||||
|
{{ format(calendarDay.date, 'dd') }}
|
||||||
|
</span>
|
||||||
|
<span class="kiosk-calendar-day-item-name">
|
||||||
|
{{ format(calendarDay.date, 'MMMM, EEEE') }}
|
||||||
|
</span>
|
||||||
|
<ul
|
||||||
|
class="kiosk-calendar-entry"
|
||||||
|
v-for="calendarEntry in calendarDay.entries">
|
||||||
|
<span>
|
||||||
|
{{ calendarEntry.summary }}
|
||||||
|
</span>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</v-container>
|
</v-container>
|
||||||
@@ -131,7 +205,7 @@
|
|||||||
height: 100%;
|
height: 100%;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background-color: #212428;
|
background-color: #212428;
|
||||||
color: #1f1f1f;
|
color: #ebebeb;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 250px 1fr;
|
grid-template-columns: 250px 1fr;
|
||||||
grid-template-rows: 1fr;
|
grid-template-rows: 1fr;
|
||||||
@@ -169,12 +243,15 @@
|
|||||||
|
|
||||||
.kiosk-content {
|
.kiosk-content {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
max-height: 100vh;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
grid-template-columns: repeat(3, 1fr);
|
||||||
grid-template-rows: repeat(2, 1fr);
|
grid-template-rows: repeat(2, 1fr);
|
||||||
grid-auto-flow: row;
|
grid-auto-flow: row;
|
||||||
grid-template-areas: 'kiosk-calendar .';
|
grid-template-areas:
|
||||||
|
'kiosk-calendar . .'
|
||||||
|
'kiosk-calendar . .';
|
||||||
}
|
}
|
||||||
|
|
||||||
.kiosk-time {
|
.kiosk-time {
|
||||||
@@ -231,6 +308,48 @@
|
|||||||
|
|
||||||
.kiosk-calendar {
|
.kiosk-calendar {
|
||||||
grid-area: kiosk-calendar;
|
grid-area: kiosk-calendar;
|
||||||
|
background-color: #121212;
|
||||||
|
margin: 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-header {
|
||||||
|
font-size: 1.15em;
|
||||||
|
padding-top: 10px;
|
||||||
|
padding-bottom: 2px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-day-item-number {
|
||||||
|
font-size: 1.25em;
|
||||||
|
padding-right: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-day-list {
|
||||||
|
margin-left: 10px;
|
||||||
|
overflow: auto;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-day-item:not(:last-child) {
|
||||||
|
padding-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-day-item:first-of-type {
|
||||||
|
color: #c75ec7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-day-item:not(:first-child) {
|
||||||
|
padding-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.kiosk-calendar-entry {
|
||||||
|
color: #ebebeb;
|
||||||
|
padding-left: 2em;
|
||||||
|
padding-bottom: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.true {
|
.true {
|
||||||
|
|||||||
17
WebDisplay/src/stores/calendarStore.ts
Normal file
17
WebDisplay/src/stores/calendarStore.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import axios from 'axios';
|
||||||
|
import Environment from '@/environment';
|
||||||
|
import CalendarEntry from '@/models/calendar/calendar-entry';
|
||||||
|
|
||||||
|
export const useCalendarStore = defineStore('calendar', {
|
||||||
|
state: () => {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
async getUpcoming(days: number): Promise<CalendarEntry[]> {
|
||||||
|
const response = await axios.get<CalendarEntry[]>(Environment.getUrlPrefix() + `:8081/api/calendar/calendar/upcoming?days=${days}`);
|
||||||
|
|
||||||
|
return response.data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -1,7 +1,5 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { WebSocketStream } from 'websocketstream-polyfill';
|
import { createConnection, subscribeEntities, createLongLivedTokenAuth, Connection } from 'home-assistant-js-websocket';
|
||||||
import { MessageType, AuthMessage, IncomingMessage, SubscribeEntitiesMessage, EventMessage } from '@/models/home-assistant/home-assistant';
|
|
||||||
|
|
||||||
import Environment from '@/environment';
|
import Environment from '@/environment';
|
||||||
|
|
||||||
export const useHomeAssistantStore = defineStore('home-assistant', {
|
export const useHomeAssistantStore = defineStore('home-assistant', {
|
||||||
@@ -9,7 +7,7 @@ export const useHomeAssistantStore = defineStore('home-assistant', {
|
|||||||
return {
|
return {
|
||||||
garageState: null as string | null,
|
garageState: null as string | null,
|
||||||
houseAlarmState: null as string | null,
|
houseAlarmState: null as string | null,
|
||||||
_wss: null as WebSocketStream | null
|
_connection: null as Connection | null
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
actions: {
|
actions: {
|
||||||
@@ -21,72 +19,27 @@ export const useHomeAssistantStore = defineStore('home-assistant', {
|
|||||||
const garageDevice = Environment.getGarageDevice();
|
const garageDevice = Environment.getGarageDevice();
|
||||||
const alarmDevice = Environment.getAlarmDevice();
|
const alarmDevice = Environment.getAlarmDevice();
|
||||||
|
|
||||||
this._wss = new WebSocketStream(Environment.getHomeAssistantUrl());
|
const auth = createLongLivedTokenAuth(Environment.getHomeAssistantUrl(), Environment.getHomeAssistantToken());
|
||||||
|
|
||||||
const { readable, writable } = await this._wss.opened;
|
this._connection = await createConnection({ auth });
|
||||||
|
|
||||||
const reader = readable.getReader();
|
subscribeEntities(this._connection as Connection, entities => {
|
||||||
const writer = writable.getWriter();
|
const garageEntity = entities[garageDevice];
|
||||||
|
|
||||||
while (true) {
|
|
||||||
const { value, done } = await reader.read();
|
|
||||||
|
|
||||||
const message = JSON.parse(value as string) as IncomingMessage;
|
|
||||||
|
|
||||||
console.info(message);
|
|
||||||
|
|
||||||
switch (message.type) {
|
|
||||||
case MessageType.auth_required:
|
|
||||||
const authMessage = new AuthMessage(Environment.getHomeAssistantToken());
|
|
||||||
writer.write(JSON.stringify(authMessage));
|
|
||||||
break;
|
|
||||||
case MessageType.auth_ok:
|
|
||||||
const subscribeEntitiesMessage = new SubscribeEntitiesMessage([
|
|
||||||
garageDevice,
|
|
||||||
alarmDevice
|
|
||||||
]);
|
|
||||||
writer.write(JSON.stringify(subscribeEntitiesMessage));
|
|
||||||
break;
|
|
||||||
case MessageType.event:
|
|
||||||
const eventMessage = message as EventMessage;
|
|
||||||
|
|
||||||
if (!eventMessage?.event?.a) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
const garageEntity = eventMessage.event.a[garageDevice];
|
|
||||||
|
|
||||||
if (garageEntity) {
|
if (garageEntity) {
|
||||||
this.$patch({ garageState: garageEntity.s });
|
this.$patch({ garageState: garageEntity.state });
|
||||||
}
|
}
|
||||||
|
|
||||||
const houseAlarmEntity = eventMessage.event.a[alarmDevice];
|
const houseAlarmEntity = entities[alarmDevice];
|
||||||
|
|
||||||
if (houseAlarmEntity) {
|
if (houseAlarmEntity) {
|
||||||
this.$patch({ houseAlarmState: houseAlarmEntity.s });
|
this.$patch({ houseAlarmState: houseAlarmEntity.state });
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case MessageType.result:
|
|
||||||
// Handle result type
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
// Handle unknown message type
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (done) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
async stop() {
|
async stop() {
|
||||||
if (!this._wss) {
|
this._connection?.close();
|
||||||
return;
|
this._connection = null;
|
||||||
}
|
|
||||||
|
|
||||||
this._wss.close();
|
|
||||||
this._wss = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user