frontend/smart-hut/src/components/dashboard/devices/Sensor.js

199 lines
5.2 KiB
JavaScript
Raw Normal View History

/**
* Users can add sensors in their rooms.
* Sensors typically measure physical quantities in a room.
* You must support temperature sensors, humidity sensors, light sensors (which measure luminosity1).
* Sensors have an internal state that cannot be changed by the user.
* For this story, make the sensors return a constant value with some small random error.
*/
2020-03-23 20:24:17 +00:00
/*
2020-03-23 18:08:31 +00:00
OPTIONAL STATE
error: 2.4
2020-03-23 18:08:31 +00:00
<text style={errorStyle} x={100} y={100} textAnchor="middle" dy="0.6em" fontWeight="bold">
&#177;{this.state.error}
</text>
errorStyle,
*/
2020-03-23 20:24:17 +00:00
import React, { Component } from "react";
2020-03-25 16:20:53 +00:00
import { CircularInput, CircularProgress } from "react-circular-input";
2020-03-25 15:04:02 +00:00
import {
container,
sensorText,
style,
valueStyle,
motionSensorInnerCircle,
motionSensorOuterCircle,
nameMotionStyle,
motionSensorIcon,
temperatureSensorColors,
lightSensorColors,
humiditySensorColors,
2020-03-25 16:20:53 +00:00
iconSensorStyle,
2020-03-25 15:04:02 +00:00
} from "./SensorStyle";
2020-03-24 19:35:23 +00:00
import { Image } from "semantic-ui-react";
2020-04-10 15:25:52 +00:00
import { RemoteService } from "../../../remote";
import { connect } from "react-redux";
2020-04-10 15:25:52 +00:00
class Sensor extends Component {
constructor(props) {
super(props);
this.state = {
2020-03-23 18:08:31 +00:00
value: 0,
2020-03-24 19:35:23 +00:00
motion: false,
};
2020-03-23 20:24:17 +00:00
this.units = "";
this.stateCallback = (e) => {
this.setState(Object.assign(this.state, e));
};
2020-03-25 15:04:02 +00:00
this.colors = temperatureSensorColors;
this.icon = "temperatureIcon.svg";
this.name = "Sensor";
}
// setName = () => {
// if (this.props.device.name.length > 15) {
// return this.props.device.name.slice(0, 12) + "...";
// }
// return this.props.device.name;
// };
componentDidUpdate(prevProps) {
if (
this.props.device.kind === "sensor" &&
this.props.device.value !== prevProps.device.value
) {
this.setState({ value: this.props.device.value });
} else if (
this.props.device.kind === "motionSensor" &&
this.props.device.detected !== prevProps.device.detected
) {
this.setState({ motion: true, detected: this.props.device.detected });
}
}
componentDidMount() {
2020-03-24 19:35:23 +00:00
if (this.props.device.kind === "sensor") {
switch (this.props.device.sensor) {
case "TEMPERATURE":
this.units = "ºC";
2020-03-25 15:04:02 +00:00
this.colors = temperatureSensorColors;
2020-03-25 16:20:53 +00:00
this.icon = "temperatureIcon.svg";
this.name = "Temperature Sensor";
2020-03-24 19:35:23 +00:00
break;
case "HUMIDITY":
this.units = "%";
2020-03-25 15:04:02 +00:00
this.colors = humiditySensorColors;
2020-03-25 16:20:53 +00:00
this.icon = "humidityIcon.svg";
this.name = "Humidity Sensor";
2020-03-24 19:35:23 +00:00
break;
case "LIGHT":
this.units = "lm";
2020-03-25 15:04:02 +00:00
this.colors = lightSensorColors;
2020-03-25 16:20:53 +00:00
this.icon = "lightSensorIcon.svg";
this.name = "Light Sensor";
2020-03-24 19:35:23 +00:00
break;
default:
this.units = "";
}
this.setState({
value: this.props.device.value,
});
} else {
this.setState({
detected: this.props.device.detected,
motion: true,
});
2020-03-23 18:08:31 +00:00
}
}
2020-03-24 19:35:23 +00:00
getIcon = () => {
if (this.state.detected) {
return this.iconOn;
}
return this.iconOff;
};
render() {
2020-03-25 15:04:02 +00:00
const MotionSensor = (props) => {
return (
2020-03-25 16:20:53 +00:00
<div
style={{
...motionSensorOuterCircle,
backgroundColor: this.state.detected ? "#505bda" : "#00bdaa",
}}
>
<div
style={{
...motionSensorInnerCircle,
backgroundColor: this.state.detected ? "#fe346e" : "#00bdaa",
}}
>
2020-03-25 15:04:02 +00:00
<Image style={motionSensorIcon} src="/img/motionSensorIcon.svg" />
<span style={nameMotionStyle}>Motion Sensor</span>
2020-03-25 16:20:53 +00:00
</div>
2020-03-25 15:04:02 +00:00
</div>
2020-03-25 16:20:53 +00:00
);
2020-03-25 15:04:02 +00:00
};
return (
2020-03-25 15:04:02 +00:00
<div style={container}>
2020-03-24 19:35:23 +00:00
{this.state.motion ? (
2020-03-25 15:04:02 +00:00
<MotionSensor />
2020-03-24 19:35:23 +00:00
) : (
2020-03-25 16:20:53 +00:00
<React.Fragment>
<CircularInput
value={
this.props.device.sensor === "LIGHT"
? this.state.value / 2000
: this.state.value / 100
}
style={style}
>
<CircularProgress
strokeWidth="2rem"
stroke={this.colors.progress}
fill={this.colors.circle}
/>
<text
style={{ ...valueStyle, fill: this.colors.text }}
x={100}
y={110}
textAnchor="middle"
dy="0.3em"
fontWeight="bold"
fill={this.colors.text}
>
{+(Math.round(this.state.value + "e+2") + "e-2")}
{this.units}
</text>
<text
style={{ ...sensorText, fill: this.colors.text }}
x={100}
y={150}
textAnchor="middle"
dy="0.4em"
fontWeight="bold"
>
{this.name}
2020-03-25 16:20:53 +00:00
</text>
</CircularInput>
<Image style={iconSensorStyle} src={`/img/${this.icon}`} />
</React.Fragment>
)}
2020-03-25 15:04:02 +00:00
</div>
2020-03-23 20:24:17 +00:00
);
}
}
2020-04-10 15:25:52 +00:00
const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id],
});
const SensorContainer = connect(mapStateToProps, RemoteService)(Sensor);
export default SensorContainer;