diff --git a/smart-hut/src/components/dashboard/AutomationCreationModal.js b/smart-hut/src/components/dashboard/AutomationCreationModal.js index 4280263..f32abde 100644 --- a/smart-hut/src/components/dashboard/AutomationCreationModal.js +++ b/smart-hut/src/components/dashboard/AutomationCreationModal.js @@ -11,6 +11,7 @@ import { Header, Input, Button, + Modal, List, Divider, Menu, @@ -50,8 +51,14 @@ const deviceStateOptions = [ const CreateTrigger = (props) => { const [activeOperand, setActiveOperand] = useState(true); - const admitedDevices = ["sensor", "regularLight", "dimmableLight"]; // TODO: Complete this list - const deviceList = props.devices + const notAdmitedDevices = ["buttonDimmer"]; + const hasOperand = new Set([ + "knobDimmer", + "dimmableLight", + "curtains", + "sensor", + ]); + const deviceList = Object.values(props.devices) .map((device) => { return { key: device.id, @@ -60,17 +67,11 @@ const CreateTrigger = (props) => { kind: device.kind, }; }) - .filter((e) => admitedDevices.includes(e.kind)); + .filter((e) => !notAdmitedDevices.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); - } + setActiveOperand(hasOperand.has(props.devices[val.value].kind)); }; return ( @@ -182,7 +183,6 @@ const Trigger = ({ deviceName, trigger, onRemove, index }) => { class AutomationSaveModal extends Component { constructor(props) { super(props); - this.props = props; this.state = { triggerList: [], order: [], @@ -190,8 +190,29 @@ class AutomationSaveModal extends Component { editName: false, newTrigger: {}, scenesFilter: null, + openModal: false, }; + if (this.props.automation) { + this.state.automationName = this.props.automation.name; + for (const scenePriority of this.props.automation.scenes) { + this.state.order[scenePriority.priority] = scenePriority.sceneId; + } + for (const trigger of this.props.automation.triggers) { + this.state.triggerList.push( + Object.assign( + { + device: trigger.deviceId, + kind: trigger.kind, + }, + trigger.kind === "booleanTrigger" + ? { on: trigger.on } + : { operand: trigger.operator, value: trigger.value } + ) + ); + } + } + this.setTrigger = this._setter("triggerList"); this.setOrder = this._setter("order"); this.setautomationName = this._setter("automationName"); @@ -203,8 +224,17 @@ class AutomationSaveModal extends Component { this.onInputChange = this.onInputChange.bind(this); this.searchScenes = this.searchScenes.bind(this); this.orderScenes = this.orderScenes.bind(this); + this.onChangeName = this.onChangeName.bind(this); } + openModal = (e) => { + this.setState({ openModal: true }); + }; + + closeModal = (e) => { + this.setState({ openModal: false }); + }; + get deviceList() { return Object.values(this.props.devices); } @@ -216,9 +246,9 @@ class AutomationSaveModal extends Component { triggerKind(trigger) { if ("on" in trigger) { - return "BooleanTrigger"; + return "booleanTrigger"; } else if ("operand" in trigger && "value" in trigger) { - return "RangeTrigger"; + return "rangeTrigger"; } else { throw new Error("Trigger kind not handled"); } @@ -234,10 +264,11 @@ class AutomationSaveModal extends Component { }; switch (this.triggerKind(trigger)) { - case "BooleanTrigger": - if (!trigger.device || !trigger.on) return error; + case "booleanTrigger": + if (!trigger.device || trigger.on === null || trigger.on === undefined) + return error; break; - case "RangeTrigger": + case "rangeTrigger": if (!trigger.device || !trigger.operand || !trigger.value) return error; break; } @@ -310,10 +341,10 @@ class AutomationSaveModal extends Component { _generateKey = (trigger) => { switch (this.triggerKind(trigger)) { - case "BooleanTrigger": - return trigger.device + trigger.value; - case "RangeTrigger": - return trigger.device + trigger.operand + trigger.value; + case "booleanTrigger": + return "" + trigger.device + trigger.on; + case "rangeTrigger": + return "" + trigger.device + trigger.operand + trigger.value; } }; @@ -338,132 +369,187 @@ class AutomationSaveModal extends Component { const automation = { name: this.state.automationName, }; - this.props.save({ - automation, - triggerList: this.state.triggerList, - order: this.state.order, - }); + + if (this.props.id) { + automation.id = this.props.id; + automation.triggers = []; + automation.scenes = []; + + for (let i = 0; i < this.state.order.length; i++) { + automation.scenes.push({ + priority: i, + sceneId: this.state.order[i], + }); + } + + for (const trigger of this.state.triggerList) { + const kind = trigger.kind || this.triggerKind(trigger); + automation.triggers.push( + Object.assign( + { + deviceId: trigger.device, + kind, + }, + kind + ? { on: trigger.on } + : { operator: trigger.operand, value: trigger.value } + ) + ); + } + + console.log(automation); + this.props + .fastUpdateAutomation(automation) + .then(this.closeModal) + .catch(console.error); + } else { + this.props + .saveAutomation({ + automation, + triggerList: this.state.triggerList, + order: this.state.order, + }) + .then(this.closeModal) + .catch(console.error); + } } }; + get trigger() { + return this.props.id ? ( + + ); + } + render() { return ( - -
- {this.state.editName ? ( - - ) : ( - this.state.automationName - )} -
+ + +
+ {this.state.editName ? ( + + ) : ( + this.state.automationName + )} +
- -
- )} + + + + )} + + + + + + + + - - - - - - - - + ); } } -const mapStateToProps = (state, _) => ({ - activeRoom: state.active.activeRoom, - activeTab: state.active.activeTab, - get scenes() { - return Object.values(state.scenes); - }, +const mapStateToProps = (state, ownProps) => ({ + scenes: Object.values(state.scenes), devices: state.devices, - get automations() { - return Object.values(state.automations); - }, + automation: ownProps.id ? state.automations[ownProps.id] : null, }); const AutomationSaveModalContainer = connect( mapStateToProps, diff --git a/smart-hut/src/components/dashboard/AutomationsPanel.js b/smart-hut/src/components/dashboard/AutomationsPanel.js index 0119b62..d3eae66 100644 --- a/smart-hut/src/components/dashboard/AutomationsPanel.js +++ b/smart-hut/src/components/dashboard/AutomationsPanel.js @@ -25,12 +25,7 @@ const Automation = ({ automation, devices, scenes, removeAutomation }) => {
{automation.name}
- @@ -138,7 +133,6 @@ class AutomationsPanel extends Component { {this.props.automations.map((automation, i) => { - console.log(23, automation, i, this.props.automations); return ( + {this.props.devices.map((e, i) => { - return ( - - - - ); + return ; })} {!this.props.isActiveRoomHome ? ( - - - + + + + + ) : null} ); diff --git a/smart-hut/src/components/dashboard/devices/NewDevice.js b/smart-hut/src/components/dashboard/devices/NewDevice.js index 2120ba0..84a5b8c 100644 --- a/smart-hut/src/components/dashboard/devices/NewDevice.js +++ b/smart-hut/src/components/dashboard/devices/NewDevice.js @@ -341,7 +341,14 @@ class NewDevice extends Component { open={this.state.openModal} onClose={this.resetState} trigger={ - + } diff --git a/smart-hut/src/remote.js b/smart-hut/src/remote.js index c238c56..df6ed0e 100644 --- a/smart-hut/src/remote.js +++ b/smart-hut/src/remote.js @@ -315,36 +315,7 @@ export const RemoteService = { fetchAutomations: () => { return (dispatch) => { return Endpoint.get("/automation/") - .then((res) => { - const length = res.data.length; - const automations = []; - - res.data.forEach((a, index) => { - const { id, name } = a; - const automation = { - name, - id, - triggers: [], - scenes: [], - }; - - return Endpoint.get(`/booleanTrigger/${id}`).then((res) => { - automation.triggers.push(...res.data); - return Endpoint.get(`/rangeTrigger/${id}`).then((res) => { - automation.triggers.push(...res.data); - return Endpoint.get(`/scenePriority/${id}`).then((res) => { - automation.scenes.push(...res.data); - automations.push(automation); - if (index + 1 === length) { - return void dispatch( - actions.automationsUpdate(automations) - ); - } - }); - }); - }); - }); - }) + .then((res) => void dispatch(actions.automationsUpdate(res.data))) .catch((err) => { console.error(`Fetch automations error`, err); throw new RemoteError(["Network error"]); @@ -502,11 +473,22 @@ export const RemoteService = { }; }, + fastUpdateAutomation: (automation) => { + return (dispatch) => { + return Endpoint.put("/automation/fast", {}, automation) + .then((res) => dispatch(actions.automationSave(res.data))) + .catch((err) => { + console.warn("Update automation: ", automation, "error: ", err); + throw new RemoteError(["Network error"]); + }); + }; + }, + /** * Creates/Updates an automation with the given data. If * data.id is truthy, then a update call is performed, * otherwise a create call is performed. - * @param {Automation} data the device to update. + * @param {Automation} data the automation to update. * @returns {Promise} promise that resolves to the saved device and rejects * with user-fiendly errors as a RemoteError */ diff --git a/smart-hut/src/store.js b/smart-hut/src/store.js index 002c0db..fce1897 100644 --- a/smart-hut/src/store.js +++ b/smart-hut/src/store.js @@ -257,7 +257,6 @@ function reducer(previousState, action) { break; case "AUTOMATION_UPDATE": - newState = previousState; const automations = {}; for (const automation of action.automations) { automations[automation.id] = automation;