mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 02:36:37 +00:00
Use signed path for camera snapshot (#3138)
This commit is contained in:
parent
1e85880d7b
commit
73ef03e33f
@ -6,7 +6,7 @@ import "@polymer/paper-icon-button/paper-icon-button";
|
|||||||
import "@polymer/paper-input/paper-input";
|
import "@polymer/paper-input/paper-input";
|
||||||
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
import { html } from "@polymer/polymer/lib/utils/html-tag";
|
||||||
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
import { PolymerElement } from "@polymer/polymer/polymer-element";
|
||||||
import { getSignedPath } from "../../../../src/auth/data";
|
import { getSignedPath } from "../../../../src/data/auth";
|
||||||
|
|
||||||
import "../../../../src/resources/ha-style";
|
import "../../../../src/resources/ha-style";
|
||||||
import "../../../../src/components/dialog/ha-paper-dialog";
|
import "../../../../src/components/dialog/ha-paper-dialog";
|
||||||
|
@ -1,7 +0,0 @@
|
|||||||
import { HomeAssistant } from "../types";
|
|
||||||
import { SignedPath } from "./types";
|
|
||||||
|
|
||||||
export const getSignedPath = (
|
|
||||||
hass: HomeAssistant,
|
|
||||||
path: string
|
|
||||||
): Promise<SignedPath> => hass.callWS({ type: "auth/sign_path", path });
|
|
@ -1,3 +0,0 @@
|
|||||||
export interface SignedPath {
|
|
||||||
path: string;
|
|
||||||
}
|
|
@ -5,6 +5,7 @@ import { PolymerElement } from "@polymer/polymer/polymer-element";
|
|||||||
import computeStateName from "../common/entity/compute_state_name";
|
import computeStateName from "../common/entity/compute_state_name";
|
||||||
import EventsMixin from "../mixins/events-mixin";
|
import EventsMixin from "../mixins/events-mixin";
|
||||||
import LocalizeMixin from "../mixins/localize-mixin";
|
import LocalizeMixin from "../mixins/localize-mixin";
|
||||||
|
import { fetchThumbnailUrlWithCache } from "../data/camera";
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 10000; // ms
|
const UPDATE_INTERVAL = 10000; // ms
|
||||||
/*
|
/*
|
||||||
@ -54,6 +55,8 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
src="[[cameraFeedSrc]]"
|
src="[[cameraFeedSrc]]"
|
||||||
class="camera-feed"
|
class="camera-feed"
|
||||||
alt="[[_computeStateName(stateObj)]]"
|
alt="[[_computeStateName(stateObj)]]"
|
||||||
|
on-load="_imageLoaded"
|
||||||
|
on-error="_imageError"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
<div class="caption">
|
<div class="caption">
|
||||||
@ -98,23 +101,23 @@ class HaCameraCard extends LocalizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
clearInterval(this.timer);
|
clearInterval(this.timer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_imageLoaded() {
|
||||||
|
this.imageLoaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_imageError() {
|
||||||
|
this.imageLoaded = false;
|
||||||
|
}
|
||||||
|
|
||||||
cardTapped() {
|
cardTapped() {
|
||||||
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
this.fire("hass-more-info", { entityId: this.stateObj.entity_id });
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateCameraFeedSrc() {
|
async updateCameraFeedSrc() {
|
||||||
try {
|
this.cameraFeedSrc = await fetchThumbnailUrlWithCache(
|
||||||
const { content_type: contentType, content } = await this.hass.callWS({
|
this.hass,
|
||||||
type: "camera_thumbnail",
|
this.stateObj.entity_id
|
||||||
entity_id: this.stateObj.entity_id,
|
);
|
||||||
});
|
|
||||||
this.setProperties({
|
|
||||||
imageLoaded: true,
|
|
||||||
cameraFeedSrc: `data:${contentType};base64, ${content}`,
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
this.imageLoaded = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeStateName(stateObj) {
|
_computeStateName(stateObj) {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import { HomeAssistant } from "../types";
|
||||||
|
|
||||||
export interface AuthProvider {
|
export interface AuthProvider {
|
||||||
name: string;
|
name: string;
|
||||||
id: string;
|
id: string;
|
||||||
@ -7,3 +9,12 @@ export interface AuthProvider {
|
|||||||
export interface Credential {
|
export interface Credential {
|
||||||
type: string;
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface SignedPath {
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getSignedPath = (
|
||||||
|
hass: HomeAssistant,
|
||||||
|
path: string
|
||||||
|
): Promise<SignedPath> => hass.callWS({ type: "auth/sign_path", path });
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { HomeAssistant, CameraEntity } from "../types";
|
import { HomeAssistant, CameraEntity } from "../types";
|
||||||
import { timeCachePromiseFunc } from "../common/util/time-cache-function-promise";
|
import { timeCachePromiseFunc } from "../common/util/time-cache-function-promise";
|
||||||
|
import { getSignedPath } from "./auth";
|
||||||
|
|
||||||
export const CAMERA_SUPPORT_ON_OFF = 1;
|
export const CAMERA_SUPPORT_ON_OFF = 1;
|
||||||
export const CAMERA_SUPPORT_STREAM = 2;
|
export const CAMERA_SUPPORT_STREAM = 2;
|
||||||
@ -22,16 +23,29 @@ export const computeMJPEGStreamUrl = (entity: CameraEntity) =>
|
|||||||
entity.attributes.access_token
|
entity.attributes.access_token
|
||||||
}`;
|
}`;
|
||||||
|
|
||||||
export const fetchThumbnailWithCache = (
|
export const fetchThumbnailUrlWithCache = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
entityId: string
|
entityId: string
|
||||||
) => timeCachePromiseFunc("_cameraTmb", 9000, fetchThumbnail, hass, entityId);
|
) =>
|
||||||
|
timeCachePromiseFunc(
|
||||||
|
"_cameraTmbUrl",
|
||||||
|
9000,
|
||||||
|
fetchThumbnailUrl,
|
||||||
|
hass,
|
||||||
|
entityId
|
||||||
|
);
|
||||||
|
|
||||||
export const fetchThumbnail = (hass: HomeAssistant, entityId: string) =>
|
export const fetchThumbnailUrl = (hass: HomeAssistant, entityId: string) =>
|
||||||
hass.callWS<CameraThumbnail>({
|
getSignedPath(hass, `/api/camera_proxy/${entityId}`).then(({ path }) => path);
|
||||||
|
|
||||||
|
export const fetchThumbnail = (hass: HomeAssistant, entityId: string) => {
|
||||||
|
// tslint:disable-next-line: no-console
|
||||||
|
console.warn("This method has been deprecated.");
|
||||||
|
return hass.callWS<CameraThumbnail>({
|
||||||
type: "camera_thumbnail",
|
type: "camera_thumbnail",
|
||||||
entity_id: entityId,
|
entity_id: entityId,
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
export const fetchStreamUrl = (
|
export const fetchStreamUrl = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
@ -17,8 +17,7 @@ import {
|
|||||||
import { HomeAssistant, CameraEntity } from "../../../types";
|
import { HomeAssistant, CameraEntity } from "../../../types";
|
||||||
import { styleMap } from "lit-html/directives/style-map";
|
import { styleMap } from "lit-html/directives/style-map";
|
||||||
import { classMap } from "lit-html/directives/class-map";
|
import { classMap } from "lit-html/directives/class-map";
|
||||||
import { b64toBlob } from "../../../common/file/b64-to-blob";
|
import { fetchThumbnailUrlWithCache } from "../../../data/camera";
|
||||||
import { fetchThumbnailWithCache } from "../../../data/camera";
|
|
||||||
|
|
||||||
const UPDATE_INTERVAL = 10000;
|
const UPDATE_INTERVAL = 10000;
|
||||||
const DEFAULT_FILTER = "grayscale(100%)";
|
const DEFAULT_FILTER = "grayscale(100%)";
|
||||||
@ -197,21 +196,20 @@ export class HuiImage extends LitElement {
|
|||||||
if (!this.hass || !this.cameraImage) {
|
if (!this.hass || !this.cameraImage) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
const {
|
const cameraState = this.hass.states[this.cameraImage] as
|
||||||
content_type: contentType,
|
| CameraEntity
|
||||||
content,
|
| undefined;
|
||||||
} = await fetchThumbnailWithCache(this.hass, this.cameraImage);
|
|
||||||
if (this._cameraImageSrc) {
|
if (!cameraState) {
|
||||||
URL.revokeObjectURL(this._cameraImageSrc);
|
|
||||||
}
|
|
||||||
this._cameraImageSrc = URL.createObjectURL(
|
|
||||||
b64toBlob(content, contentType)
|
|
||||||
);
|
|
||||||
this._onImageLoad();
|
|
||||||
} catch (err) {
|
|
||||||
this._onImageError();
|
this._onImageError();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._cameraImageSrc = await fetchThumbnailUrlWithCache(
|
||||||
|
this.hass,
|
||||||
|
this.cameraImage
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles(): CSSResult {
|
static get styles(): CSSResult {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user