Newer
Older
smart-home-server / webclient / src / js / components / screens / devices / device-state-component.js
const renderingByType = {
	relay: (alias, deviceResp) => {
		let channels = "";
		for(let channel of deviceResp.channels) {
			const channelState = channel.state == "off" ? "OFF" : "ON";
			const channelStateClass = channel.state == "on" ? "badge-success" : "";
			const chId = deviceResp.channels.length > 1 ? `${channel.id}:` : "";
			channels += `
				<span class="badge ${channelStateClass}">${chId}<b>${channelState}</b></span>
			`;
		}

		return `<div class="channels f-grid g-2">${channels}</div>`;
	},

	button: (alias, deviceResp) => {
		const channelClassMap = {
			enabled: "badge-success",
			disabled: "",
			mute: "badge-primary-outline",
			waiting: "badge-warning",
			error: "badge-error"
		};

		let channels = "";
		for(let channel of deviceResp.channels) {
			channels += `
				<span class="badge ${channelClassMap[channel.indicator]}">${channel.id}:<b>${channel.indicator}</b></span>
			`;
		}

		return `<div class="channels f-grid g-2">${channels}</div>`;
	},

	sensor: (alias, deviceResp) => {
		/*
		{"status":"ok","indicators":"ok","sensors":{
			"light":{"online":true,"level":5,"lux":240.17,"percent":48},
			"temperature":{"online":true,"current":26.44,"dynamics":"constant","dynamics_val":0},
			"pressure":{"online":true,"current":1000.69,"dynamics":"constant","dynamics_val":0},
			"humidity":{"online":true,"current":43.02,"dynamics":"constant","dynamics_val":0},
			"radar":{"online":true,"presence":true,"activity_score":1,"activity_score_current":1,"activity_score_dynamics":"constant","distance_m":0},
			"microphone":{"online":true,"current_noise":53,"noise_level":7,"noise_level_dbi":50,"noise_dynamics":"constant"}}}
		 */

		const dynamics = dynamics => {
			switch(dynamics) {
				case "constant": return `<i class="ph ph-minus"></i>`;
				case "increasing": return `<i class="ph ph-caret-up"></i>`;
				case "decreasing": return `<i class="ph ph-caret-down"></i>`;
				case "variable": return `~`;
			}

			return ``;
		};

		const presence = deviceResp.sensors.radar.presence 
			? `<i class="ph ph-user-square"></i>${deviceResp.sensors.radar.activity_score}${dynamics(deviceResp.sensors.radar.activity_score_dynamics)}` 
			: '<i class="ph ph-square"></i>'; 
		const temperature = deviceResp.sensors.temperature.current + "°C" + dynamics(deviceResp.sensors.temperature.dynamics); 
		const humidity = deviceResp.sensors.humidity.current + "%" + dynamics(deviceResp.sensors.humidity.dynamics); 
		const pressure = deviceResp.sensors.pressure.current + "hpa" + dynamics(deviceResp.sensors.pressure.dynamics); 
		const light = deviceResp.sensors.light.percent + "%"; 
		const noise = deviceResp.sensors.microphone.current_noise + "dBi" + dynamics(deviceResp.sensors.microphone.noise_dynamics); 

		let sensors = `
			<span class="badge badge-primary">${presence}</span>
			<span class="badge badge-primary"><i class="ph ph-thermometer"></i>${temperature}</span>
			<span class="badge badge-primary"><i class="ph ph-drop-half-bottom"></i>${humidity}</span>
			<span class="badge badge-primary">${pressure}</span>
			<span class="badge badge-primary"><i class="ph ph-lightbulb"></i>${light}</span>
			<span class="badge badge-primary"><i class="ph ph-ear"></i>${noise}</span>
		`;

		return `<div class="channels f-grid g-2">${sensors}</div>`;
	}
};

function initEventHandlers(component) {
	component.addEventListener("click", e => {
		e.currentTarget.deviceStateComponent.create();
	});
}

function stateRendering(deviceType, deviceAlias, deviceResponse) {
	return typeof renderingByType[deviceType] != "undefined"
		? renderingByType[deviceType](deviceAlias, deviceResponse)
		: "Unknown device type<br>" + JSON.stringify(deviceResponse);
}

export default function deviceStateComponent(sh_api, deviceId, deviceType) {
	const component = Helper.template.createElement("div", {
		class: "component device-state-component"
	}, "");

	component.deviceStateComponent = {
		create: () => {
			component.innerHTML = Helper.template.circleLoaderHTML();

			sh_api.devices.status(deviceId, (err, resp, meta) => {
				console.log("sh_api.devices.status", err, resp);

				if(!resp) {
					component.innerHTML = `
						<span class="badge badge-error"><i class="ph ph-warning-octagon fs-lg normalize"></i> Loading Error</span>
					`;
					return console.error("deviceStateComponent", `DeviceID ${deviceId}`);
				}

				component.innerHTML = stateRendering(deviceType, resp.data.device.alias, resp.data.device.device_response);
				initEventHandlers(component);
			});
		}
	}

	component.deviceStateComponent.create();

	return component;
}