Merge branch '82-scene-states-update' into 'dev'

Resolve "scene-states-update"

Closes #82

See merge request sa4-2020/the-sanmarinoes/frontend!94
This commit is contained in:
Andrea Brites Marto 2020-04-25 19:03:41 +02:00
commit a54df637cd
11 changed files with 464 additions and 186 deletions

View file

@ -15,9 +15,10 @@ class ScenesPanel extends Component {
<Grid doubling columns={2} divided="vertically"> <Grid doubling columns={2} divided="vertically">
{!this.props.isActiveDefaultScene {!this.props.isActiveDefaultScene
? this.props.sceneStates.map((e, i) => { ? this.props.sceneStates.map((e, i) => {
console.log(this.props.sceneStates);
return ( return (
<Grid.Column key={i}> <Grid.Column key={i}>
<Device tab={this.props.tab} id={e} /> <Device tab={this.props.tab} id={e.id} />
</Grid.Column> </Grid.Column>
); );
}) })
@ -40,7 +41,8 @@ const mapStateToProps = (state, _) => ({
const stateArray = [ const stateArray = [
...state.scenes[state.active.activeScene].sceneStates, ...state.scenes[state.active.activeScene].sceneStates,
].sort(); ].sort();
return stateArray.map((id) => state.sceneStates[id]); console.log(stateArray);
return stateArray;
} else { } else {
return []; return [];
} }

View file

@ -2,30 +2,33 @@ import React, { Component } from "react";
import "./Curtains.css"; import "./Curtains.css";
import { RemoteService } from "../../../remote"; import { RemoteService } from "../../../remote";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Slider } from "@material-ui/core";
class Curtain extends Component { class Curtain extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { intensity: this.props.device.intensity, timeout: null }; this.state = { intensity: this.props.stateOrDevice.intensity, timeout: null };
this.setIntensity = this.setIntensity.bind(this); this.setIntensity = this.setIntensity.bind(this);
} }
//getters //getters
get turnedOn() { get turnedOn() {
return this.props.device.on; return this.props.stateOrDevice.on;
} }
get intensity() { get intensity() {
return this.props.device.intensity || 0; return this.props.stateOrDevice.intensity || 0;
} }
onClickDevice = () => { onClickDevice = () => {
const on = !this.turnedOn; const on = !this.turnedOn;
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, on }) this.props
.catch((err) => console.error("curtains update error", err)); .saveDevice({ ...this.props.stateOrDevice, on })
.catch((err) => console.error("curtains update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, on: on },this.props.sceneState.kind);
}
}; };
setIntensity(intensity) { setIntensity(intensity) {
@ -49,9 +52,13 @@ class Curtain extends Component {
saveIntensity = () => { saveIntensity = () => {
const intensity = Math.round(this.state.intensity); const intensity = Math.round(this.state.intensity);
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, intensity }) this.props
.catch((err) => console.error("curtains update error", err)); .saveDevice({ ...this.props.stateOrDevice, intensity })
.catch((err) => console.error("curtain update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, intensity: intensity },this.props.sceneState.kind);
}
}; };
helper = () => { helper = () => {
@ -59,7 +66,7 @@ class Curtain extends Component {
this.setIntensity(1); this.setIntensity(1);
this.saveIntensity(); this.saveIntensity();
} else { } else {
this.setIntensity(this.props.device.intensity / 100 + 0.1); this.setIntensity(this.props.stateOrDevice.intensity / 100 + 0.1);
this.saveIntensity(); this.saveIntensity();
} }
}; };
@ -78,15 +85,15 @@ class Curtain extends Component {
<div <div
className="open-container" className="open-container"
style={{ style={{
height: (9 * this.props.device.intensity) / 100 + "rem", height: (9 * this.props.stateOrDevice.intensity) / 100 + "rem",
}} }}
></div>{" "} ></div>{" "}
<span className="span-open"> <span className="span-open">
{Math.round(this.props.device.intensity)}% {Math.round(this.props.stateOrDevice.intensity)}%
</span> </span>
<input <input
onChange={this.handleChange} onChange={this.handleChange}
value={this.props.device.intensity} value={this.props.stateOrDevice.intensity}
className="slider" className="slider"
type="range" type="range"
min="0" min="0"
@ -99,7 +106,14 @@ class Curtain extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice(){
if(state.active.activeTab==="Devices"){
return state.devices[ownProps.id];
}else{
return state.sceneStates[ownProps.id];
}
},
//device: state.devices[ownProps.id],
}); });
const CurtainContainer = connect(mapStateToProps, RemoteService)(Curtain); const CurtainContainer = connect(mapStateToProps, RemoteService)(Curtain);
export default CurtainContainer; export default CurtainContainer;

View file

@ -13,114 +13,237 @@ import { connect } from "react-redux";
import DeviceSettingsModal from "./DeviceSettingsModal"; import DeviceSettingsModal from "./DeviceSettingsModal";
class Device extends React.Component { class Device extends React.Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.modalRef = React.createRef(); this.modalRef = React.createRef();
this.edit = this.edit.bind(this); this.edit = this.edit.bind(this);
this.resetSmartPlug = this.resetSmartPlug.bind(this); this.resetSmartPlug = this.resetSmartPlug.bind(this);
} this.deleteState=this.deleteState.bind(this);
}
edit() { edit() {
console.log("editing device with id=" + this.props.id); console.log("editing device with id=" + this.props.id);
this.modalRef.current.openModal(); this.modalRef.current.openModal();
} }
resetSmartPlug() { resetSmartPlug() {
this.props this.props
.smartPlugReset(this.props.id) .smartPlugReset(this.props.id)
.catch((err) => console.error(`Smart plug reset error`, err)); .catch((err) => console.error(`Smart plug reset error`, err));
} }
renderDeviceComponent() { deleteState() {
console.log("check here") //console.log("alpaca "+this.props);
console.log(this.props.stateOrDevice.kind) this.props.deleteState(this.props.id, this.props.type);
switch (this.props.stateOrDevice.kind) { }
case "curtains":
return <Curtains tab={this.props.tab} id={this.props.id} />;
case "thermostat":
return <Thermostat tab={this.props.tab} id={this.props.id} />;
case "regularLight":
return <Light tab={this.props.tab} id={this.props.id} />;
case "sensor":
return <Sensor tab={this.props.tab} id={this.props.id} />;
case "motionSensor":
return <Sensor tab={this.props.tab} id={this.props.id} />;
case "buttonDimmer":
return <ButtonDimmer tab={this.props.tab} id={this.props.id} />;
case "knobDimmer":
return <KnobDimmer tab={this.props.tab} id={this.props.id} />;
case "smartPlug":
return <SmartPlug tab={this.props.tab} id={this.props.id} />;
case "switch":
return <Switcher tab={this.props.tab} id={this.props.id} />;
case "dimmableLight":
return <Light id={this.props.id} />;
case "securityCamera":
return <Videocam id={this.props.id} />;
default:
throw new Error("Device type unknown");
}
}
render() { renderDeviceComponent() {
switch (
this.props.tab === "Devices"
? this.props.stateOrDevice.kind
: this.props.type
) {
case "curtains":
return ( return (
<Segment> <Curtains
<Grid columns={2}> tab={this.props.tab}
<Grid.Column>{this.renderDeviceComponent()}</Grid.Column> sceneState={this.props.sceneState}
{this.props.tab === "Devices" ? ( id={this.props.id}
<Grid.Column textAlign="center"> />
<Header as="h3">
{this.props.stateOrDevice.name}
</Header>
<Button
color="blue"
icon
onClick={this.edit}
labelPosition="left"
>
<Icon name="pencil" />
Edit
</Button>
{this.props.stateOrDevice.kind === "smartPlug" ? (
<Button
color="orange"
icon
onClick={this.resetSmartPlug}
labelPosition="left"
>
<Icon name="undo" />
Reset
</Button>
) : null}
</Grid.Column>
) : (
<Grid.Column textAlign="center">
<Header as="h3">
{this.props.stateOrDevice.name}
</Header>
</Grid.Column>
)}
<DeviceSettingsModal
ref={this.modalRef}
id={this.props.id}
/>
</Grid>
</Segment>
); );
case "thermostat":
return (
<Thermostat
tab={this.props.tab}
sceneState={this.props.sceneStat}
id={this.props.stateOrDevice.id}
/>
);
case "regularLight":
return (
<Light
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "sensor":
return (
<Sensor
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "motionSensor":
return (
<Sensor
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "buttonDimmer":
return (
<ButtonDimmer
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "knobDimmer":
return (
<KnobDimmer
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "smartPlug":
return (
<SmartPlug
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "switch":
return (
<Switcher
tab={this.props.tab}
sceneState={this.props.sceneState}
id={this.props.stateOrDevice.id}
/>
);
case "dimmableLight":
return (
<Light
id={this.props.stateOrDevice.id}
sceneState={this.props.sceneState}
tab={this.props.tab}
/>
);
case "securityCamera":
return (
<Videocam
id={this.props.stateOrDevice.id}
sceneState={this.props.sceneState}
tab={this.props.tab}
/>
);
default:
//throw new Error("Device type unknown");
return undefined;
} }
} }
render() {
{
if (this.props.type !== "") {
return (
<Segment>
<Grid columns={2}>
<Grid.Column>{this.renderDeviceComponent()}</Grid.Column>
{this.props.tab === "Devices" ? (
<Grid.Column textAlign="center">
<Header as="h3">{this.props.stateOrDevice.name}</Header>
<Button
color="blue"
icon
onClick={this.edit}
labelPosition="left"
>
<Icon name="pencil" />
Edit
</Button>
{this.props.stateOrDevice.kind === "smartPlug" ? (
<Button
color="orange"
icon
onClick={this.resetSmartPlug}
labelPosition="left"
>
<Icon name="undo" />
Reset
</Button>
) : null}
</Grid.Column>
) : (
<Grid.Column textAlign="center">
<Header as="h3">
{this.props.stateOrDevice
? this.props.stateOrDevice.name
: ""}
</Header>
<Button
color="red"
icon
onClick={this.deleteState}
labelPosition="left"
>
<Icon name="undo" />
Delete
</Button>
</Grid.Column>
)}
</Grid>
</Segment>
);
} else {
return null;
}
}
}
}
/*
{this.props.stateOrDevice ?
<DeviceSettingsModal
ref={this.modalRef}
id={this.props.stateOrDevice.id}
/> :
""
}
*/
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
get stateOrDevice() { get stateOrDevice() {
if (state.active.activeTab === "Devices") { if (state.active.activeTab === "Devices") {
return state.devices[ownProps.id]; return state.devices[ownProps.id];
} else { } else {
const sceneState = state.sceneStates[ownProps.id]; console.log(
return state.devices[sceneState]; state.sceneStates,
} ownProps.id,
}, state.sceneStates[ownProps.id]
);
return state.sceneStates[ownProps.id];
}
},
get sceneState() {
if (state.active.activeTab === "Scenes") {
const array = [
...state.scenes[state.active.activeScene].sceneStates,
].sort();
const deviceState = array.filter((e) => e.id === ownProps.id)[0];
return deviceState;
} else {
return null;
}
},
get type() {
if (state.active.activeTab === "Scenes") {
if (state.sceneStates[ownProps.id]) {
console.log(state.sceneStates[ownProps.id], ownProps.id);
const id = state.sceneStates[ownProps.id].deviceId;
console.log(id, state.devices[id].kind);
return state.devices[id].kind;
} else {
return "";
}
} else {
return null;
}
},
}); });
const DeviceContainer = connect(mapStateToProps, RemoteService)(Device); const DeviceContainer = connect(mapStateToProps, RemoteService)(Device);
export default DeviceContainer; export default DeviceContainer;

View file

@ -64,7 +64,7 @@ export class KnobDimmerComponent extends Component {
super(props); super(props);
this.state = { this.state = {
intensity: this.props.device.intensity || 0, intensity: this.props.stateOrDevice.intensity || 0,
timeout: null, timeout: null,
}; };
@ -129,7 +129,13 @@ export class KnobDimmerComponent extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice(){
if(state.active.activeTab==="Devices"){
return state.devices[ownProps.id];
}else{
return state.sceneStates[ownProps.id];
}
},
}); });
const conn = connect(mapStateToProps, RemoteService); const conn = connect(mapStateToProps, RemoteService);

View file

@ -35,7 +35,10 @@ import { connect } from "react-redux";
class Light extends Component { class Light extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { intensity: this.props.device.intensity, timeout: null }; this.state = {
intensity: this.props.stateOrDevice.intensity,
timeout: null,
};
this.iconOn = "/img/lightOn.svg"; this.iconOn = "/img/lightOn.svg";
this.iconOff = "/img/lightOff.svg"; this.iconOff = "/img/lightOff.svg";
@ -44,24 +47,36 @@ class Light extends Component {
} }
componentDidUpdate(prevProps, prevState) { componentDidUpdate(prevProps, prevState) {
if (this.props.device.intensity !== prevProps.device.intensity) { if (
this.setState({ intensity: this.props.device.intensity, timeout: null }); this.props.stateOrDevice.intensity !== prevProps.stateOrDevice.intensity
) {
this.setState({
intensity: this.props.stateOrDevice.intensity,
timeout: null,
});
} }
} }
get turnedOn() { get turnedOn() {
return this.props.device.on; return this.props.stateOrDevice.on;
} }
get intensity() { get intensity() {
return this.props.device.intensity || 0; return this.props.stateOrDevice.intensity || 0;
} }
onClickDevice = () => { onClickDevice = () => {
const on = !this.turnedOn; const on = !this.turnedOn;
this.props if (this.props.tab === "Devices") {
.saveDevice({ ...this.props.device, on }) this.props
.catch((err) => console.error("regular light update error", err)); .saveDevice({ ...this.props.stateOrDevice, on })
.catch((err) => console.error("regular light update error", err));
} else {
this.props.updateState(
{ id: this.props.sceneState.id, on: on },
this.props.sceneState.kind
);
}
}; };
getIcon = () => { getIcon = () => {
@ -89,9 +104,16 @@ class Light extends Component {
saveIntensity = () => { saveIntensity = () => {
const intensity = Math.round(this.state.intensity); const intensity = Math.round(this.state.intensity);
this.props if (this.props.tab === "Devices") {
.saveDevice({ ...this.props.device, intensity }) this.props
.catch((err) => console.error("intensity light update error", err)); .saveDevice({ ...this.props.stateOrDevice, intensity })
.catch((err) => console.error("regular light update error", err));
} else {
this.props.updateState(
{ id: this.props.sceneState.id, intensity: intensity },
this.props.sceneState.kind
);
}
}; };
render() { render() {
@ -139,7 +161,7 @@ class Light extends Component {
return ( return (
<div> <div>
{this.props.device.kind === "dimmableLight" {this.props.stateOrDevice.kind === "dimmableLight"
? intensityLightView ? intensityLightView
: normalLightView} : normalLightView}
</div> </div>
@ -148,7 +170,15 @@ class Light extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice() {
if (state.active.activeTab === "Devices") {
return state.devices[ownProps.id];
} else {
return state.sceneStates[ownProps.id];
}
},
//device: state.devices[ownProps.id],
}); });
const LightContainer = connect(mapStateToProps, RemoteService)(Light); const LightContainer = connect(mapStateToProps, RemoteService)(Light);
export default LightContainer; export default LightContainer;

View file

@ -65,20 +65,20 @@ class Sensor extends Component {
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
if ( if (
this.props.device.kind === "sensor" && this.props.stateOrDevice.kind === "sensor" &&
this.props.device.value !== prevProps.device.value this.props.stateOrDevice.value !== prevProps.stateOrDevice.value
) { ) {
this.setState({ value: this.props.device.value }); this.setState({ value: this.props.stateOrDevice.value });
} else if ( } else if (
this.props.device.kind === "motionSensor" && this.props.stateOrDevice.kind === "motionSensor" &&
this.props.device.detected !== prevProps.device.detected this.props.stateOrDevice.detected !== prevProps.stateOrDevice.detected
) { ) {
this.setState({ motion: true, detected: this.props.device.detected }); this.setState({ motion: true, detected: this.props.stateOrDevice.detected });
} }
} }
componentDidMount() { componentDidMount() {
if (this.props.device.kind === "sensor") { if (this.props.stateOrDevice.kind === "sensor") {
switch (this.props.device.sensor) { switch (this.props.device.sensor) {
case "TEMPERATURE": case "TEMPERATURE":
this.units = "ºC"; this.units = "ºC";
@ -102,11 +102,11 @@ class Sensor extends Component {
this.units = ""; this.units = "";
} }
this.setState({ this.setState({
value: this.props.device.value, value: this.props.stateOrDevice.value,
}); });
} else { } else {
this.setState({ this.setState({
detected: this.props.device.detected, detected: this.props.stateOrDevice.detected,
motion: true, motion: true,
}); });
} }
@ -149,7 +149,7 @@ class Sensor extends Component {
<React.Fragment> <React.Fragment>
<CircularInput <CircularInput
value={ value={
this.props.device.sensor === "LIGHT" this.props.stateOrDevice.sensor === "LIGHT"
? this.state.value / 2000 ? this.state.value / 2000
: this.state.value / 100 : this.state.value / 100
} }
@ -192,7 +192,13 @@ class Sensor extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice(){
if(state.active.activeTab==="Devices"){
return state.devices[ownProps.id];
}else{
return state.sceneStates[ownProps.id];
}
},
}); });
const SensorContainer = connect(mapStateToProps, RemoteService)(Sensor); const SensorContainer = connect(mapStateToProps, RemoteService)(Sensor);
export default SensorContainer; export default SensorContainer;

View file

@ -24,18 +24,22 @@ class SmartPlug extends Component {
} }
get turnedOn() { get turnedOn() {
return this.props.device.on; return this.props.stateOrDevice.on;
} }
get energyConsumed() { get energyConsumed() {
return (this.props.device.totalConsumption / 1000).toFixed(3); return (this.props.stateOrDevice.totalConsumption / 1000).toFixed(3);
} }
onClickDevice = () => { onClickDevice = () => {
const on = !this.turnedOn; const on = !this.turnedOn;
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, on }) this.props
.catch((err) => console.error("smart plug update error", err)); .saveDevice({ ...this.props.stateOrDevice, on })
.catch((err) => console.error("smart plug update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, on: on},this.props.sceneState.kind);
}
}; };
getIcon = () => { getIcon = () => {
@ -64,7 +68,13 @@ class SmartPlug extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice(){
if(state.active.activeTab==="Devices"){
return state.devices[ownProps.id];
}else{
return state.sceneStates[ownProps.id];
}
},
}); });
const SmartPlugContainer = connect(mapStateToProps, RemoteService)(SmartPlug); const SmartPlugContainer = connect(mapStateToProps, RemoteService)(SmartPlug);
export default SmartPlugContainer; export default SmartPlugContainer;

View file

@ -19,11 +19,11 @@ class Thermostats extends Component {
constructor(props) { constructor(props) {
super(props); super(props);
this.state = { this.state = {
targetTemperature: this.props.device.targetTemperature, targetTemperature: this.props.stateOrDevice.targetTemperature,
internalSensorTemperature: this.props.device.internalSensorTemperature, internalSensorTemperature: this.props.stateOrDevice.internalSensorTemperature,
mode: this.props.device.mode, mode: this.props.stateOrDevice.mode,
measuredTemperature: this.props.device.measuredTemperature, measuredTemperature: this.props.stateOrDevice.measuredTemperature,
useExternalSensors: this.props.device.useExternalSensors, useExternalSensors: this.props.stateOrDevice.useExternalSensors,
timeout: null, timeout: null,
}; };
this.setMode = this.setMode.bind(this); this.setMode = this.setMode.bind(this);
@ -35,23 +35,23 @@ class Thermostats extends Component {
//getters //getters
get getMode() { get getMode() {
return this.props.device.mode; return this.props.stateOrDevice.mode;
} }
get getTargetTemperature() { get getTargetTemperature() {
return this.props.device.targetTemperature; return this.props.stateOrDevice.targetTemperature;
} }
get getInternalSensorTemperature() { get getInternalSensorTemperature() {
return this.props.device.internalSensorTemperature; return this.props.stateOrDevice.internalSensorTemperature;
} }
get getMeasuredTemperature() { get getMeasuredTemperature() {
return this.props.device.measuredTemperature; return this.props.stateOrDevice.measuredTemperature;
} }
get getUseExternalSensors() { get getUseExternalSensors() {
return this.props.device.useExternalSensors; return this.props.stateOrDevice.useExternalSensors;
} }
setMode(mode) { setMode(mode) {
@ -63,23 +63,35 @@ class Thermostats extends Component {
//i came to the conclusion that is not possible to set mode. //i came to the conclusion that is not possible to set mode.
//this.mode = "HEATING"; //this.mode = "HEATING";
const turnOn = mode; const turnOn = mode;
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, turnOn }) this.props
.catch((err) => console.error("regular light update error", err)); .saveDevice({ ...this.props.stateOrDevice, turnOn })
.catch((err) => console.error("thermostat update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, turnOn: turnOn },this.props.sceneState.kind);
}
} }
onClickDevice = () => { onClickDevice = () => {
const on = !this.turnedOn; const on = !this.turnedOn;
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, on }) this.props
.catch((err) => console.error("regular light update error", err)); .saveDevice({ ...this.props.stateOrDevice, on })
.catch((err) => console.error("thermostat update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, on: on },this.props.sceneState.kind);
}
}; };
//It seems to work //It seems to work
saveTargetTemperature(targetTemperature) { saveTargetTemperature(targetTemperature) {
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, targetTemperature }) this.props
.catch((err) => console.error(" update error", err)); .saveDevice({ ...this.props.stateOrDevice, targetTemperature })
.catch((err) => console.error("thermostat update error", err));
}else{
this.props.updateState({id: this.props.sceneState.id, targetTemperature: targetTemperature},this.props.sceneState.kind);
}
} }
setTargetTemperature(newTemp) { setTargetTemperature(newTemp) {
@ -101,9 +113,13 @@ class Thermostats extends Component {
//I have no idea why it doesn't want to update the temperature //I have no idea why it doesn't want to update the temperature
saveInternalSensorTemperature(internalSensorTemperature) { saveInternalSensorTemperature(internalSensorTemperature) {
this.props if(this.props.tab==="Devices"){
.saveDevice({ ...this.props.device, internalSensorTemperature }) this.props
.catch((err) => console.error(" update error", err)); .saveDevice({ ...this.props.device, internalSensorTemperature })
.catch((err) => console.error("thermostat update error", err));
}else{
this.props.updateState({ id: this.props.sceneState.id, internalSensorTemperature:internalSensorTemperature },this.props.sceneState.kind);
}
} }
setInternalSensorTemperature(newTemp) { setInternalSensorTemperature(newTemp) {
@ -137,7 +153,7 @@ class Thermostats extends Component {
return ( return (
<div style={container}> <div style={container}>
<h3 style={deviceName}>{this.props.device.name}</h3> <h3 style={deviceName}>{this.props.stateOrDevice.name}</h3>
<div style={line}></div> <div style={line}></div>
<Checkbox <Checkbox
slider slider
@ -147,19 +163,19 @@ class Thermostats extends Component {
/> />
<span style={targetTemperature}> <span style={targetTemperature}>
{this.props.device.targetTemperature}ºC {this.props.stateOrDevice.targetTemperature}ºC
</span> </span>
<input <input
type="range" type="range"
min="0" min="0"
max="40" max="40"
className="slider-css" className="slider-css"
value={this.props.device.targetTemperature} value={this.props.stateOrDevice.targetTemperature}
onChange={(event) => this.handleChange(event.target.value)} onChange={(event) => this.handleChange(event.target.value)}
id="targetTemperature" id="targetTemperature"
/> />
<div style={stateTagContainer}> <div style={stateTagContainer}>
<span style={stateTag}>{this.props.device.mode}</span> <span style={stateTag}>{this.props.stateOrDevice.mode}</span>
</div> </div>
</div> </div>
); );
@ -167,7 +183,14 @@ class Thermostats extends Component {
} }
const mapStateToProps = (state, ownProps) => ({ const mapStateToProps = (state, ownProps) => ({
device: state.devices[ownProps.id], get stateOrDevice(){
if(state.active.activeTab==="Devices"){
return state.devices[ownProps.id];
}else{
const sceneState = state.sceneStates[ownProps.id];
return state.devices[sceneState];
}
},
}); });
const ThermostatContainer = connect( const ThermostatContainer = connect(

View file

@ -374,6 +374,45 @@ export const RemoteService = {
}; };
}, },
//
updateState: (data, type) => {
return (dispatch) => {
let url;
if (type === "dimmableState") {
url = "/dimmableState";
} else {
url = "/switchableState";
}
return Endpoint.put(url, {}, data)
.then((res) => {
dispatch(actions.stateSave(res.data));
return res.data;
})
.catch((err) => {
console.warn("Update device: ", data, "error: ", err);
throw new RemoteError(["Network error"]);
});
};
},
deleteState: (id, type)=>{
return (dispatch)=>{
let url;
if (type === "dimmableState") {
url = "/dimmableState";
} else {
url = "/switchableState";
}
return Endpoint.delete(url+`/${id}`)
.then((_) => dispatch(actions.stateDelete(id)))
.catch((err) => {
console.warn("state delete error", err);
throw new RemoteError(["Network error"]);
});
};
},
/** /**
* Creates/Updates a device with the given data. If * Creates/Updates a device with the given data. If
* data.id is truthy, then a update call is performed, * data.id is truthy, then a update call is performed,

View file

@ -80,8 +80,10 @@ function reducer(previousState, action) {
}; };
const updateSceneStateProps = (state) => { const updateSceneStateProps = (state) => {
change.sceneStates[state.deviceId] = {}; change.sceneStates[state.id] = {};
change.sceneStates[state.deviceId] = { $set: state.deviceId }; for (const key in state) {
change.sceneStates[state.id][key] = { $set: state[key] };
}
}; };
switch (action.type) { switch (action.type) {
@ -104,6 +106,7 @@ function reducer(previousState, action) {
} }
break; break;
case "STATE_UPDATE": case "STATE_UPDATE":
//console.log(action.sceneStates);
newState = previousState; newState = previousState;
change = null; change = null;
@ -129,9 +132,9 @@ function reducer(previousState, action) {
}; };
for (const sceneState of action.sceneStates) { for (const sceneState of action.sceneStates) {
if (!newState.sceneStates[sceneState.deviceId]) { if (!newState.sceneStates[sceneState.id]) {
change.sceneStates[sceneState.deviceId] = { change.sceneStates[sceneState.id] = {
$set: sceneState.deviceId, $set: sceneState,
}; };
} else { } else {
updateSceneStateProps(sceneState); updateSceneStateProps(sceneState);
@ -144,19 +147,17 @@ function reducer(previousState, action) {
change.scenes[sceneState.sceneId].sceneStates || {}; change.scenes[sceneState.sceneId].sceneStates || {};
const sceneStates = change.scenes[sceneState.sceneId].sceneStates; const sceneStates = change.scenes[sceneState.sceneId].sceneStates;
sceneStates.$add = sceneStates.$add || []; sceneStates.$add = sceneStates.$add || [];
sceneStates.$add.push(sceneState.deviceId); sceneStates.$add.push(sceneState);
} else { } else {
// room does not exist yet, so add to the list of pending // room does not exist yet, so add to the list of pending
// joins // joins
if (!change.pendingJoins.scenes[sceneState.sceneId]) { if (!change.pendingJoins.scenes[sceneState.sceneId]) {
change.pendingJoins.scenes[sceneState.sceneId] = { change.pendingJoins.scenes[sceneState.sceneId] = {
$set: new Set([sceneState.deviceId]), $set: new Set([sceneState]),
}; };
} else { } else {
change.pendingJoins.scenes[sceneState.sceneId].$set.add( change.pendingJoins.scenes[sceneState.sceneId].$set.add(sceneState);
sceneState.deviceId
);
} }
} }
} }
@ -295,7 +296,7 @@ function reducer(previousState, action) {
change.scenes = { change.scenes = {
[action.sceneState.sceneId]: { [action.sceneState.sceneId]: {
sceneStates: { sceneStates: {
$add: [action.sceneState.id], $add: [action.sceneState],
}, },
}, },
}; };
@ -303,7 +304,7 @@ function reducer(previousState, action) {
change.pendingJoins = { change.pendingJoins = {
scenes: { scenes: {
[action.sceneState.sceneId]: { [action.sceneState.sceneId]: {
$add: [action.sceneState.id], $add: [action.sceneState],
}, },
}, },
}; };
@ -355,6 +356,26 @@ function reducer(previousState, action) {
change.active = { activeScene: { $set: -1 } }; change.active = { activeScene: { $set: -1 } };
} }
newState = update(previousState, change);
break;
case "STATE_DELETE":
if (!(action.stateId in previousState.sceneStates)) {
console.warn(`State to delete ${action.stateId} does not exist`);
break;
}
change = {
sceneStates: { $unset: [action.stateId] },
};
if (previousState.scenes[previousState.sceneStates[action.stateId].sceneId]) {
change.scenes = {
[previousState.sceneStates[action.stateId].sceneId]: {
sceneStates: { $remove: [action.stateId] },
},
};
}
newState = update(previousState, change); newState = update(previousState, change);
break; break;
case "DEVICE_DELETE": case "DEVICE_DELETE":

View file

@ -40,6 +40,10 @@ const actions = {
devices, devices,
partial, partial,
}), }),
stateDelete: (stateId)=>({
type: "STATE_DELETE",
stateId,
}),
deviceOperationUpdate: (devices) => ({ deviceOperationUpdate: (devices) => ({
type: "DEVICES_UPDATE", type: "DEVICES_UPDATE",
devices, devices,