Use custom websocket to avoid needing admin privileges.
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
import { localize } from '../../localize/localize';
|
||||
import { ExtendedHomeAssistant } from '../../types';
|
||||
import { hasHAConnectionStateChanged } from '../../utils/ha';
|
||||
import { CardHASSAPI } from '../types';
|
||||
import { StateWatcher, StateWatcherSubscriptionInterface } from './state-watcher';
|
||||
|
||||
export class HASSManager {
|
||||
protected _hass: ExtendedHomeAssistant | null = null;
|
||||
protected _api: CardHASSAPI;
|
||||
protected _stateWatcher: StateWatcher = new StateWatcher();
|
||||
|
||||
constructor(api: CardHASSAPI) {
|
||||
this._api = api;
|
||||
}
|
||||
|
||||
public getHASS(): ExtendedHomeAssistant | null {
|
||||
return this._hass;
|
||||
}
|
||||
|
||||
public getStateWatcher(): StateWatcherSubscriptionInterface {
|
||||
return this._stateWatcher;
|
||||
}
|
||||
|
||||
public setHASS(hass?: ExtendedHomeAssistant | null): void {
|
||||
if (hasHAConnectionStateChanged(this._hass, hass)) {
|
||||
if (!hass?.connected) {
|
||||
this._api.getMessageManager().setMessageIfHigherPriority({
|
||||
message: localize('error.reconnecting'),
|
||||
icon: 'mdi:lan-disconnect',
|
||||
type: 'connection',
|
||||
dotdotdot: true,
|
||||
});
|
||||
} else {
|
||||
this._api.getMessageManager().resetType('connection');
|
||||
}
|
||||
}
|
||||
|
||||
if (!hass) {
|
||||
return;
|
||||
}
|
||||
|
||||
const oldHass = this._hass;
|
||||
this._hass = hass;
|
||||
|
||||
if (this._api.getConditionsManager().hasHAStateConditions()) {
|
||||
this._api.getConditionsManager().setState({
|
||||
state: this._hass.states,
|
||||
user: this._hass.user,
|
||||
});
|
||||
}
|
||||
|
||||
// Dark mode may depend on HASS.
|
||||
this._api.getStyleManager().setLightOrDarkMode();
|
||||
|
||||
this._stateWatcher.setHASS(oldHass, hass);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import { HomeAssistant } from '@dermotduffy/custom-card-helpers';
|
||||
import { getHassDifferences, HassStateDifference } from '../../utils/ha';
|
||||
|
||||
type StateWatcherCallback = (difference: HassStateDifference) => void;
|
||||
|
||||
export interface StateWatcherSubscriptionInterface {
|
||||
subscribe(callback: StateWatcherCallback, entityIDs: string[]): void;
|
||||
unsubscribe(callback: StateWatcherCallback): void;
|
||||
}
|
||||
|
||||
export class StateWatcher implements StateWatcherSubscriptionInterface {
|
||||
protected _watcherCallbacks = new Map<StateWatcherCallback, string[]>();
|
||||
|
||||
public setHASS(oldHass: HomeAssistant | null, hass: HomeAssistant): void {
|
||||
if (!oldHass) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const [callback, entityIDs] of this._watcherCallbacks.entries()) {
|
||||
const differences = getHassDifferences(hass, oldHass, entityIDs, {
|
||||
stateOnly: true,
|
||||
firstOnly: true,
|
||||
});
|
||||
if (differences.length) {
|
||||
callback(differences[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls callback when the state of any of the entities changes. The callback is
|
||||
* called with the state difference of the first entity that changed.
|
||||
* @param callback The callback.
|
||||
* @param entityIDs An array of entity IDs to watch.
|
||||
*/
|
||||
public subscribe(callback: StateWatcherCallback, entityIDs: string[]): boolean {
|
||||
if (!entityIDs.length) {
|
||||
return false;
|
||||
}
|
||||
if (this._watcherCallbacks.has(callback)) {
|
||||
this._watcherCallbacks.get(callback)?.push(...entityIDs);
|
||||
} else {
|
||||
this._watcherCallbacks.set(callback, entityIDs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public unsubscribe(callback: StateWatcherCallback): void {
|
||||
this._watcherCallbacks.delete(callback);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user