From 40c86518731cb93c429c18a4c405777b6e09ad17 Mon Sep 17 00:00:00 2001 From: twoosky Date: Thu, 18 Feb 2021 18:04:19 +0900 Subject: [PATCH 1/5] update logicCore_url --- ui/src/defineUrl.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/src/defineUrl.tsx b/ui/src/defineUrl.tsx index 155d824..1ec94fb 100644 --- a/ui/src/defineUrl.tsx +++ b/ui/src/defineUrl.tsx @@ -57,9 +57,9 @@ export const TOPIC_URL = 'http://' .concat('/regist/topic'); export const LOGICCORE_URL = 'http://' - .concat(process.env.REACT_APP_LOGICCORE_IP) + .concat(process.env.REACT_APP_DB_IP) .concat(':') - .concat(process.env.REACT_APP_LOGICCORE_PORT) + .concat(process.env.REACT_APP_DB_PORT) .concat('/regist/logic'); export const HEALTHCHECK_URL = 'ws://' From e635b8ee4dcc099bd5b7b2e3ec08e1964d443a9f Mon Sep 17 00:00:00 2001 From: twoosky Date: Fri, 19 Feb 2021 22:44:06 +0900 Subject: [PATCH 2/5] create actuator form --- ui/.env | 11 ++ ui/src/ElemInterface/LcElementsInterface.tsx | 8 +- .../InputCards/InputActionCard.tsx | 106 ++++++++++++++++-- 3 files changed, 115 insertions(+), 10 deletions(-) create mode 100644 ui/.env diff --git a/ui/.env b/ui/.env new file mode 100644 index 0000000..5b0e62c --- /dev/null +++ b/ui/.env @@ -0,0 +1,11 @@ +REACT_APP_DB_IP=0.0.0.0 +REACT_APP_DB_PORT=8080 +REACT_APP_KIBANA_IP=0.0.0.0 +REACT_APP_KIBANA_PORT=8080 +REACT_APP_HEALTHCHECK_IP=0.0.0.0 +REACT_APP_HEALTHCHECK_PORT=8080 +REACT_APP_LOGICCORE_IP=0.0.0.0 +REACT_APP_LOGICCORE_PORT=8080 +REACT_APP_ALARM_IP=0.0.0.0 +REACT_APP_ALARM_PORT=8080 +REACT_APP_KAKAO_MAP_KEY=abcdefg12345678 \ No newline at end of file diff --git a/ui/src/ElemInterface/LcElementsInterface.tsx b/ui/src/ElemInterface/LcElementsInterface.tsx index 8408cdf..23af370 100644 --- a/ui/src/ElemInterface/LcElementsInterface.tsx +++ b/ui/src/ElemInterface/LcElementsInterface.tsx @@ -12,7 +12,7 @@ export interface timeRange { export interface logicElem { elem: string; - arg: lcValueArg | lcTimeArg | lcGroupArg | lcActionArg; + arg: lcValueArg | lcTimeArg | lcGroupArg | lcActionArg | lcActuator; } export interface lcValueArg { @@ -32,6 +32,12 @@ export interface lcActionArg { text: string; } +export interface lcActuator { + elem: string; + value: number; + sleep: number; +} + export interface logicListElem { id: string; // request: undefined, receive: number logic_name: string; diff --git a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx index 3be0e49..210960a 100644 --- a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx +++ b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx @@ -1,3 +1,4 @@ +import { type } from 'jquery'; import React, { Component } from 'react'; import Select from 'react-select'; import { logicElem } from '../../ElemInterface/LcElementsInterface'; @@ -13,6 +14,9 @@ interface InputActionCardState { elem: string; arg: { text: string; + elem: string; + value: number; + sleep: number; }; } interface actionOptionsElem { @@ -30,24 +34,63 @@ class InputActionCard extends Component< > { state: InputActionCardState = { elem: '', - arg: { text: '' }, + arg: { text: '', elem: '', value: 0, sleep: 0 }, }; // Handle action change (select alarm or email) handleActionChange = async (e: any) => { // Change this state and then.. - await this.setState({ - elem: e.value, - }); - // change parent's state + if (e.value === 'motor' || e.value === 'switch') { + await this.setState({ + arg: { + text: this.state.arg.text, + elem: e.value, + value: this.state.arg.value, + sleep: this.state.arg.sleep + } + }); + } + else { + await this.setState({ + elem: e.value, + }); + // change parent's state + } this.props.handleInputActionCardChange(this.state); }; // Handle text change by typing handleTextChange = async (e: React.ChangeEvent) => { - await this.setState({ - arg: { text: e.target.value }, - }); + if (e.target.id === 'alarm_msg' || e.target.id === 'email') { + await this.setState({ + arg: { + text: e.target.value, + elem: this.state.arg.elem, + value: this.state.arg.value, + sleep: this.state.arg.sleep + }, + }); + } + else if (e.target.id === 'actuator_value') { + await this.setState({ + arg: { + text: this.state.arg.text, + elem: this.state.arg.elem, + value: parseInt(e.target.value), + sleep: this.state.arg.sleep + }, + }); + } + else { + await this.setState({ + arg: { + text: this.state.arg.text, + elem: this.state.arg.elem, + value: this.state.arg.value, + sleep: parseInt(e.target.value) + }, + }); + } this.props.handleInputActionCardChange(this.state); }; @@ -55,7 +98,13 @@ class InputActionCard extends Component< let actionOptions: Array = [ { label: 'alarm', value: 'alarm' }, { label: 'email', value: 'email' }, + { label: 'actuator', value: 'actuator'}, ]; + + let actuatorOptios: Array = [ + { label: 'motor', value: 'motor'}, + { label: 'switch', value: 'switch'}, + ] return (
@@ -106,7 +155,7 @@ class InputActionCard extends Component< placeholder="Enter alarm msg which you want to get alert" onChange={this.handleTextChange} /> -
+
) : this.state.elem === 'email' ? ( // If user select email
Email address @@ -123,6 +172,45 @@ class InputActionCard extends Component< We'll send message to this e-mail.
+ ) : this.state.elem === 'actuator' ? ( +
+ + +
+ +
+
+
+ sleep + +
+
+ + ) : (
)} From 6079e2c9a972fe6b7bc965779c0c90553529ddab Mon Sep 17 00:00:00 2001 From: twoosky Date: Mon, 22 Feb 2021 19:46:40 +0900 Subject: [PATCH 3/5] create actuator/battery --- ui/.env | 18 +- ui/src/ElemInterface/ElementsInterface.tsx | 3 +- ui/src/ElemInterface/LcElementsInterface.tsx | 8 +- .../InputCards/InputActionCard.tsx | 169 ++++++++++++------ ui/src/LogicCoreComponents/RegisterLogic.tsx | 5 +- .../ShowCards/ShowActionCard.tsx | 18 ++ .../ShowCards/ShowValueCard.tsx | 2 +- ui/src/LogicCoreComponents/ShowLogic.tsx | 2 +- .../Table/MapNodeTable.tsx | 18 +- .../ManagementComponents/Table/NodeTable.tsx | 18 +- 10 files changed, 186 insertions(+), 75 deletions(-) diff --git a/ui/.env b/ui/.env index 5b0e62c..55dfed2 100644 --- a/ui/.env +++ b/ui/.env @@ -1,11 +1,11 @@ -REACT_APP_DB_IP=0.0.0.0 -REACT_APP_DB_PORT=8080 -REACT_APP_KIBANA_IP=0.0.0.0 -REACT_APP_KIBANA_PORT=8080 -REACT_APP_HEALTHCHECK_IP=0.0.0.0 -REACT_APP_HEALTHCHECK_PORT=8080 -REACT_APP_LOGICCORE_IP=0.0.0.0 -REACT_APP_LOGICCORE_PORT=8080 +REACT_APP_DB_IP=10.5.110.11 +REACT_APP_DB_PORT=8081 +REACT_APP_KIBANA_IP=10.5.110.1 +REACT_APP_KIBANA_PORT=5601 +REACT_APP_HEALTHCHECK_IP=10.5.110.11 +REACT_APP_HEALTHCHECK_PORT=8083 +REACT_APP_LOGICCORE_IP=10.5.110.11 +REACT_APP_LOGICCORE_PORT=8081 REACT_APP_ALARM_IP=0.0.0.0 REACT_APP_ALARM_PORT=8080 -REACT_APP_KAKAO_MAP_KEY=abcdefg12345678 \ No newline at end of file +REACT_APP_KAKAO_MAP_KEY=21ac78abd39b1baa196594d8611e392d \ No newline at end of file diff --git a/ui/src/ElemInterface/ElementsInterface.tsx b/ui/src/ElemInterface/ElementsInterface.tsx index eb19680..86dd218 100644 --- a/ui/src/ElemInterface/ElementsInterface.tsx +++ b/ui/src/ElemInterface/ElementsInterface.tsx @@ -86,8 +86,9 @@ export interface topicOptionsElem { // node health check export interface nodeHealthCheckElem { - n_id: number; + nid: number; state: number; + battery: number; } // alarm diff --git a/ui/src/ElemInterface/LcElementsInterface.tsx b/ui/src/ElemInterface/LcElementsInterface.tsx index 23af370..c03bfe5 100644 --- a/ui/src/ElemInterface/LcElementsInterface.tsx +++ b/ui/src/ElemInterface/LcElementsInterface.tsx @@ -10,6 +10,11 @@ export interface timeRange { end: string; } +export interface control { + value: number; + sleep: number; +} + export interface logicElem { elem: string; arg: lcValueArg | lcTimeArg | lcGroupArg | lcActionArg | lcActuator; @@ -34,8 +39,7 @@ export interface lcActionArg { export interface lcActuator { elem: string; - value: number; - sleep: number; + motion: Array; } export interface logicListElem { diff --git a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx index 210960a..5c53b69 100644 --- a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx +++ b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx @@ -1,7 +1,7 @@ import { type } from 'jquery'; import React, { Component } from 'react'; import Select from 'react-select'; -import { logicElem } from '../../ElemInterface/LcElementsInterface'; +import { control, logicElem } from '../../ElemInterface/LcElementsInterface'; import '../LogicCore.css'; interface InputActionCardProps { @@ -15,8 +15,7 @@ interface InputActionCardState { arg: { text: string; elem: string; - value: number; - sleep: number; + motion: Array; }; } interface actionOptionsElem { @@ -34,7 +33,9 @@ class InputActionCard extends Component< > { state: InputActionCardState = { elem: '', - arg: { text: '', elem: '', value: 0, sleep: 0 }, + arg: { text: '', + elem: '', + motion:[{ value: 0, sleep: 0 }] }, }; // Handle action change (select alarm or email) @@ -45,55 +46,78 @@ class InputActionCard extends Component< arg: { text: this.state.arg.text, elem: e.value, - value: this.state.arg.value, - sleep: this.state.arg.sleep + motion: this.state.arg.motion, } }); + console.log(this.state.arg.elem); } else { await this.setState({ elem: e.value, }); // change parent's state + console.log(this.state.elem); } this.props.handleInputActionCardChange(this.state); }; // Handle text change by typing handleTextChange = async (e: React.ChangeEvent) => { - if (e.target.id === 'alarm_msg' || e.target.id === 'email') { - await this.setState({ - arg: { - text: e.target.value, - elem: this.state.arg.elem, - value: this.state.arg.value, - sleep: this.state.arg.sleep - }, - }); - } - else if (e.target.id === 'actuator_value') { - await this.setState({ - arg: { - text: this.state.arg.text, - elem: this.state.arg.elem, - value: parseInt(e.target.value), - sleep: this.state.arg.sleep - }, - }); - } - else { - await this.setState({ - arg: { - text: this.state.arg.text, - elem: this.state.arg.elem, - value: this.state.arg.value, - sleep: parseInt(e.target.value) - }, - }); - } + await this.setState({ + arg: { + text: e.target.value, + elem: this.state.arg.elem, + motion: this.state.arg.motion, + }, + }); this.props.handleInputActionCardChange(this.state); }; + handleControlChange = (idx: number) => async (e:any) => { + const new_motion_elem = this.state.arg.motion.map( + (motionElem: control, sidx: number) => { + if (idx !== sidx) return motionElem; + if (e.target.id === 'actuator_value') + return { ...motionElem, value: parseInt(e.target.value) }; + return { ...motionElem, sleep: parseInt(e.target.sleep) }; + } + ); + + await this.setState({ + arg: { + text: this.state.arg.text, + elem: this.state.arg.elem, + motion: new_motion_elem + } + }); + + this.props.handleInputActionCardChange(this.state); + }; + + handleAddClick = async () => { + await this.setState({ + arg: { + text: this.state.arg.text, + elem: this.state.arg.elem, + motion: [...this.state.arg.motion, {value: 0, sleep: 0}], + }, + }); + this.props.handleInputActionCardChange(this.state); + }; + + handleRemoveClick = (idx: number) => async () => { + await this.setState({ + arg: { + text: this.state.arg.text, + elem: this.state.arg.elem, + motion: this.state.arg.motion.filter( + (s: any, sidx: number) => idx !== sidx + ), + }, + }); + this.props.handleInputActionCardChange(this.state) + }; + render() { let actionOptions: Array = [ { label: 'alarm', value: 'alarm' }, @@ -143,9 +167,9 @@ class InputActionCard extends Component<
-
+ {/*
*/} {this.state.elem === 'alarm' ? ( // If user select alarm -
+
Alarm MSG
) : this.state.elem === 'email' ? ( // If user select email -
+
Email address
) : this.state.elem === 'actuator' ? ( -
+
- -
-
-
-
-
+ +
sleep + onChange={this.handleControlChange(idx)} + /> + + < button + className="btn btn-sm" + type="button" + id="button-addon2" + onClick={this.handleRemoveClick(idx)} + > + + + +
-
-
+ ))} +
+
) : (
)}
- + // ); } } diff --git a/ui/src/LogicCoreComponents/RegisterLogic.tsx b/ui/src/LogicCoreComponents/RegisterLogic.tsx index 774737b..7935cd2 100644 --- a/ui/src/LogicCoreComponents/RegisterLogic.tsx +++ b/ui/src/LogicCoreComponents/RegisterLogic.tsx @@ -146,6 +146,7 @@ class RegisterLogic extends Component<{}, RegisterLogicState> { handleActionCardChange = (idx: number) => (selectedAction: logicElem) => { // Action card is updated dynamic. It can be added or removed freely. // so find changing field by using received idx and change state. + console.log(selectedAction.elem + "!!!!"); const new_selected_action = this.state.selected_action.map( (action: logicElem, sidx: number) => { if (idx !== sidx) return action; @@ -237,7 +238,9 @@ class RegisterLogic extends Component<{}, RegisterLogicState> { this.state.selected_action ); - // Filter elem: 'empty' field + console.log(this.state.selected_action[0] + "!@!@!@!!@@!@"); + + // Filter elem: 'empty' fie ld elems = elems.filter(function (logic) { return logic.elem !== 'empty'; }); diff --git a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx index 1286e88..8d5ffa4 100644 --- a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx +++ b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx @@ -3,6 +3,8 @@ import '../LogicCore.css'; import { logicElem, lcActionArg, + lcActuator, + control, } from '../../ElemInterface/LcElementsInterface'; interface ShowActionCardProps { @@ -16,6 +18,8 @@ ShowActionCard class ShowActionCard extends Component { render() { var action = this.props.logic_elem.arg as lcActionArg; + var motion_name = (this.props.logic_elem.arg as lcActuator).elem; + var control = (this.props.logic_elem.arg as lcActuator).motion; return (
@@ -41,6 +45,20 @@ class ShowActionCard extends Component { : {action.text}
+ ) : this.props.logic_elem.elem === 'actuator' ? ( +
+ {control.map((control: control, idx: number) => ( +
+ + [actuator #{idx}] + +
+ + motion: {motion_name} / value: {control.value} / sleep: {control.sleep} + +
+ ))} +
) : (
)} diff --git a/ui/src/LogicCoreComponents/ShowCards/ShowValueCard.tsx b/ui/src/LogicCoreComponents/ShowCards/ShowValueCard.tsx index e846373..1fac4e9 100644 --- a/ui/src/LogicCoreComponents/ShowCards/ShowValueCard.tsx +++ b/ui/src/LogicCoreComponents/ShowCards/ShowValueCard.tsx @@ -33,7 +33,7 @@ class ShowValueCard extends Component { {range.map((range: numRange, idx: number) => (
- range #{idx} + [range #{idx}]
diff --git a/ui/src/LogicCoreComponents/ShowLogic.tsx b/ui/src/LogicCoreComponents/ShowLogic.tsx index 6161d4b..ffd3c50 100644 --- a/ui/src/LogicCoreComponents/ShowLogic.tsx +++ b/ui/src/LogicCoreComponents/ShowLogic.tsx @@ -76,7 +76,7 @@ class ShowLogic extends Component { ))} {this.props.logic.elems .filter(function (element) { - return element.elem === 'alarm' || element.elem === 'email'; + return element.elem === 'alarm' || element.elem === 'email' || element.elem === 'actuator'; }) .map((actionCard: logicElem, idx: number) => ( diff --git a/ui/src/ManagementComponents/Table/MapNodeTable.tsx b/ui/src/ManagementComponents/Table/MapNodeTable.tsx index a5e967b..e56e51b 100644 --- a/ui/src/ManagementComponents/Table/MapNodeTable.tsx +++ b/ui/src/ManagementComponents/Table/MapNodeTable.tsx @@ -39,7 +39,7 @@ class MapNodeTable extends Component { // Find node state(health) and represent as colors (red - yellow - green, gray) findNodeState = (id: number) => { for (let prop in this.props.nodeState) { - if (this.props.nodeState[prop].n_id === id) { + if (this.props.nodeState[prop].nid === id) { return ( { return ●; }; + findNodeBattery = (id: number) => { + for (let prop in this.props.nodeState) { + if (this.props.nodeState[prop].nid === id) { + var battery = this.props.nodeState[prop].battery; + if ( battery === 0 ) + return External power + if ( battery === 255 ) + return Not measurable + // return {battery} + } + } + return 200 + }; + render() { return ( <> @@ -65,6 +79,7 @@ class MapNodeTable extends Component { id sensors health + battery @@ -76,6 +91,7 @@ class MapNodeTable extends Component { {node.id} {node.sensors.map((sensor: any) => sensor.name + ', ')} {this.findNodeState(node.id)} + {this.findNodeBattery(node.id)} -
- ))} - - - + ) : (
)} diff --git a/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx b/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx new file mode 100644 index 0000000..0e84750 --- /dev/null +++ b/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx @@ -0,0 +1,193 @@ +import { type } from 'jquery'; +import React, { Component } from 'react'; +import Select from 'react-select'; +import { control, logicElem } from '../../ElemInterface/LcElementsInterface'; +import '../LogicCore.css'; + +interface InputActionCardProps { + handleInputActionCardChange: (value: logicElem) => void; + //handleRemoveInputActionCardClick: () => void; + //index: number; +} + +interface InputActionCardState { + elem: string; + arg: { + aid: number; + motion: Array; + }; +} +interface actionOptionsElem { + label: string; + value: string; +} + +/* +InputActionCard +- Get input of action element +*/ +class InputActionCard extends Component< + InputActionCardProps, + InputActionCardState +> { + state: InputActionCardState = { + elem: 'actuator', + arg: { + aid: 0, + motion:[{ value: 0, sleep: 0 }] + }, + }; + + // Handle action change (select alarm or email) + handleActionChange = async (e: any) => { + // Change this state and then.. + if (e.value === 'motor') { + await this.setState({ + arg: { + aid: 1, + motion: this.state.arg.motion, + } + }); + console.log(this.state.arg.aid); + } + else if (e.value === 'switch') { + await this.setState({ + arg: { + aid: 2, + motion: this.state.arg.motion, + } + }); + } + this.props.handleInputActionCardChange(this.state); + }; + + // Handle text change by typing + handleTextChange = async (e: React.ChangeEvent) => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: this.state.arg.motion, + }, + }); + this.props.handleInputActionCardChange(this.state); + }; + + handleControlChange = (idx: number) => async (e:any) => { + const new_motion_elem = this.state.arg.motion.map( + (motionElem: control, sidx: number) => { + if (idx !== sidx) return motionElem; + if (e.target.id === 'actuator_value') + return { ...motionElem, value: parseInt(e.target.value) }; + return { ...motionElem, sleep: parseInt(e.target.value) }; + + } + ); + + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: new_motion_elem + } + }); + + this.props.handleInputActionCardChange(this.state); + }; + + handleAddClick = async () => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: [...this.state.arg.motion, {value: 0, sleep: 0}], + }, + }); + this.props.handleInputActionCardChange(this.state); + }; + + handleRemoveClick = (idx: number) => async () => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: this.state.arg.motion.filter( + (s: any, sidx: number) => idx !== sidx + ), + }, + }); + this.props.handleInputActionCardChange(this.state) + }; + + render() { + let actuatorOptios: Array = [ + { label: 'motor', value: 'motor'}, + { label: 'switch', value: 'switch'}, + ] + return ( +
+
+ +
+ sleep + +< button + className="btn btn-sm" + type="button" + id="button-addon2" + onClick={this.handleRemoveClick(idx)} + > + + + + +
+ ))} +
+ + ); + } +} + +export default InputActionCard; diff --git a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx index 8d5ffa4..ef771b4 100644 --- a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx +++ b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx @@ -18,8 +18,10 @@ ShowActionCard class ShowActionCard extends Component { render() { var action = this.props.logic_elem.arg as lcActionArg; - var motion_name = (this.props.logic_elem.arg as lcActuator).elem; var control = (this.props.logic_elem.arg as lcActuator).motion; + var motion_name = (this.props.logic_elem.arg as lcActuator).aid; + if (motion_name === 1) var name = 'motor'; + else name = 'switch'; return (
@@ -54,7 +56,7 @@ class ShowActionCard extends Component {
- motion: {motion_name} / value: {control.value} / sleep: {control.sleep} + motion: {name} / value: {control.value} / sleep: {control.sleep}
))} diff --git a/ui/src/ManagementComponents/ActuatorManagement.tsx b/ui/src/ManagementComponents/ActuatorManagement.tsx new file mode 100644 index 0000000..a642a90 --- /dev/null +++ b/ui/src/ManagementComponents/ActuatorManagement.tsx @@ -0,0 +1,34 @@ +import React, { Component } from 'react'; +import RegisterActuator from './Register/RegisterActuator'; +import ActuatorTable from './Table/ActuatorTable'; + +/* +SensorManagement +- Manage sensor table, register sensor +*/ +class ActuatorManagement extends Component { + render() { + return ( + <> +
+ + +
+
+

Actuator

+ +
+ + ); + } +} + +export default ActuatorManagement; diff --git a/ui/src/ManagementComponents/Register/RegisterActuator.tsx b/ui/src/ManagementComponents/Register/RegisterActuator.tsx new file mode 100644 index 0000000..a02759e --- /dev/null +++ b/ui/src/ManagementComponents/Register/RegisterActuator.tsx @@ -0,0 +1,124 @@ +import React, { Component } from 'react'; +import { ACTUATOR_URL } from '../../defineUrl'; + +interface RegisterActuatorState { + name: string; + nameValid: boolean; +} + +class RegisterActuator extends Component<{}, RegisterActuatorState> { + state: RegisterActuatorState = { + name: '', + nameValid: false, + }; + + handleNameChange = (e: React.ChangeEvent) => { + if (e.target.value.length > 0) { + this.setState({ + name: e.target.value, + nameValid: true, + }); + } else { + this.setState({ + name: e.target.value, + nameValid: false, + }); + } + console.log(this.state.name + '@@2!!@!@'); + }; + + handleSubmit = (e: React.MouseEvent) => { + e.preventDefault(); + + var url = ACTUATOR_URL; + var data = this.state; + + if (!this.state.nameValid) { + alert('Please enter actuator name.'); + return; + } + + var submitValid: boolean; + submitValid = window.confirm('Are you sure to register this actuator?'); + if (!submitValid) { + return; + } + alert('data : '+data+', url : ' + url); + fetch(url, { + method: 'POST', // or 'PUT' + body: JSON.stringify(data), + headers: { + 'Content-Type': 'application/json', + }, + }) + .then((res) => res.json()) + .then((response) => console.log('Success:', JSON.stringify(response))) + .catch((error) => console.error('Error:', error)) + .then(() => window.location.reload(false)); + }; + + render() { + return ( + <> + + + ); + } +} + +export default RegisterActuator; \ No newline at end of file diff --git a/ui/src/ManagementComponents/Table/ActuatorTable.tsx b/ui/src/ManagementComponents/Table/ActuatorTable.tsx new file mode 100644 index 0000000..8d7b10d --- /dev/null +++ b/ui/src/ManagementComponents/Table/ActuatorTable.tsx @@ -0,0 +1,119 @@ +import React, { Component } from 'react'; +import { ACTUATOR_URL } from '../../defineUrl'; +import { actuatorListElem } from '../../ElemInterface/ElementsInterface'; +import Pagination from '../Pagination'; + +//import DeleteRequest from './DeleteRequest' + +interface ActuatorTableState { + actuatorList: Array + currentPage: number; + pages: number; +} + +/* +SensorTable +- Show up sensor list. +*/ +class ActuatorTable extends Component<{}, ActuatorTableState> { + state: ActuatorTableState = { + actuatorList: [], + currentPage: 1, + pages: 0, + }; + + componentDidMount() { + this.getsensorList(this.state.currentPage); + } + + // Get sensor list from backend per page + getsensorList(page: number) { + var url = ACTUATOR_URL + '?page=' + page; + + fetch(url) + .then((res) => res.json()) + .then((data) => { + page === 1 + ? this.setState({ actuatorList: data.actuators, pages: data.pages }) + : this.setState({ actuatorList: data.actuators }); + }) + .catch((error) => console.error('Error:', error)); + } + + // Handle click event of the Remove button + handleRemoveClick = (actuator_id: number) => () => { + var url = ACTUATOR_URL + '/' + actuator_id; + + fetch(url, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + }) + .then((res) => res.json()) + .catch((error) => console.error('Error:', error)) + .then(() => window.location.reload(false)); + }; + + handlePageChange = (page: number) => { + this.setState({ currentPage: page }); + this.getsensorList(page); + }; + + render() { + return ( + <> + + + + + + + + + + + {this.state.actuatorList.map( + (actuator: actuatorListElem, idx: number) => ( + + + + + + + ) + )} + +
#nameid
{idx + 10 * (this.state.currentPage - 1)}{actuator.name}{actuator.id} + +
+ + + ); + } +} + +export default ActuatorTable; diff --git a/ui/src/Navigation.tsx b/ui/src/Navigation.tsx index 322131e..5bca21a 100644 --- a/ui/src/Navigation.tsx +++ b/ui/src/Navigation.tsx @@ -60,6 +60,13 @@ class Navigation extends Component { > Sink + + Actuator +
  • diff --git a/ui/src/defineUrl.tsx b/ui/src/defineUrl.tsx index 1ec94fb..0dadae9 100644 --- a/ui/src/defineUrl.tsx +++ b/ui/src/defineUrl.tsx @@ -50,6 +50,10 @@ export const SINK_URL = 'http://' .concat(':') .concat(process.env.REACT_APP_DB_PORT) .concat('/regist/sink'); +export const ACTUATOR_URL = 'http://' + .concat(process.env.REACT_APP_DB_IP) + .concat(':') + .concat('/regist/actuator'); export const TOPIC_URL = 'http://' .concat(process.env.REACT_APP_DB_IP) .concat(':') From 62c15ec2818982ca4a529b2ecbb1f5b7c0d6411b Mon Sep 17 00:00:00 2001 From: twoosky Date: Tue, 23 Feb 2021 23:00:02 +0900 Subject: [PATCH 5/5] create actuator, batteryInfoView --- ui/src/App.tsx | 2 + ui/src/ElemInterface/ElementsInterface.tsx | 5 + ui/src/ElemInterface/LcElementsInterface.tsx | 2 +- .../InputCards/InputActionCard.tsx | 156 ++------------ .../InputCards/InputActuatorCard.tsx | 193 ++++++++++++++++++ .../ShowCards/ShowActionCard.tsx | 6 +- .../ActuatorManagement.tsx | 34 +++ .../Register/RegisterActuator.tsx | 124 +++++++++++ .../Table/ActuatorTable.tsx | 119 +++++++++++ ui/src/Navigation.tsx | 7 + ui/src/defineUrl.tsx | 4 + 11 files changed, 506 insertions(+), 146 deletions(-) create mode 100644 ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx create mode 100644 ui/src/ManagementComponents/ActuatorManagement.tsx create mode 100644 ui/src/ManagementComponents/Register/RegisterActuator.tsx create mode 100644 ui/src/ManagementComponents/Table/ActuatorTable.tsx diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 8420103..df149d8 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -3,6 +3,7 @@ import { BrowserRouter as Router, Route } from 'react-router-dom'; import Nav from './Navigation'; import SensorManagement from './ManagementComponents/SensorManagement'; import NodeManagement from './ManagementComponents/NodeManagement'; +import ActuatorManagement from './ManagementComponents/ActuatorManagement'; import Dashboard from './KibanaDashboard'; import Visualize from './KibanaVisualize'; import Main from './Home'; @@ -28,6 +29,7 @@ class App extends Component {
    + diff --git a/ui/src/ElemInterface/ElementsInterface.tsx b/ui/src/ElemInterface/ElementsInterface.tsx index 86dd218..d5946bc 100644 --- a/ui/src/ElemInterface/ElementsInterface.tsx +++ b/ui/src/ElemInterface/ElementsInterface.tsx @@ -28,6 +28,11 @@ export interface value_list_elem { index: number; } +export interface actuatorListElem { + id: number; + name: string; +} + // sinkList interface export interface sinkListElem { id: number; diff --git a/ui/src/ElemInterface/LcElementsInterface.tsx b/ui/src/ElemInterface/LcElementsInterface.tsx index c03bfe5..75f0e7a 100644 --- a/ui/src/ElemInterface/LcElementsInterface.tsx +++ b/ui/src/ElemInterface/LcElementsInterface.tsx @@ -38,7 +38,7 @@ export interface lcActionArg { } export interface lcActuator { - elem: string; + aid: number; motion: Array; } diff --git a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx index 5c53b69..5e01743 100644 --- a/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx +++ b/ui/src/LogicCoreComponents/InputCards/InputActionCard.tsx @@ -2,6 +2,7 @@ import { type } from 'jquery'; import React, { Component } from 'react'; import Select from 'react-select'; import { control, logicElem } from '../../ElemInterface/LcElementsInterface'; +import InputActuatorCard from './InputActuatorCard'; import '../LogicCore.css'; interface InputActionCardProps { @@ -12,12 +13,11 @@ interface InputActionCardProps { interface InputActionCardState { elem: string; - arg: { + arg: { text: string; - elem: string; - motion: Array; }; } + interface actionOptionsElem { label: string; value: string; @@ -33,31 +33,16 @@ class InputActionCard extends Component< > { state: InputActionCardState = { elem: '', - arg: { text: '', - elem: '', - motion:[{ value: 0, sleep: 0 }] }, - }; + arg: { text: '' }, + } // Handle action change (select alarm or email) handleActionChange = async (e: any) => { - // Change this state and then.. - if (e.value === 'motor' || e.value === 'switch') { - await this.setState({ - arg: { - text: this.state.arg.text, - elem: e.value, - motion: this.state.arg.motion, - } - }); - console.log(this.state.arg.elem); - } - else { - await this.setState({ - elem: e.value, - }); - // change parent's state - console.log(this.state.elem); - } + await this.setState({ + elem: e.value, + }); + console.log(this.state.elem + '!!!!!@@#@####!@#!'); + // change parent's state this.props.handleInputActionCardChange(this.state); }; @@ -66,58 +51,11 @@ class InputActionCard extends Component< await this.setState({ arg: { text: e.target.value, - elem: this.state.arg.elem, - motion: this.state.arg.motion, - }, - }); - this.props.handleInputActionCardChange(this.state); - }; - - handleControlChange = (idx: number) => async (e:any) => { - const new_motion_elem = this.state.arg.motion.map( - (motionElem: control, sidx: number) => { - if (idx !== sidx) return motionElem; - if (e.target.id === 'actuator_value') - return { ...motionElem, value: parseInt(e.target.value) }; - return { ...motionElem, sleep: parseInt(e.target.sleep) }; - } - ); - - await this.setState({ - arg: { - text: this.state.arg.text, - elem: this.state.arg.elem, - motion: new_motion_elem - } - }); - - this.props.handleInputActionCardChange(this.state); - }; - - handleAddClick = async () => { - await this.setState({ - arg: { - text: this.state.arg.text, - elem: this.state.arg.elem, - motion: [...this.state.arg.motion, {value: 0, sleep: 0}], }, }); this.props.handleInputActionCardChange(this.state); }; - handleRemoveClick = (idx: number) => async () => { - await this.setState({ - arg: { - text: this.state.arg.text, - elem: this.state.arg.elem, - motion: this.state.arg.motion.filter( - (s: any, sidx: number) => idx !== sidx - ), - }, - }); - this.props.handleInputActionCardChange(this.state) - }; - render() { let actionOptions: Array = [ { label: 'alarm', value: 'alarm' }, @@ -125,10 +63,6 @@ class InputActionCard extends Component< { label: 'actuator', value: 'actuator'}, ]; - let actuatorOptios: Array = [ - { label: 'motor', value: 'motor'}, - { label: 'switch', value: 'switch'}, - ] return (
    @@ -197,73 +131,9 @@ class InputActionCard extends Component<
    ) : this.state.elem === 'actuator' ? ( -
    - - -
    - sleep - - - < button - className="btn btn-sm" - type="button" - id="button-addon2" - onClick={this.handleRemoveClick(idx)} - > - - - - -
    - ))} - -
    -
    + ) : (
    )} diff --git a/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx b/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx new file mode 100644 index 0000000..0e84750 --- /dev/null +++ b/ui/src/LogicCoreComponents/InputCards/InputActuatorCard.tsx @@ -0,0 +1,193 @@ +import { type } from 'jquery'; +import React, { Component } from 'react'; +import Select from 'react-select'; +import { control, logicElem } from '../../ElemInterface/LcElementsInterface'; +import '../LogicCore.css'; + +interface InputActionCardProps { + handleInputActionCardChange: (value: logicElem) => void; + //handleRemoveInputActionCardClick: () => void; + //index: number; +} + +interface InputActionCardState { + elem: string; + arg: { + aid: number; + motion: Array; + }; +} +interface actionOptionsElem { + label: string; + value: string; +} + +/* +InputActionCard +- Get input of action element +*/ +class InputActionCard extends Component< + InputActionCardProps, + InputActionCardState +> { + state: InputActionCardState = { + elem: 'actuator', + arg: { + aid: 0, + motion:[{ value: 0, sleep: 0 }] + }, + }; + + // Handle action change (select alarm or email) + handleActionChange = async (e: any) => { + // Change this state and then.. + if (e.value === 'motor') { + await this.setState({ + arg: { + aid: 1, + motion: this.state.arg.motion, + } + }); + console.log(this.state.arg.aid); + } + else if (e.value === 'switch') { + await this.setState({ + arg: { + aid: 2, + motion: this.state.arg.motion, + } + }); + } + this.props.handleInputActionCardChange(this.state); + }; + + // Handle text change by typing + handleTextChange = async (e: React.ChangeEvent) => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: this.state.arg.motion, + }, + }); + this.props.handleInputActionCardChange(this.state); + }; + + handleControlChange = (idx: number) => async (e:any) => { + const new_motion_elem = this.state.arg.motion.map( + (motionElem: control, sidx: number) => { + if (idx !== sidx) return motionElem; + if (e.target.id === 'actuator_value') + return { ...motionElem, value: parseInt(e.target.value) }; + return { ...motionElem, sleep: parseInt(e.target.value) }; + + } + ); + + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: new_motion_elem + } + }); + + this.props.handleInputActionCardChange(this.state); + }; + + handleAddClick = async () => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: [...this.state.arg.motion, {value: 0, sleep: 0}], + }, + }); + this.props.handleInputActionCardChange(this.state); + }; + + handleRemoveClick = (idx: number) => async () => { + await this.setState({ + arg: { + aid: this.state.arg.aid, + motion: this.state.arg.motion.filter( + (s: any, sidx: number) => idx !== sidx + ), + }, + }); + this.props.handleInputActionCardChange(this.state) + }; + + render() { + let actuatorOptios: Array = [ + { label: 'motor', value: 'motor'}, + { label: 'switch', value: 'switch'}, + ] + return ( +
    +
    + +
    + sleep + +< button + className="btn btn-sm" + type="button" + id="button-addon2" + onClick={this.handleRemoveClick(idx)} + > + + + + +
    + ))} +
    + + ); + } +} + +export default InputActionCard; diff --git a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx index 8d5ffa4..ef771b4 100644 --- a/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx +++ b/ui/src/LogicCoreComponents/ShowCards/ShowActionCard.tsx @@ -18,8 +18,10 @@ ShowActionCard class ShowActionCard extends Component { render() { var action = this.props.logic_elem.arg as lcActionArg; - var motion_name = (this.props.logic_elem.arg as lcActuator).elem; var control = (this.props.logic_elem.arg as lcActuator).motion; + var motion_name = (this.props.logic_elem.arg as lcActuator).aid; + if (motion_name === 1) var name = 'motor'; + else name = 'switch'; return (
    @@ -54,7 +56,7 @@ class ShowActionCard extends Component {
    - motion: {motion_name} / value: {control.value} / sleep: {control.sleep} + motion: {name} / value: {control.value} / sleep: {control.sleep}
    ))} diff --git a/ui/src/ManagementComponents/ActuatorManagement.tsx b/ui/src/ManagementComponents/ActuatorManagement.tsx new file mode 100644 index 0000000..a642a90 --- /dev/null +++ b/ui/src/ManagementComponents/ActuatorManagement.tsx @@ -0,0 +1,34 @@ +import React, { Component } from 'react'; +import RegisterActuator from './Register/RegisterActuator'; +import ActuatorTable from './Table/ActuatorTable'; + +/* +SensorManagement +- Manage sensor table, register sensor +*/ +class ActuatorManagement extends Component { + render() { + return ( + <> +
    + + +
    +
    +

    Actuator

    + +
    + + ); + } +} + +export default ActuatorManagement; diff --git a/ui/src/ManagementComponents/Register/RegisterActuator.tsx b/ui/src/ManagementComponents/Register/RegisterActuator.tsx new file mode 100644 index 0000000..a02759e --- /dev/null +++ b/ui/src/ManagementComponents/Register/RegisterActuator.tsx @@ -0,0 +1,124 @@ +import React, { Component } from 'react'; +import { ACTUATOR_URL } from '../../defineUrl'; + +interface RegisterActuatorState { + name: string; + nameValid: boolean; +} + +class RegisterActuator extends Component<{}, RegisterActuatorState> { + state: RegisterActuatorState = { + name: '', + nameValid: false, + }; + + handleNameChange = (e: React.ChangeEvent) => { + if (e.target.value.length > 0) { + this.setState({ + name: e.target.value, + nameValid: true, + }); + } else { + this.setState({ + name: e.target.value, + nameValid: false, + }); + } + console.log(this.state.name + '@@2!!@!@'); + }; + + handleSubmit = (e: React.MouseEvent) => { + e.preventDefault(); + + var url = ACTUATOR_URL; + var data = this.state; + + if (!this.state.nameValid) { + alert('Please enter actuator name.'); + return; + } + + var submitValid: boolean; + submitValid = window.confirm('Are you sure to register this actuator?'); + if (!submitValid) { + return; + } + alert('data : '+data+', url : ' + url); + fetch(url, { + method: 'POST', // or 'PUT' + body: JSON.stringify(data), + headers: { + 'Content-Type': 'application/json', + }, + }) + .then((res) => res.json()) + .then((response) => console.log('Success:', JSON.stringify(response))) + .catch((error) => console.error('Error:', error)) + .then(() => window.location.reload(false)); + }; + + render() { + return ( + <> + + + ); + } +} + +export default RegisterActuator; \ No newline at end of file diff --git a/ui/src/ManagementComponents/Table/ActuatorTable.tsx b/ui/src/ManagementComponents/Table/ActuatorTable.tsx new file mode 100644 index 0000000..8d7b10d --- /dev/null +++ b/ui/src/ManagementComponents/Table/ActuatorTable.tsx @@ -0,0 +1,119 @@ +import React, { Component } from 'react'; +import { ACTUATOR_URL } from '../../defineUrl'; +import { actuatorListElem } from '../../ElemInterface/ElementsInterface'; +import Pagination from '../Pagination'; + +//import DeleteRequest from './DeleteRequest' + +interface ActuatorTableState { + actuatorList: Array + currentPage: number; + pages: number; +} + +/* +SensorTable +- Show up sensor list. +*/ +class ActuatorTable extends Component<{}, ActuatorTableState> { + state: ActuatorTableState = { + actuatorList: [], + currentPage: 1, + pages: 0, + }; + + componentDidMount() { + this.getsensorList(this.state.currentPage); + } + + // Get sensor list from backend per page + getsensorList(page: number) { + var url = ACTUATOR_URL + '?page=' + page; + + fetch(url) + .then((res) => res.json()) + .then((data) => { + page === 1 + ? this.setState({ actuatorList: data.actuators, pages: data.pages }) + : this.setState({ actuatorList: data.actuators }); + }) + .catch((error) => console.error('Error:', error)); + } + + // Handle click event of the Remove button + handleRemoveClick = (actuator_id: number) => () => { + var url = ACTUATOR_URL + '/' + actuator_id; + + fetch(url, { + method: 'DELETE', + headers: { + 'Content-Type': 'application/json', + }, + }) + .then((res) => res.json()) + .catch((error) => console.error('Error:', error)) + .then(() => window.location.reload(false)); + }; + + handlePageChange = (page: number) => { + this.setState({ currentPage: page }); + this.getsensorList(page); + }; + + render() { + return ( + <> + + + + + + + + + + + {this.state.actuatorList.map( + (actuator: actuatorListElem, idx: number) => ( + + + + + + + ) + )} + +
    #nameid
    {idx + 10 * (this.state.currentPage - 1)}{actuator.name}{actuator.id} + +
    + + + ); + } +} + +export default ActuatorTable; diff --git a/ui/src/Navigation.tsx b/ui/src/Navigation.tsx index 322131e..5bca21a 100644 --- a/ui/src/Navigation.tsx +++ b/ui/src/Navigation.tsx @@ -60,6 +60,13 @@ class Navigation extends Component { > Sink + + Actuator +
  • diff --git a/ui/src/defineUrl.tsx b/ui/src/defineUrl.tsx index 1ec94fb..0dadae9 100644 --- a/ui/src/defineUrl.tsx +++ b/ui/src/defineUrl.tsx @@ -50,6 +50,10 @@ export const SINK_URL = 'http://' .concat(':') .concat(process.env.REACT_APP_DB_PORT) .concat('/regist/sink'); +export const ACTUATOR_URL = 'http://' + .concat(process.env.REACT_APP_DB_IP) + .concat(':') + .concat('/regist/actuator'); export const TOPIC_URL = 'http://' .concat(process.env.REACT_APP_DB_IP) .concat(':')