Add support for perform-action calls.

This commit is contained in:
Dermot Duffy
2024-09-09 22:05:49 -07:00
parent 804aa97d0b
commit a0283c35c1
14 changed files with 247 additions and 112 deletions
@@ -4,6 +4,8 @@
Call a service. See [Home Assistant actions documentation](https://www.home-assistant.io/dashboards/actions/).
!> Home Assistant has deprecated the `call-service` action, please use [`perform-action`](#perform-action) instead.
```yaml
action: call-service
# [...]
@@ -27,6 +29,15 @@ action: navigate
# [...]
```
## `perform-action`
Perform a Home Assistant action. See [Home Assistant actions documentation](https://www.home-assistant.io/dashboards/actions/).
```yaml
action: perform-action
# [...]
```
## `toggle`
Toggle an entity. See [Home Assistant actions documentation](https://www.home-assistant.io/dashboards/actions/).
@@ -117,4 +128,15 @@ elements:
tap_action:
action: fire-dom-event
key: value
- type: icon
icon: mdi:numeric-8-box
title: Perform action
style:
left: 200px
top: 400px
tap_action:
action: perform-action
perform_action: homeassistant.toggle
target:
entity_id: light.office_main_lights
```
+11 -11
View File
@@ -210,8 +210,8 @@ the integration currently offers.
| Option | Default | Description |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `actions_left`, `actions_right`, `actions_up`, `actions_down`, `actions_zoom_in`, `actions_zoom_out`, `actions_home` | Set by camera [engine](./engine.md) of the selected camera | The [call-service](../actions/stock/README.md?id=call-service) action that will be called for each PTZ action for relative movements. |
| `actions_left_start`, `actions_left_stop`, `actions_right_start`, `actions_right_stop`,`actions_up_start`, `actions_up_stop`,`actions_down_start`, `actions_down_stop`,`actions_zoom_in_start`, `actions_zoom_in_stop`,`actions_zoom_out_start`, `actions_zoom_out_stop` | Set by camera [engine](./engine.md) of the selected camera | The [call-service](../actions/stock/README.md?id=call-service) action that will be called for each PTZ action for continous movements. Both a `_start` and `_stop` variety must be provided for an action to be usable. |
| `actions_left`, `actions_right`, `actions_up`, `actions_down`, `actions_zoom_in`, `actions_zoom_out`, `actions_home` | Set by camera [engine](./engine.md) of the selected camera | The [perform-action](../actions/stock/README.md?id=perform-action) action that will be called for each PTZ action for relative movements. |
| `actions_left_start`, `actions_left_stop`, `actions_right_start`, `actions_right_stop`,`actions_up_start`, `actions_up_stop`,`actions_down_start`, `actions_down_stop`,`actions_zoom_in_start`, `actions_zoom_in_stop`,`actions_zoom_out_start`, `actions_zoom_out_stop` | Set by camera [engine](./engine.md) of the selected camera | The [perform-action](../actions/stock/README.md?id=perform-action) action that will be called for each PTZ action for continous movements. Both a `_start` and `_stop` variety must be provided for an action to be usable. |
| `c2r_delay_between_calls_seconds` | `0.2` | When the camera is configured with continuous actions only (e.g. `left_start` and `left_stop`, but not `left`), if something requests a relative action (e.g. a manually configured [action](../actions/README.md)), then `start` will be called, followed by a delay of this number of seconds and finally `stop` will be called. Cameras / integrations that are slower to respond to continuous steps may need to increase this value to avoid the continuous motion being too small. Cameras / integrations that are rapid to respond may need to decrease this value to avoid the "relative step" being too large. |
| `data_left`, `data_right`, `data_up`, `data_down`, `data_zoom_in`, `data_zoom_out`, `data_home` | | Shorthand for relative actions that call the service defined by the `service` parameter, with the data provided in this argument. Internally, this is just translated into the longer-form `actions_[action]`. If both `actions_X` and `data_X` are specified, `actions_X` takes priority. This is compatible with [AlexxIT's WebRTC Card PTZ configuration](https://github.com/AlexxIT/WebRTC/wiki/PTZ-Config-Examples). |
| `data_left_start`, `data_left_stop`, `data_right_start`, `data_right_stop`, `data_up_start`, `data_up_stop`, `data_down_start`, `data_down_stop`, `data_zoom_in_start`, `data_zoom_in_stop`, `data_zoom_out_start`, `data_zoom_out_stop` | | Shorthand for continuous actions that call the service defined by the `service` parameter, with the data provided in this argument. Internally, this is just translated into the longer-form `actions_[action]_start` and `actions_[action]_stop`. If both `actions_X_*` and `data_X_*` are specified, `actions_X_*` takes priority. This is compatible with [AlexxIT's WebRTC Card PTZ configuration](https://github.com/AlexxIT/WebRTC/wiki/PTZ-Config-Examples). Both a `_start` and `_stop` variety must be provided for an action to be usable. |
@@ -232,7 +232,7 @@ cameras:
? [action]
```
`[action]` is any [call-service](../actions/stock/README.md?id=call-service) action.
`[action]` is any [perform-action](../actions/stock/README.md?id=perform-action) action.
## `triggers`
@@ -382,22 +382,22 @@ cameras:
r2c_delay_between_calls_seconds: 0.5
# Relative action (only `left` shown)
actions_left:
action: call-service
service: service.of_your_choice
action: perform-action
perform_action: service.of_your_choice
data:
device: '048123'
cmd: left
# Continuous action (only `right` shown)
actions_right_start:
action: call-service
service: service.of_your_choice
action: perform-action
perform_action: service.of_your_choice
data:
device: '048123'
cmd: right
phase: start
actions_right_stop:
action: call-service
service: service.of_your_choice
action: perform-action
perform_action: service.of_your_choice
data:
device: '048123'
phase: stop
@@ -419,8 +419,8 @@ cameras:
presets:
# Preset using long form.
armchair:
action: call-service
service: service.of_your_choice
action: perform-action
perform_action: service.of_your_choice
data:
device: '048123'
cmd: preset
+4 -4
View File
@@ -205,7 +205,7 @@ elements:
right: 25px
bottom: 50px
tap_action:
action: call-service
action: perform-action
service: amcrest.ptz_control
data:
entity_id: camera.kitchen
@@ -252,9 +252,9 @@ elements:
style:
color: red
tap_action:
action: call-service
service: homeassistant.toggle
data:
action: perform-action
perform_action: homeassistant.toggle
target:
entity_id: siren.siren
conditions:
- condition: triggered
+2 -2
View File
@@ -16,7 +16,7 @@
"license": "MIT",
"dependencies": {
"@cycjimmy/jsmpeg-player": "^6.0.5",
"@dermotduffy/custom-card-helpers": "^1.9.0",
"@dermotduffy/custom-card-helpers": "^1.9.1",
"@dermotduffy/panzoom": "^4.5.1",
"@egjs/hammerjs": "^2.0.17",
"@graphiteds/core": "^1.9.21",
@@ -29,7 +29,7 @@
"date-fns-tz": "^3.1.3",
"embla-carousel": "^8.1.4",
"embla-carousel-wheel-gestures": "^8.0.1",
"home-assistant-js-websocket": "^8.2.0",
"home-assistant-js-websocket": "^9.4.0",
"keycharm": "^0.4.0",
"lit": "^3.1.4",
"lodash-es": "^4.17.21",
-1
View File
@@ -101,7 +101,6 @@ const config = {
moduleContext: {
'./node_modules/@formatjs/intl-utils/lib/src/diff.js': 'window',
'./node_modules/@formatjs/intl-utils/lib/src/resolve-locale.js': 'window',
'./node_modules/flatpickr/dist/esm/index.js': 'window',
},
};
+1 -1
View File
@@ -131,7 +131,7 @@ export class FrigateCardImage extends LitElement implements FrigateCardMediaPlay
this._cachedValueController?.clearValue();
return true;
}
return false;
return !this.hasUpdated;
}
return true;
}
+5 -3
View File
@@ -229,12 +229,14 @@ export class FrigateCardSubmenuSelect extends LitElement {
title: title || option,
...((entityID.startsWith('select.') || entityID.startsWith('input_select.')) && {
tap_action: {
action: 'call-service',
service: entityID.startsWith('select.')
action: 'perform-action',
perform_action: entityID.startsWith('select.')
? 'select.select_option'
: 'input_select.select_option',
data: {
target: {
entity_id: entityID,
},
data: {
option: option,
},
},
+29
View File
@@ -446,6 +446,21 @@ const conditionToConditionsTransform = (data: unknown): boolean => {
return false;
};
const callServiceToPerformActionTransform = (data: unknown): boolean => {
if (
typeof data !== 'object' ||
!data ||
data['action'] !== 'call-service' ||
typeof data['service'] !== 'string'
) {
return false;
}
data['action'] = 'perform-action';
data['perform_action'] = data['service'];
delete data['service'];
return true;
};
/**
* Transform service_data -> data
* See: https://github.com/dermotduffy/frigate-hass-card/issues/1103
@@ -849,4 +864,18 @@ const UPGRADES = [
}),
deleteWithOverrides('live.controls.title'),
deleteWithOverrides('media_viewer.controls.title'),
// Upgrade call-service calls throughout the card config. They could show up
// attached to any element, any automation, or any card/view action (i.e. very
// broadly across the config), so it's challenging to better target this
// upgrade. As written, this will convert things that look like call-service
// calls recurseively throughout the whole card config, but this could
// conceivably be an overreach if (e.g.) some totally unrelated object has {
// action: 'call-service', service: '<any string>' } that means something
// different.
(data: unknown): boolean => {
return upgradeObjectRecursively(callServiceToPerformActionTransform)(
typeof data === 'object' && data ? (data as RawFrigateCardConfig) : {},
);
},
];
+47 -21
View File
@@ -4,9 +4,11 @@ import {
MoreInfoActionConfig,
NavigateActionConfig,
NoActionConfig,
PerformActionActionConfig,
ToggleActionConfig,
UrlActionConfig,
} from '@dermotduffy/custom-card-helpers';
import { HassServiceTarget } from 'home-assistant-js-websocket';
import { z } from 'zod';
import { MEDIA_CHUNK_SIZE_DEFAULT, MEDIA_CHUNK_SIZE_MAX } from '../const.js';
import { capabilityKeys } from '../types.js';
@@ -168,6 +170,28 @@ const toggleActionSchema = schemaForType<
}),
);
const targetSchema = schemaForType<HassServiceTarget>()(
z.object({
entity_id: z.string().optional(),
device_id: z.string().optional(),
area_id: z.string().optional(),
}),
);
const performActionActionSchema = schemaForType<
PerformActionActionConfig & ExtendedConfirmationRestrictionConfig
>()(
actionBaseSchema.extend({
action: z.literal('perform-action'),
perform_action: z.string(),
data: z.object({}).passthrough().optional(),
target: targetSchema.optional(),
}),
);
// Note: call-service is deprecated and will eventually go away. Please use
// perform-action instead.
// See: https://www.home-assistant.io/blog/2024/08/07/release-20248/#goodbye-service-calls-hello-actions-
const callServiceActionSchema = schemaForType<
CallServiceActionConfig & ExtendedConfirmationRestrictionConfig
>()(
@@ -175,6 +199,7 @@ const callServiceActionSchema = schemaForType<
action: z.literal('call-service'),
service: z.string(),
data: z.object({}).passthrough().optional(),
target: targetSchema.optional(),
}),
);
@@ -391,6 +416,7 @@ export type FrigateCardCustomAction = z.infer<typeof frigateCardCustomActionSche
export const actionSchema = z.union([
toggleActionSchema,
callServiceActionSchema,
performActionActionSchema,
navigateActionSchema,
urlActionSchema,
moreInfoActionSchema,
@@ -814,8 +840,8 @@ const dataPTZFormatToFullFormat = function (suffix: string): (data: unknown) =>
const name = match?.[1];
if (name && !(`${suffix}${name}` in data)) {
out[`${suffix}${name}`] = {
action: 'call-service',
service: data['service'],
action: 'perform-action',
perform_action: data['service'],
data: data[key],
};
delete out[key];
@@ -830,29 +856,29 @@ const ptzCameraConfigSchema = z.preprocess(
dataPTZFormatToFullFormat('actions_'),
z
.object({
actions_left: callServiceActionSchema.optional(),
actions_left_start: callServiceActionSchema.optional(),
actions_left_stop: callServiceActionSchema.optional(),
actions_left: performActionActionSchema.optional(),
actions_left_start: performActionActionSchema.optional(),
actions_left_stop: performActionActionSchema.optional(),
actions_right: callServiceActionSchema.optional(),
actions_right_start: callServiceActionSchema.optional(),
actions_right_stop: callServiceActionSchema.optional(),
actions_right: performActionActionSchema.optional(),
actions_right_start: performActionActionSchema.optional(),
actions_right_stop: performActionActionSchema.optional(),
actions_up: callServiceActionSchema.optional(),
actions_up_start: callServiceActionSchema.optional(),
actions_up_stop: callServiceActionSchema.optional(),
actions_up: performActionActionSchema.optional(),
actions_up_start: performActionActionSchema.optional(),
actions_up_stop: performActionActionSchema.optional(),
actions_down: callServiceActionSchema.optional(),
actions_down_start: callServiceActionSchema.optional(),
actions_down_stop: callServiceActionSchema.optional(),
actions_down: performActionActionSchema.optional(),
actions_down_start: performActionActionSchema.optional(),
actions_down_stop: performActionActionSchema.optional(),
actions_zoom_in: callServiceActionSchema.optional(),
actions_zoom_in_start: callServiceActionSchema.optional(),
actions_zoom_in_stop: callServiceActionSchema.optional(),
actions_zoom_in: performActionActionSchema.optional(),
actions_zoom_in_start: performActionActionSchema.optional(),
actions_zoom_in_stop: performActionActionSchema.optional(),
actions_zoom_out: callServiceActionSchema.optional(),
actions_zoom_out_start: callServiceActionSchema.optional(),
actions_zoom_out_stop: callServiceActionSchema.optional(),
actions_zoom_out: performActionActionSchema.optional(),
actions_zoom_out_start: performActionActionSchema.optional(),
actions_zoom_out_stop: performActionActionSchema.optional(),
// The number of seconds between subsequent relative calls when converting a
// relative request into a continuous request.
@@ -870,7 +896,7 @@ const ptzCameraConfigSchema = z.preprocess(
.preprocess(
dataPTZFormatToFullFormat(''),
z.union([
z.record(callServiceActionSchema),
z.record(performActionActionSchema),
// This is used by the data_ style of action.
z.object({ service: z.string().optional() }),
+2 -2
View File
@@ -1120,8 +1120,8 @@ describe('CameraManager', async () => {
const hass = createHASS();
vi.mocked(api.getHASSManager().getHASS).mockReturnValue(hass);
const action = {
action: 'call-service' as const,
service: 'service',
action: 'perform-action' as const,
perform_action: 'action',
};
const manager = createCameraManager(api, engine, [
{
+4 -4
View File
@@ -1,15 +1,15 @@
import { describe, expect, it, vi } from 'vitest';
import { describe, expect, it } from 'vitest';
import {
getConfiguredPTZAction,
getConfiguredPTZMovementType,
getPTZCapabilitiesFromCameraConfig,
} from '../../../src/camera-manager/utils/ptz';
import { createCameraConfig } from '../../test-utils';
import { PTZAction } from '../../../src/config/ptz';
import { createCameraConfig } from '../../test-utils';
const action = {
action: 'call-service' as const,
service: 'service',
action: 'perform-action' as const,
perform_action: 'action',
data: {
device: '048123',
cmd: 'preset',
+99 -35
View File
@@ -21,6 +21,7 @@ import {
import { PTZControlAction } from '../../src/config/ptz';
import {
Actions,
PerformActionActionConfig,
RawFrigateCardConfig,
frigateCardConfigSchema,
} from '../../src/config/types';
@@ -752,8 +753,8 @@ describe('should handle version specific upgrades', () => {
color: 'white',
},
tap_action: {
action: 'call-service',
service: 'notify.persistent_notification',
action: 'perform-action',
perform_action: 'notify.persistent_notification',
data: {
message: 'Hello 1',
},
@@ -773,15 +774,15 @@ describe('should handle version specific upgrades', () => {
view: {
actions: {
double_tap_action: {
action: 'call-service',
service: 'notify.persistent_notification',
action: 'perform-action',
perform_action: 'notify.persistent_notification',
data: {
message: 'Hello 2',
},
},
hold_action: {
action: 'call-service',
service: 'notify.persistent_notification',
action: 'perform-action',
perform_action: 'notify.persistent_notification',
data: {
message: 'Hello 3',
},
@@ -812,7 +813,7 @@ describe('should handle version specific upgrades', () => {
});
describe('should move PTZ elements to live', () => {
it('case with 1 element', () => {
it('xxx case with 1 element', () => {
const config = {
type: 'custom:frigate-card',
cameras: [{ camera_entity: 'camera.office' }],
@@ -843,11 +844,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Hello 1',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -907,11 +908,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Hello 1',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -1000,11 +1001,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Hello 1',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -1073,11 +1074,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Hello 1',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -1160,11 +1161,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Hello 1',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -1237,11 +1238,11 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
actions_up: {
action: 'call-service',
action: 'perform-action',
data: {
message: 'Original',
},
service: 'notify.persistent_notification',
perform_action: 'notify.persistent_notification',
},
},
},
@@ -2855,7 +2856,7 @@ describe('should handle version specific upgrades', () => {
});
describe('split live.ptz', () => {
const getAction = (action: PTZControlAction): CallServiceActionConfig => ({
const getActionBefore = (action: PTZControlAction): CallServiceActionConfig => ({
action: 'call-service',
service: 'service',
data: {
@@ -2863,8 +2864,16 @@ describe('should handle version specific upgrades', () => {
},
});
const getActionAfter = (action: PTZControlAction): PerformActionActionConfig => ({
action: 'perform-action',
perform_action: 'service',
data: {
arg: action,
},
});
const getTapAction = (action: PTZControlAction): Actions => ({
tap_action: getAction(action),
tap_action: getActionBefore(action),
});
it('with action_ format', () => {
@@ -2882,7 +2891,7 @@ describe('should handle version specific upgrades', () => {
actions_zoom_out: getTapAction('zoom_out'),
actions_home: {
...getTapAction('home'),
double_tap_action: getAction('up'),
double_tap_action: getActionBefore('up'),
},
mode: 'auto' as const,
@@ -2907,14 +2916,14 @@ describe('should handle version specific upgrades', () => {
cameras: [{}],
cameras_global: {
ptz: {
actions_left: getAction('left'),
actions_right: getAction('right'),
actions_up: getAction('up'),
actions_down: getAction('down'),
actions_zoom_in: getAction('zoom_in'),
actions_zoom_out: getAction('zoom_out'),
actions_left: getActionAfter('left'),
actions_right: getActionAfter('right'),
actions_up: getActionAfter('up'),
actions_down: getActionAfter('down'),
actions_zoom_in: getActionAfter('zoom_in'),
actions_zoom_out: getActionAfter('zoom_out'),
presets: {
home: getAction('home'),
home: getActionAfter('home'),
},
},
},
@@ -3052,7 +3061,7 @@ describe('should handle version specific upgrades', () => {
controls: {
ptz: {
actions_up: {
double_tap_action: getAction('up'),
double_tap_action: getActionBefore('up'),
},
actions_down: getTapAction('down'),
},
@@ -3065,7 +3074,7 @@ describe('should handle version specific upgrades', () => {
expect.objectContaining({
cameras_global: {
ptz: {
actions_down: getAction('down'),
actions_down: getActionAfter('down'),
},
},
}),
@@ -3081,8 +3090,8 @@ describe('should handle version specific upgrades', () => {
controls: {
ptz: {
presets: {
home: getAction('left'),
other: getAction('right'),
home: getActionBefore('left'),
other: getActionBefore('right'),
},
actions_home: getTapAction('home'),
},
@@ -3096,8 +3105,8 @@ describe('should handle version specific upgrades', () => {
cameras_global: {
ptz: {
presets: {
other: getAction('right'),
home: getAction('home'),
other: getActionAfter('right'),
home: getActionAfter('home'),
},
},
},
@@ -3303,5 +3312,60 @@ describe('should handle version specific upgrades', () => {
});
});
});
it('call-service -> perform-action', () => {
const config = {
type: 'custom:frigate-card',
cameras: [{ camera_entity: 'camera.office' }],
elements: [
{
type: 'icon',
icon: 'mdi:cow',
tap_action: {
action: 'call-service',
service: 'foo',
},
},
],
view: {
actions: {
double_tap_action: {
action: 'call-service',
service: 'bar',
data: {
key: 'value',
},
},
},
},
};
expect(upgradeConfig(config)).toBeTruthy();
expect(config).toEqual({
type: 'custom:frigate-card',
cameras: [{ camera_entity: 'camera.office' }],
elements: [
{
type: 'icon',
icon: 'mdi:cow',
tap_action: {
action: 'perform-action',
perform_action: 'foo',
},
},
],
view: {
actions: {
double_tap_action: {
action: 'perform-action',
perform_action: 'bar',
data: {
key: 'value',
},
},
},
},
});
postUpgradeChecks(config);
});
});
});
+10 -10
View File
@@ -423,8 +423,8 @@ describe('should convert webrtc card PTZ to Frigate card PTZ', () => {
expect.objectContaining({
ptz: expect.objectContaining({
[`actions_${action}`]: {
action: 'call-service',
service: 'foo',
action: 'perform-action',
perform_action: 'foo',
data: {
device: '048123',
cmd: action,
@@ -465,8 +465,8 @@ describe('should convert webrtc card PTZ to Frigate card PTZ', () => {
expect.objectContaining({
ptz: expect.objectContaining({
[`actions_${action}_start`]: {
action: 'call-service',
service: 'foo',
action: 'perform-action',
perform_action: 'foo',
data: {
device: '048123',
cmd: action,
@@ -474,8 +474,8 @@ describe('should convert webrtc card PTZ to Frigate card PTZ', () => {
},
},
[`actions_${action}_stop`]: {
action: 'call-service',
service: 'foo',
action: 'perform-action',
perform_action: 'foo',
data: {
device: '048123',
cmd: action,
@@ -511,16 +511,16 @@ describe('should convert webrtc card PTZ to Frigate card PTZ', () => {
ptz: expect.objectContaining({
presets: {
home: {
action: 'call-service',
service: 'service_inner',
action: 'perform-action',
perform_action: 'service_inner',
data: {
device: '048123',
cmd: 'home',
},
},
another: {
action: 'call-service',
service: 'service_inner',
action: 'perform-action',
perform_action: 'service_inner',
data: {
device: '048123',
cmd: 'another',
+11 -18
View File
@@ -603,18 +603,18 @@ __metadata:
languageName: node
linkType: hard
"@dermotduffy/custom-card-helpers@npm:^1.9.0":
version: 1.9.0
resolution: "@dermotduffy/custom-card-helpers@npm:1.9.0"
"@dermotduffy/custom-card-helpers@npm:^1.9.1":
version: 1.9.1
resolution: "@dermotduffy/custom-card-helpers@npm:1.9.1"
dependencies:
"@formatjs/intl-utils": "npm:^3.8.4"
home-assistant-js-websocket: "npm:^6.0.1"
home-assistant-js-websocket: "npm:^9.4.0"
intl-messageformat: "npm:^9.11.1"
lit: "npm:^2.1.1"
rollup: "npm:^2.63.0"
superstruct: "npm:^0.15.3"
typescript: "npm:^4.5.4"
checksum: 10c0/312a31a9abe6ddc37109ffe2725df30e72213b4fa2cceacbb4bdb3712b46a73e49b9fb7fab69dc521050538e882d7180e3d7434011f637a34f2bc9098b880e97
checksum: 10c0/e42073e00682195c3d253f9b36dc091f7329a5e2a5cdd395bf0988ec2c8585db887ef772975894e4a1126653a2f3cb348a4ea4c1fbe8ce739002fd0f8461da40
languageName: node
linkType: hard
@@ -4075,7 +4075,7 @@ __metadata:
"@babel/plugin-proposal-decorators": "npm:^7.24.7"
"@babel/plugin-transform-class-properties": "npm:^7.24.7"
"@cycjimmy/jsmpeg-player": "npm:^6.0.5"
"@dermotduffy/custom-card-helpers": "npm:^1.9.0"
"@dermotduffy/custom-card-helpers": "npm:^1.9.1"
"@dermotduffy/panzoom": "npm:^4.5.1"
"@egjs/hammerjs": "npm:^2.0.17"
"@graphiteds/core": "npm:^1.9.21"
@@ -4106,7 +4106,7 @@ __metadata:
eslint-config-airbnb-base: "npm:^15.0.0"
eslint-config-prettier: "npm:^9.1.0"
eslint-plugin-import: "npm:^2.29.1"
home-assistant-js-websocket: "npm:^8.2.0"
home-assistant-js-websocket: "npm:^9.4.0"
jsdom: "npm:^21.1.2"
keycharm: "npm:^0.4.0"
lit: "npm:^3.1.4"
@@ -4559,17 +4559,10 @@ __metadata:
languageName: node
linkType: hard
"home-assistant-js-websocket@npm:^6.0.1":
version: 6.1.1
resolution: "home-assistant-js-websocket@npm:6.1.1"
checksum: 10c0/fe00b8d7a681d39b31ac5078b79fa1ef67cccd37df2c7ec31b1ad9ded33c899570b453c9439db71c3bda24df6d0c1e3d9d040583b0717f4630476ab528120a9f
languageName: node
linkType: hard
"home-assistant-js-websocket@npm:^8.2.0":
version: 8.2.0
resolution: "home-assistant-js-websocket@npm:8.2.0"
checksum: 10c0/9a1f1f5cb39ce0629653347d5ae31a14f14742596c15fea7bd72f4c0ee4ce4613b1172b4f4df52f293b4e5aeb3b5ead75f395d5fe5c4785193e7d00f8355ef5a
"home-assistant-js-websocket@npm:^9.4.0":
version: 9.4.0
resolution: "home-assistant-js-websocket@npm:9.4.0"
checksum: 10c0/9c8a5ff903648ebe7856f62a58af53e3d89dd24a30c600a2145ed518cd5f5f2218345048cfc42bdc3ee5d6f2994da3948765c77b6012ed56cf4546173a1a1de1
languageName: node
linkType: hard