From 6de6d35a6bc39cb20b6b7c99887084702d1c6087 Mon Sep 17 00:00:00 2001 From: Fachba Date: Mon, 29 Sep 2025 16:23:20 +0700 Subject: [PATCH] example dashboard svg mqtt --- .env.example | 5 + package.json | 1 + src/App.jsx | 2 + src/components/Global/MqttConnection.jsx | 101 ++-- src/pages/home/SvgTest.jsx | 37 ++ svg/test-new.svg | 566 +++++++++++++++++++++++ 6 files changed, 675 insertions(+), 37 deletions(-) create mode 100644 .env.example create mode 100644 src/pages/home/SvgTest.jsx create mode 100644 svg/test-new.svg diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..62bd0b8 --- /dev/null +++ b/.env.example @@ -0,0 +1,5 @@ +VITE_API_SERVER=http://36.66.16.49:9528/api +VITE_MQTT_SERVER=ws://localhost:1884 +VITE_MQTT_USERNAME= +VITE_MQTT_PASSWORD= +VITE_KEY_SESSION=PetekRombonganPetekMorekMorakMarek \ No newline at end of file diff --git a/package.json b/package.json index 6167a07..21bd8b0 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "react-dom": "^18.2.0", "react-icons": "^4.11.0", "react-router-dom": "^6.22.3", + "react-svg": "^16.3.0", "sweetalert2": "^11.17.2" }, "devDependencies": { diff --git a/src/App.jsx b/src/App.jsx index 659b307..8d2c595 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -11,6 +11,7 @@ import Blank from './pages/blank/Blank'; // Master import IndexDevice from './pages/master/device/IndexDevice'; +import SvgTest from './pages/home/SvgTest'; const App = () => { return ( @@ -20,6 +21,7 @@ const App = () => { } /> } /> } /> + } /> {/* Protected Routes */} }> diff --git a/src/components/Global/MqttConnection.jsx b/src/components/Global/MqttConnection.jsx index 1a9551b..731a3fe 100644 --- a/src/components/Global/MqttConnection.jsx +++ b/src/components/Global/MqttConnection.jsx @@ -1,19 +1,18 @@ // mqttService.js import mqtt from 'mqtt'; -const mqttUrl = 'ws://36.66.16.49:9001'; -const topics = ['SYPIU_GGCP', 'SYPIU_GGCP/list-permit/changed','SYPIU_GGCP/list-user/changed']; - +const mqttUrl = `${import.meta.env.VITE_MQTT_SERVER ?? 'ws://localhost:1884'}`; +const topics = ['PIU_GGCP/Devices/PB']; const options = { - keepalive: 30, - clientId: 'react_mqtt_' + Math.random().toString(16).substr(2, 8), - protocolId: 'MQTT', - protocolVersion: 4, - clean: true, - reconnectPeriod: 1000, - connectTimeout: 30 * 1000, - username: 'ide', // jika ada - password: 'aremania', // jika ada + keepalive: 30, + clientId: 'react_mqtt_' + Math.random().toString(16).substr(2, 8), + protocolId: 'MQTT', + protocolVersion: 4, + clean: true, + reconnectPeriod: 1000, + connectTimeout: 30 * 1000, + username: `${import.meta.env.VITE_MQTT_USERNAME ?? ''}`, // jika ada + password: `${import.meta.env.VITE_MQTT_PASSWORD ?? ''}`, // jika ada }; const client = mqtt.connect(mqttUrl, options); @@ -22,37 +21,37 @@ const client = mqtt.connect(mqttUrl, options); let isConnected = false; client.on('connect', () => { - console.log('MQTT Connected'); - isConnected = true; + console.log('MQTT Connected'); + isConnected = true; - // Subscribe default topic - client.subscribe(topics, (err) => { - if (err) console.error('Subscribe error:', err); - else console.log(`Subscribed to topics: ${topics.join(', ')}`); - }); + // Subscribe default topic + client.subscribe(topics, (err) => { + if (err) console.error('Subscribe error:', err); + else console.log(`Subscribed to topics: ${topics.join(', ')}`); + }); }); client.on('error', (err) => { - console.error('Connection error: ', err); - client.end(); + console.error('Connection error: ', err); + client.end(); }); client.on('close', () => { - console.log('MQTT Disconnected'); - isConnected = false; + console.log('MQTT Disconnected'); + isConnected = false; }); /** * Publish message to MQTT - * @param {string} topic - * @param {string} message + * @param {string} topic + * @param {string} message */ const publishMessage = (topic, message) => { - if (client && isConnected && message.trim() !== '') { - client.publish(topic, message); - } else { - console.warn('MQTT not connected or message empty'); - } + if (client && isConnected && message.trim() !== '') { + client.publish(topic, message); + } else { + console.warn('MQTT not connected or message empty'); + } }; /** @@ -60,13 +59,41 @@ const publishMessage = (topic, message) => { * @param {function} callback - Function(topic, message) */ const listenMessage = (callback) => { - client.on('message', (topic, message) => { - callback(topic, message.toString()); - }); + client.on('message', (topic, message) => { + callback(topic, message.toString()); + }); }; -export { - publishMessage, - listenMessage, - client, +const listenMessageState = (setState) => { + client.on('message', (topic, message) => { + const msgObj = { + date: new Date().toLocaleString(), + topic: topic, + msg: JSON.parse(message), + }; + setState(msgObj); + }); }; + +const setValSvg = (msgValue, topic, svg) => { + if (msgValue.topic == topic) { + const objChanel = msgValue?.msg; + Object.entries(objChanel).forEach(([key, value]) => { + // console.log(key, value); + const el = svg.getElementById(key); + if (el) { + if (value === true) { + el.style.display = ''; // sembunyikan + } else if (value === false) { + el.style.display = 'none'; + } else if (!isNaN(value)) { + el.textContent = Number(value ?? 0.0); + } else { + el.textContent = value; + } + } + }); + } +}; + +export { publishMessage, listenMessage, listenMessageState, setValSvg }; diff --git a/src/pages/home/SvgTest.jsx b/src/pages/home/SvgTest.jsx new file mode 100644 index 0000000..976fc4b --- /dev/null +++ b/src/pages/home/SvgTest.jsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from 'react'; +import { Card, Typography, Flex } from 'antd'; +import { ReactSVG } from 'react-svg'; +import { listenMessageState, setValSvg } from '../../components/Global/MqttConnection'; + +const { Text } = Typography; + +const filePathSvg = '/svg/test-new.svg'; +const topicMqtt = 'PIU_GGCP/Devices/PB'; + +const SvgTest = () => { + const [received, setReceived] = useState([]); + + listenMessageState(setReceived) + + useEffect(() => {}, []); + + return ( + <> + + + + Example SVG Value By Mqtt + + + + { + setValSvg(received, topicMqtt, svg); + }} + /> + + ); +}; + +export default SvgTest; diff --git a/svg/test-new.svg b/svg/test-new.svg new file mode 100644 index 0000000..8628689 --- /dev/null +++ b/svg/test-new.svg @@ -0,0 +1,566 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + STARTER + GENERATOR + + + + + + + + + + + + + + + + + ###.## + 01-PT008-A + + ###.## + 01-ZT002 + + ###.## + 01-TE014-A + + ###.## + 01-TE014-B + + ###.## + 01-TE015-A + + ###.## + 01-TE015-B + 01-PT008-B + + ###.## + 01-PT008-C + + ###.## + + ###.## + 01-KT001 + + ###.## + 01-PDT007 + + ###.## + 01-TE019 + + + + + + \ No newline at end of file