diff --git a/smart-hut/src/components/dashboard/AutomationsPanel.js b/smart-hut/src/components/dashboard/AutomationsPanel.js
index c730332..dd49666 100644
--- a/smart-hut/src/components/dashboard/AutomationsPanel.js
+++ b/smart-hut/src/components/dashboard/AutomationsPanel.js
@@ -1,597 +1,571 @@
-import React, {Component, useState, useEffect} from "react";
-import {connect} from "react-redux";
-import {RemoteService} from "../../remote";
+import React, { Component, useState, useEffect } from "react";
+import { connect } from "react-redux";
+import { RemoteService } from "../../remote";
import "./Automations.css";
import {
- Segment,
- Grid,
- Icon,
- Header,
- Input,
- Button,
- List,
- Dropdown,
- Form,
- Divider,
- Checkbox,
- Menu,
- Label,
+ Segment,
+ Grid,
+ Icon,
+ Header,
+ Input,
+ Button,
+ List,
+ Dropdown,
+ Form,
+ Divider,
+ Checkbox,
+ Menu,
+ Label,
} from "semantic-ui-react";
const operands = [
- {key: "EQUAL", text: "=", value: "EQUAL"},
- {
- key: "GREATER_EQUAL",
- text: "\u2265",
- value: "GREATER_EQUAL",
- },
- {
- key: "GREATER",
- text: ">",
- value: "GREATER",
- },
- {
- key: "LESS_EQUAL",
- text: "\u2264",
- value: "LESS_EQUAL",
- },
- {
- key: "LESS",
- text: "<",
- value: "LESS",
- },
+ { key: "EQUAL", text: "=", value: "EQUAL" },
+ {
+ key: "GREATER_EQUAL",
+ text: "\u2265",
+ value: "GREATER_EQUAL",
+ },
+ {
+ key: "GREATER",
+ text: ">",
+ value: "GREATER",
+ },
+ {
+ key: "LESS_EQUAL",
+ text: "\u2264",
+ value: "LESS_EQUAL",
+ },
+ {
+ key: "LESS",
+ text: "<",
+ value: "LESS",
+ },
];
const deviceStateOptions = [
- {key: "off", text: "off", value: false},
- {key: "on", text: "on", value: true},
+ { key: "off", text: "off", value: false },
+ { key: "on", text: "on", value: true },
];
const CreateTrigger = (props) => {
- const [activeOperand, setActiveOperand] = useState(true);
- const admitedDevices = ["sensor", "regularLight", "dimmableLight"]; // TODO Complete this list
- const deviceList = props.devices
- .map((device) => {
- return {
- key: device.id,
- text: device.name,
- value: device.id,
- kind: device.kind,
- };
- })
- .filter((e) => admitedDevices.includes(e.kind));
+ const [activeOperand, setActiveOperand] = useState(true);
+ const admitedDevices = ["sensor", "regularLight", "dimmableLight"]; // TODO Complete this list
+ const deviceList = props.devices
+ .map((device) => {
+ return {
+ key: device.id,
+ text: device.name,
+ value: device.id,
+ kind: device.kind,
+ };
+ })
+ .filter((e) => admitedDevices.includes(e.kind));
- const onChange = (e, val) => {
- props.inputChange(val);
- if (
- props.devices
- .filter((d) => d.id === val.value)[0]
- .hasOwnProperty("on")
- ) {
- setActiveOperand(false);
- } else {
- setActiveOperand(true);
- }
- };
+ const onChange = (e, val) => {
+ props.inputChange(val);
+ if (
+ props.devices.filter((d) => d.id === val.value)[0].hasOwnProperty("on")
+ ) {
+ setActiveOperand(false);
+ } else {
+ setActiveOperand(true);
+ }
+ };
- return (
-
-
-
-
-
-
- {activeOperand ? (
-
-
-
- props.inputChange(val)
- }
- name="operand"
- compact
- selection
- options={operands}
- />
-
-
-
- props.inputChange(val)
- }
- name="value"
- type="number"
- placeholder="Value"
- />
-
-
- ) : (
-
-
- props.inputChange(val)
- }
- placeholder="State"
- name="value"
- compact
- selection
- options={deviceStateOptions}
- />
-
- )}
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+ {activeOperand ? (
+
+
+ props.inputChange(val)}
+ name="operand"
+ compact
+ selection
+ options={operands}
+ />
+
+
+ props.inputChange(val)}
+ name="value"
+ type="number"
+ placeholder="Value"
+ />
+
+
+ ) : (
+
+ props.inputChange(val)}
+ placeholder="State"
+ name="value"
+ compact
+ selection
+ options={deviceStateOptions}
+ />
+
+ )}
+
+
+
+
+ );
};
const SceneItem = (props) => {
- let position = props.order.indexOf(props.scene.id);
- return (
-
-
-
-
-
-
- props.orderScenes(
- props.scene.id,
- val.checked
- )
- }
- checked={position + 1 > 0}
- />
-
-
- {props.scene.name}
-
-
-
- {position !== -1 ? "# " + (position + 1) : ""}
-
-
-
-
-
-
- );
+ let position = props.order.indexOf(props.scene.id);
+ return (
+
+
+
+
+
+
+ props.orderScenes(props.scene.id, val.checked)
+ }
+ checked={position + 1 > 0}
+ />
+
+
+ {props.scene.name}
+
+
+ {position !== -1 ? "# " + (position + 1) : ""}
+
+
+
+
+
+ );
};
-const Trigger = ({deviceName, trigger, onRemove, index}) => {
- const {device, operand, value} = trigger;
- let symbol;
- if (operand) {
- symbol = operands.filter((opt) => opt.key === operand)[0].text;
- }
- return (
-
-
- onRemove(index)}
- className="remove-icon"
- name="remove"
- />
-
- );
+const Trigger = ({ deviceName, trigger, onRemove, index }) => {
+ const { device, operand, value } = trigger;
+ let symbol;
+ if (operand) {
+ symbol = operands.filter((opt) => opt.key === operand)[0].text;
+ }
+ return (
+
+
+ onRemove(index)}
+ className="remove-icon"
+ name="remove"
+ />
+
+ );
};
export const CreateAutomation = (props) => {
- const [triggerList, setTrigger] = useState([]);
- const [order, setOrder] = useState([]);
- const [stateScenes, setScenes] = useState(props.scenes);
- const [automationName, setautomationName] = useState("New Automation");
- const [editName, setEditName] = useState(false);
- const [newTrigger, setNewTrigger] = useState({});
+ const [triggerList, setTrigger] = useState([]);
+ const [order, setOrder] = useState([]);
+ const [stateScenes, setScenes] = useState(props.scenes);
+ const [automationName, setautomationName] = useState("New Automation");
+ const [editName, setEditName] = useState(false);
+ const [newTrigger, setNewTrigger] = useState({});
- useEffect(() => {
- setScenes(props.scenes);
- }, [props]);
+ useEffect(() => {
+ setScenes(props.scenes);
+ }, [props]);
- const _checkNewTrigger = (trigger) => {
- const auxDevice = props.devices.filter(
- (d) => d.id === trigger.device
- )[0];
- if (auxDevice && auxDevice.hasOwnProperty("on")) {
- if (!trigger.device || !trigger.value == null) {
- return {
- result: false,
- message: "There are missing fields!",
- };
- }
- } else {
- if (!trigger.device || !trigger.operand || !trigger.value) {
- return {
- result: false,
- message: "There are missing fields",
- };
- }
- }
- const result = !triggerList.some(
- (t) => t.device === trigger.device && t.operand === trigger.operand
- );
+ const _checkNewTrigger = (trigger) => {
+ const auxDevice = props.devices.filter((d) => d.id === trigger.device)[0];
+ if (auxDevice && auxDevice.hasOwnProperty("on")) {
+ if (!trigger.device || !trigger.value == null) {
return {
- result: result,
- message: result
- ? ""
- : "You have already created a trigger for this device with the same conditions",
+ result: false,
+ message: "There are missing fields!",
};
- };
- const addTrigger = () => {
- const {result, message} = _checkNewTrigger(newTrigger);
- const auxTrigger = newTrigger;
- if (result) {
- if (
- props.devices
- .filter((d) => d.id === newTrigger.device)[0]
- .hasOwnProperty("on")
- ) {
- delete auxTrigger.operand;
- }
- setTrigger((prevList) => [...prevList, auxTrigger]);
- } else {
- alert(message);
- }
- };
-
- const removeTrigger = (index) => {
- setTrigger((prevList) => prevList.filter((t, i) => i !== index));
- };
-
- // This gets triggered when the devices dropdown changes the value.
- const onInputChange = (val) => {
- setNewTrigger({...newTrigger, [val.name]: val.value});
- };
- const onChangeName = (e, val) => setautomationName(val.value);
-
- const orderScenes = (id, checked) => {
- if (checked) {
- setOrder((prevList) => [...prevList, id]);
- } else {
- setOrder((prevList) => prevList.filter((e) => e !== id));
- }
- };
- const searchScenes = (e, {value}) => {
- if (value.length > 0) {
- setScenes((prevScenes) => {
- return stateScenes.filter((e) => {
- return e.name.includes(value);
- });
- });
- } else {
- setScenes(props.scenes);
- }
- };
-
- const _generateKey = (trigger) => {
- if (trigger.hasOwnProperty("operand")) {
- return trigger.device + trigger.operand + trigger.value;
- }
- return trigger.device + trigger.value;
- };
-
- const checkBeforeSave = () => {
- if (automationName.length <= 0) {
- alert("Give a name to the automation");
- return false;
- }
- if (triggerList.length <= 0) {
- alert("You have to create a trigger");
- return false;
- }
- if (order.length <= 0) {
- alert("You need at least one active scene");
- return false;
- }
- return true;
- };
-
- const saveAutomation = () => {
- //if(checkBeforeSave()){
- const automation = {
- name: automationName,
+ }
+ } else {
+ if (!trigger.device || !trigger.operand || !trigger.value) {
+ return {
+ result: false,
+ message: "There are missing fields",
};
- props.save({automation, triggerList, order});
- //}
- };
-
- return (
-
-
-
-
+ }
+ }
+ const result = !triggerList.some(
+ (t) => t.device === trigger.device && t.operand === trigger.operand
);
+ return {
+ result: result,
+ message: result
+ ? ""
+ : "You have already created a trigger for this device with the same conditions",
+ };
+ };
+ const addTrigger = () => {
+ const { result, message } = _checkNewTrigger(newTrigger);
+ const auxTrigger = newTrigger;
+ if (result) {
+ if (
+ props.devices
+ .filter((d) => d.id === newTrigger.device)[0]
+ .hasOwnProperty("on")
+ ) {
+ delete auxTrigger.operand;
+ }
+ setTrigger((prevList) => [...prevList, auxTrigger]);
+ } else {
+ alert(message);
+ }
+ };
+
+ const removeTrigger = (index) => {
+ setTrigger((prevList) => prevList.filter((t, i) => i !== index));
+ };
+
+ // This gets triggered when the devices dropdown changes the value.
+ const onInputChange = (val) => {
+ setNewTrigger({ ...newTrigger, [val.name]: val.value });
+ };
+ const onChangeName = (e, val) => setautomationName(val.value);
+
+ const orderScenes = (id, checked) => {
+ if (checked) {
+ setOrder((prevList) => [...prevList, id]);
+ } else {
+ setOrder((prevList) => prevList.filter((e) => e !== id));
+ }
+ };
+ const searchScenes = (e, { value }) => {
+ if (value.length > 0) {
+ setScenes((prevScenes) => {
+ return stateScenes.filter((e) => {
+ return e.name.includes(value);
+ });
+ });
+ } else {
+ setScenes(props.scenes);
+ }
+ };
+
+ const _generateKey = (trigger) => {
+ if (trigger.hasOwnProperty("operand")) {
+ return trigger.device + trigger.operand + trigger.value;
+ }
+ return trigger.device + trigger.value;
+ };
+
+ const checkBeforeSave = () => {
+ if (automationName.length <= 0) {
+ alert("Give a name to the automation");
+ return false;
+ }
+ if (triggerList.length <= 0) {
+ alert("You have to create a trigger");
+ return false;
+ }
+ if (order.length <= 0) {
+ alert("You need at least one active scene");
+ return false;
+ }
+ return true;
+ };
+
+ const saveAutomation = () => {
+ //if(checkBeforeSave()){
+ const automation = {
+ name: automationName,
+ };
+ props.save({ automation, triggerList, order });
+ //}
+ };
+
+ return (
+
+
+
+ setEditName((prev) => !prev)}
+ style={{ display: "inline" }}
+ circular
+ size="small"
+ icon={editName ? "save" : "edit"}
+ />
+
+
+
+
+
+
+
+
+ {triggerList.length > 0 &&
+ triggerList.map((trigger, i) => {
+ const deviceName = props.devices.filter(
+ (d) => d.id === trigger.device
+ )[0].name;
+ const key = _generateKey(trigger);
+ return (
+
+ );
+ })}
+
+
+
+
+
+ {props.scenes.length > 0 ? (
+
+
+
+
+
+ {stateScenes.map((scene) => (
+
+ ))}
+
+
+ ) : (
+
+
+ Create Scene
+
+ )}
+
+
+
+
+
+
+
+ saveAutomation()} color="green">
+ SAVE
+
+
+
+
+
+ );
};
-const Automation = ({automation, devices, scenes, removeAutomation}) => {
- const {triggers} = automation;
- const scenePriorities = automation.scenes;
- const getOperator = (operand) =>
- operands.filter((o) => o.key == operand)[0].text;
+const Automation = ({ automation, devices, scenes, removeAutomation }) => {
+ const { triggers } = automation;
+ const scenePriorities = automation.scenes;
+ const getOperator = (operand) =>
+ operands.filter((o) => o.key == operand)[0].text;
-
- return (
-
-
-
- removeAutomation(automation.id)}
- color="red"
- size="small"
- icon={"trash alternate outline"}
- />
-
-
-
-
-
-
-
- {triggers !== undefined &&
- triggers.map((trigger) => {
- const device = devices.filter(
- (d) => d.id === trigger.deviceId
- )[0];
- return (
-
- );
- })}
-
-
-
-
-
- {scenePriorities !== undefined &&
- scenePriorities.map((sp) => {
- const sceneData = scenes.filter(
- (s) => s.id === sp.sceneId
- )[0];
- return (
-
- );
- })}
-
-
-
-
-
-
- );
+ return (
+
+
+
+ removeAutomation(automation.id)}
+ color="red"
+ size="small"
+ icon={"trash alternate outline"}
+ />
+
+
+
+
+
+
+
+ {triggers !== undefined &&
+ triggers.map((trigger) => {
+ const device = devices.filter(
+ (d) => d.id === trigger.deviceId
+ )[0];
+ return (
+
+ );
+ })}
+
+
+
+
+
+ {scenePriorities !== undefined &&
+ scenePriorities.map((sp) => {
+ const sceneData = scenes.filter(
+ (s) => s.id === sp.sceneId
+ )[0];
+ return (
+
+ );
+ })}
+
+
+
+
+
+
+ );
};
class AutomationsPanel extends Component {
- constructor(props) {
- super(props);
- this.state = {openModal: false}
- this.getDevices();
- this.getScenes();
- this.getAutomations();
- }
+ constructor(props) {
+ super(props);
+ this.state = { openModal: false };
+ this.getDevices();
+ this.getScenes();
+ this.getAutomations();
+ }
- getScenes() {
- this.props.fetchAllScenes().catch(console.error);
- }
+ getScenes() {
+ this.props.fetchAllScenes().catch(console.error);
+ }
- getDevices() {
- this.props
- .fetchDevices()
- .catch((err) => console.error(`error fetching devices:`, err));
- }
+ getDevices() {
+ this.props
+ .fetchDevices()
+ .catch((err) => console.error(`error fetching devices:`, err));
+ }
- getAutomations() {
- this.props
- .fetchAutomations()
- .catch((err) => console.error(`error fetching automations:`, err));
- }
+ getAutomations() {
+ this.props
+ .fetchAutomations()
+ .catch((err) => console.error(`error fetching automations:`, err));
+ }
+ removeAutomation = (id) => {
+ this.props
+ .deleteAutomation(id)
+ .catch((err) => console.error(`error removing automation ${id}:`, err));
+ };
- removeAutomation = (id) => {
- this.props
- .deleteAutomation(id)
- .catch((err) => console.error(`error removing automation ${id}:`, err));
- }
-
- render() {
- return (
-
-
-
- {!this.state.openModal ?
- (
-
-
-
- ) :
- (
- CREATE AUTOMATION
- )}
-
-
-
-
- {this.props.automations.map((automation, i) => {
- return (
-
-
-
- );
- })}
-
-
- );
- }
+ render() {
+ return (
+
+
+
+ {!this.state.openModal ? (
+
+
+
+ ) : (
+ CREATE AUTOMATION
+ )}
+
+
+
+ {this.props.automations.map((automation, i) => {
+ console.log(23, automation, i, this.props.automations);
+ return (
+
+
+
+ );
+ })}
+
+
+ );
+ }
}
const mapStateToProps = (state, _) => ({
- activeRoom: state.active.activeRoom,
- activeTab: state.active.activeTab,
- get scenes() {
- return Object.values(state.scenes);
- },
- get devices() {
- return Object.values(state.devices);
- },
- get automations() {
- return Object.values(state.automations);
- },
+ activeRoom: state.active.activeRoom,
+ activeTab: state.active.activeTab,
+ get scenes() {
+ return Object.values(state.scenes);
+ },
+ get devices() {
+ return Object.values(state.devices);
+ },
+ get automations() {
+ console.log(state.automations);
+ return Object.values(state.automations);
+ },
});
const AutomationsPanelContainer = connect(
- mapStateToProps,
- RemoteService
+ mapStateToProps,
+ RemoteService
)(AutomationsPanel);
export default AutomationsPanelContainer;
diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js
index 7c0507f..0087e46 100644
--- a/smart-hut/src/store.js
+++ b/smart-hut/src/store.js
@@ -256,8 +256,13 @@ function reducer(previousState, action) {
case "AUTOMATION_UPDATE":
newState = previousState;
+ const automations = {};
+ for (const automation of action.automations) {
+ automations[automation.id] = automation;
+ }
+
change = {
- automations : {$set: action.automations}
+ automations: { $set: automations },
};
newState = update(previousState, change);
break;
@@ -297,15 +302,13 @@ function reducer(previousState, action) {
case "AUTOMATION_SAVE":
console.log("ID: ", action.automation.id);
change = {
- automations : {[action.automation.id] : {$set : action.automation}}
+ automations: { [action.automation.id]: { $set: action.automation } },
};
-
newState = update(previousState, change);
break;
-
case "STATE_SAVE":
change = {
sceneStates: { [action.sceneState.id]: { $set: action.sceneState } },
@@ -355,15 +358,14 @@ function reducer(previousState, action) {
break;
case "AUTOMATION_DELETE":
-
change = {
automations: { $unset: [action.id] },
};
- console.log("CHANGE ", change)
+ console.log("CHANGE ", change);
console.log("Action id: ", action.id);
newState = update(previousState, change);
- console.log("NEW STATE ", newState)
+ console.log("NEW STATE ", newState);
break;
case "SCENE_DELETE":
console.log("SCENE", action.sceneId);