I created a Resource in javascript as a substitution for using the CSS Hue-Rotate function, which I feel doesn’t accurately represent the colors I’m seeing in real life.
I got it working great on one Dashboard. But when I use the same resource on a new dashboard, it doesn’t seem to be getting the State of the Entity. I’ve actually cobbled this together a while ago, and thought I had it working pretty well. But my knowledge of how this all works is limited. I started on this site https://github.com/home-assistant-tutorials and went from there.
The problem I seem to be having when I call this on a new dashboard is the first line in the getCanvasInfo() function. I believe this._state comes back as undefined and therefore defaults to ‘unavailable’
Hopefully I explained that well.
I don’t know if anyone with more experience and knowledge can figure out what I’m doing wrong.
I’ve included the first part of my code. Hopefully formatted properly.
class ImageHueRotateCard extends HTMLElement {
//private properties
_config;
_hass;
_elements = {};
_state;
_imWidth;
_imHeight;
constructor() {
super();
this.createCard();
this.createStyle();
this.attachCard();
this.setElements();
}
setConfig(config) {
if (!config.entity) {
throw new Error("You need to define an entity");
}
if (!config.state_image || !config.state_image["on"]) {
throw new Error("You need to define an 'ON' state image");
}
if (!config.state_image["off"]) {
throw new Error("You need to define an 'OFF' state image");
}
if (!config.state_image["unavailable"]) {
throw new Error("You need to define an unavailable state image");
}
this._config = config;
}
set hass(hass) {
this._hass = hass;
this.updateHass();
}
onClicked() {
this.doToggle();
}
connectedCallback() {
this.getCanvasInfo();
}
createCard() {
this._elements.card = document.createElement('ha-card');
this._elements.card.innerHTML = `
<div class="ihr-card">
<canvas class="c1" id ="canvas1" style="display: block">
</canvas>
</div>
`;
}
createStyle() {
this._elements.style = document.createElement('style');
this._elements.style.textContent = `
.type-custom-image-canvas-card {
padding: 0 0 0 0;
margin: 0 0 0 0;
overflow: hidden;
}
.ihr-card {
padding: 0 0 0 0;
margin: 0 0 0 0;
overflow: hidden;
}
`
}
attachCard(){
this.attachShadow({mode: 'open'});
this.shadowRoot.append(this._elements.style, this._elements.card);
}
setElements() {
const card = this._elements.card;
this._elements.dimSrc = card.querySelector(".ihr-card");
this._elements.dimSrc.addEventListener("click", this.onClicked.bind(this), false);
}
updateHass() {
const entityID = this._config.entity;
this._state = this._hass.states[entityID];
}
getEntityID() {
return this._config.entity;
}
doToggle() {
this._hass.callService('light', 'toggle', {
entity_id: this.getEntityID()
});
}
getImageWidth(src) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve (img.width);
img.src = src;
});
}
getImageHeight(src) {
return new Promise((resolve) => {
const img = new Image();
img.onload = () => resolve (img.height);
img.src = src;
});
}
async getCanvasInfo() {
const stateStr = this._state ? this._state.state : 'unavailable';
if (stateStr == 'on') {
var imageSRC = this._config.state_image["on"];
} else if (stateStr == 'off') {
var imageSRC = this._config.state_image["off"];
} else {
var imageSRC = this._config.state_image["unavailable"];
}
console.log("The Entity is " + this._config.entity);
console.log("The State is "+ stateStr);
this._imWidth = await this.getImageWidth(imageSRC);
this._imHeight = await this.getImageHeight(imageSRC);
const cardSource = this._elements.dimSrc
const cardSize = cardSource.getBoundingClientRect();
var w = cardSize.width;
var h = this._imHeight * w / this._imWidth;
console.log("Image Size is: " + this._imWidth + " x " + this._imHeight)
console.log("Canvas Size is: " + w + " x " + h);
this.drawCanvas(imageSRC, w, h, stateStr, cardSource);
}
drawCanvas(src, w, h, state, card){
const canvas = this._elements.card.querySelector('.c1');
const ctx = canvas.getContext('2d',{willReadFrequently: true});
const image1 = new Image();
image1.src = src;
ctx.canvas.width = w;
ctx.canvas.height = h;
ctx.drawImage(image1, 0, 0, w, h);
if(state == 'on'){
this.changeHue(ctx, w, h);
}
setInterval(() => {
let currentCardSize = card.getBoundingClientRect();
if (currentCardSize.width != w) {
this.reDrawCanvas(ctx, currentCardSize.width, w, h, image1, state);
w = currentCardSize.width;
h = this._imHeight * w / this._imWidth;;
}
})
}
reDrawCanvas(ctx, newW, w, h, img, state) {
var scale = newW / w;
var newH = h * scale;
ctx.canvas.width = newW;
ctx.canvas.height = newH;
ctx.scale(scale, scale);
ctx.drawImage(img, 0, 0, w, h);
if(state == 'on'){
this.changeHue(ctx, w, h);
}
ctx.scale(-scale, -scale);
}