| | |
| | | "name": "power-test", |
| | | "version": "0.0.0", |
| | | "dependencies": { |
| | | "axios": "^1.7.2", |
| | | "element-plus": "^2.8.8", |
| | | "pinia": "^2.2.6", |
| | | "vue": "^3.5.12", |
| | |
| | | "resolved": "https://mirrors.huaweicloud.com/repository/npm/async-validator/-/async-validator-4.2.5.tgz", |
| | | "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" |
| | | }, |
| | | "node_modules/asynckit": { |
| | | "version": "0.4.0", |
| | | "resolved": "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", |
| | | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/axios": { |
| | | "version": "1.7.8", |
| | | "resolved": "https://registry.npmmirror.com/axios/-/axios-1.7.8.tgz", |
| | | "integrity": "sha512-Uu0wb7KNqK2t5K+YQyVCLM76prD5sRFjKHbJYCP1J7JFGEQ6nN7HWn9+04LAeiJ3ji54lgS/gZCH1oxyrf1SPw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "follow-redirects": "^1.15.6", |
| | | "form-data": "^4.0.0", |
| | | "proxy-from-env": "^1.1.0" |
| | | } |
| | | }, |
| | | "node_modules/birpc": { |
| | | "version": "0.2.19", |
| | | "resolved": "https://mirrors.huaweicloud.com/repository/npm/birpc/-/birpc-0.2.19.tgz", |
| | |
| | | "url": "https://paulmillr.com/funding/" |
| | | } |
| | | }, |
| | | "node_modules/combined-stream": { |
| | | "version": "1.0.8", |
| | | "resolved": "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", |
| | | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "delayed-stream": "~1.0.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.8" |
| | | } |
| | | }, |
| | | "node_modules/convert-source-map": { |
| | | "version": "2.0.0", |
| | | "resolved": "https://mirrors.huaweicloud.com/repository/npm/convert-source-map/-/convert-source-map-2.0.0.tgz", |
| | |
| | | }, |
| | | "funding": { |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/delayed-stream": { |
| | | "version": "1.0.0", |
| | | "resolved": "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", |
| | | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=0.4.0" |
| | | } |
| | | }, |
| | | "node_modules/detect-libc": { |
| | |
| | | }, |
| | | "engines": { |
| | | "node": ">=8" |
| | | } |
| | | }, |
| | | "node_modules/follow-redirects": { |
| | | "version": "1.15.9", |
| | | "resolved": "https://registry.npmmirror.com/follow-redirects/-/follow-redirects-1.15.9.tgz", |
| | | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", |
| | | "funding": [ |
| | | { |
| | | "type": "individual", |
| | | "url": "https://github.com/sponsors/RubenVerborgh" |
| | | } |
| | | ], |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">=4.0" |
| | | }, |
| | | "peerDependenciesMeta": { |
| | | "debug": { |
| | | "optional": true |
| | | } |
| | | } |
| | | }, |
| | | "node_modules/form-data": { |
| | | "version": "4.0.1", |
| | | "resolved": "https://registry.npmmirror.com/form-data/-/form-data-4.0.1.tgz", |
| | | "integrity": "sha512-tzN8e4TX8+kkxGPK8D5u0FNmjPUjw3lwC9lSLxxoB/+GtsJG91CO8bSWy73APlgAZzZbXEYZJuxjkHH2w+Ezhw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "asynckit": "^0.4.0", |
| | | "combined-stream": "^1.0.8", |
| | | "mime-types": "^2.1.12" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 6" |
| | | } |
| | | }, |
| | | "node_modules/fs-extra": { |
| | |
| | | "url": "https://github.com/sponsors/jonschlinkert" |
| | | } |
| | | }, |
| | | "node_modules/mime-db": { |
| | | "version": "1.52.0", |
| | | "resolved": "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", |
| | | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", |
| | | "license": "MIT", |
| | | "engines": { |
| | | "node": ">= 0.6" |
| | | } |
| | | }, |
| | | "node_modules/mime-types": { |
| | | "version": "2.1.35", |
| | | "resolved": "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", |
| | | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", |
| | | "license": "MIT", |
| | | "dependencies": { |
| | | "mime-db": "1.52.0" |
| | | }, |
| | | "engines": { |
| | | "node": ">= 0.6" |
| | | } |
| | | }, |
| | | "node_modules/mitt": { |
| | | "version": "3.0.1", |
| | | "resolved": "https://mirrors.huaweicloud.com/repository/npm/mitt/-/mitt-3.0.1.tgz", |
| | |
| | | "url": "https://github.com/sponsors/sindresorhus" |
| | | } |
| | | }, |
| | | "node_modules/proxy-from-env": { |
| | | "version": "1.1.0", |
| | | "resolved": "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", |
| | | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", |
| | | "license": "MIT" |
| | | }, |
| | | "node_modules/readdirp": { |
| | | "version": "4.0.2", |
| | | "resolved": "https://mirrors.huaweicloud.com/repository/npm/readdirp/-/readdirp-4.0.2.tgz", |
| | |
| | | "element-plus": "^2.8.8", |
| | | "pinia": "^2.2.6", |
| | | "vue": "^3.5.12", |
| | | "axios": "^1.7.2", |
| | | "vue-router": "^4.4.5" |
| | | }, |
| | | "devDependencies": { |
New file |
| | |
| | | import axios from "@/assets/js/axios"; |
| | | |
| | | /** |
| | | * 设置电源工作模式:testModeSet(03-逆变并网06-PFC工作) |
| | | */ |
| | | export const controllTestModel = (powerId, testModeSet) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllTestModel", |
| | | params: { |
| | | powerId, |
| | | testModeSet, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 设置LLCBuck电流 |
| | | */ |
| | | export const controllLLCBuckCurr = (powerId, llcBuckcurrSet) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllLLCBuckCurr", |
| | | params: { |
| | | powerId, |
| | | llcBuckcurrSet, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 设置LLCBuck电压 |
| | | */ |
| | | export const controllLLCBuckVol = (powerId, llcBuckvolSet) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllLLCBuckVol", |
| | | params: { |
| | | powerId, |
| | | llcBuckvolSet, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 设置PFC模式VBus电压 |
| | | */ |
| | | export const controllVBusVref = (powerId, vbusIrefSet) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllVBusVref", |
| | | params: { |
| | | powerId, |
| | | vbusIrefSet, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 控制电源开机 |
| | | */ |
| | | export const controllPowerOpen = (powerId) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllPowerOpen", |
| | | params: { |
| | | powerId, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 控制电源关机 |
| | | */ |
| | | export const controllPowerClose = (powerId) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllPowerClose", |
| | | params: { |
| | | powerId, |
| | | }, |
| | | }); |
| | | }; |
| | | |
| | | /** |
| | | * 清除变换器故障 |
| | | */ |
| | | export const controllClearAlm = (powerId) => { |
| | | return axios({ |
| | | method: "GET", |
| | | url: "setParam/controllClearAlm", |
| | | params: { |
| | | powerId, |
| | | }, |
| | | }); |
| | | }; |
New file |
| | |
| | | |
| | | import axios from 'axios'; |
| | | if (process.env.NODE_ENV == 'development') { |
| | | // 跨域请求 |
| | | axios.defaults.baseURL = 'http://localhost:8101/fksf/'; |
| | | axios.defaults.withCredentials = true; // 保持请求头 |
| | | } else { |
| | | axios.defaults.baseURL = location.protocol + '//' + location.host + '/fksf/'; |
| | | } |
| | | |
| | | let skipUrls = []; |
| | | |
| | | // 添加请求拦截器 |
| | | axios.interceptors.request.use(function (config) { |
| | | // 在发送请求之前做些什么 |
| | | return config; |
| | | }, function (error) { |
| | | // 对请求错误做些什么 |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | // 添加响应拦截器 |
| | | axios.interceptors.response.use(function (response) { |
| | | // 对响应数据做点什么 |
| | | return response; |
| | | }, function (error) { |
| | | return Promise.reject(error); |
| | | }); |
| | | |
| | | |
| | | export default axios; |
New file |
| | |
| | | export default { |
| | | // 电压保留3位小数 |
| | | VOL: 3, |
| | | // 电流保留1位小数 |
| | | CURR: 1, |
| | | // 温度保留1位小数 |
| | | TEMP: 1, |
| | | // 频率 |
| | | FREQ: 1, |
| | | }; |
New file |
| | |
| | | /** |
| | | * 获取Websocket的连接 |
| | | * @param action |
| | | * @returns {string} |
| | | */ |
| | | function getWsUrl(action, port) { |
| | | let _port = port ? port : 8101; |
| | | let hostname = window.location.hostname; |
| | | let wsProtocol = "ws://"; |
| | | if (window.location.protocol == "https:") { |
| | | wsProtocol = "wss://"; |
| | | } |
| | | if (process.env.NODE_ENV == "development") { |
| | | hostname = "localhost"; |
| | | } else { |
| | | _port = window.location.port; |
| | | } |
| | | // 处理端口为80 |
| | | _port = _port == 80 ? "" : ":" + _port; |
| | | return wsProtocol + hostname + _port + "/fksf/" + action; |
| | | } |
| | | |
| | | export default getWsUrl; |
New file |
| | |
| | | /** |
| | | * 数值保留指定位数小数 |
| | | */ |
| | | export default function toFixed(value, bit) { |
| | | if (!value) { |
| | | return 0; |
| | | } |
| | | const num = Math.pow(10, bit); |
| | | return Math.round(value * num) / num; |
| | | } |
New file |
| | |
| | | <script setup> |
| | | import { ref } from "vue"; |
| | | const props = defineProps({ |
| | | error: { |
| | | type: Boolean, |
| | | default: false, |
| | | }, |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="light-wrapper"> |
| | | <div class="yc-light" :class="{ 'error-light': error }"></div> |
| | | </div> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .light-wrapper { |
| | | display: flex; |
| | | justify-content: center; |
| | | align-items: center; |
| | | height: 30px; |
| | | } |
| | | </style> |
New file |
| | |
| | | import { ref, reactive } from "vue"; |
| | | import { ElMessageBox, ElMessage, ElLoading } from "element-plus"; |
| | | |
| | | export default () => { |
| | | const $message = ElMessage; |
| | | function $alert(title, fnCancel = () => {}) { |
| | | ElMessageBox.confirm(title, "系统提示", { |
| | | confirmButtonText: "确定", |
| | | type: "warning", |
| | | showCancelButton: false, |
| | | center: true, |
| | | }) |
| | | .then(() => { |
| | | fnCancel(); |
| | | }) |
| | | .catch(() => { |
| | | fnCancel(); |
| | | }); |
| | | } |
| | | |
| | | function $confirm(operate, fnOk, fnCancel = () => {}) { |
| | | ElMessageBox.confirm(`请确认是否${operate}?`, "系统提示", { |
| | | confirmButtonText: "确定", |
| | | cancelButtonText: "取消", |
| | | type: "warning", |
| | | center: true, |
| | | }) |
| | | .then(() => { |
| | | fnOk(); |
| | | }) |
| | | .catch(() => { |
| | | fnCancel(); |
| | | }); |
| | | } |
| | | |
| | | function $loading(customOptions = {}) { |
| | | const defaultOptions = { |
| | | lock: true, |
| | | text: "Loading", |
| | | background: "rgba(0, 0, 0, 0.7)", |
| | | target: document.body, |
| | | // 可以添加更多默认配置 |
| | | }; |
| | | |
| | | // 合并默认配置和自定义配置 |
| | | const options = { ...defaultOptions, ...customOptions }; |
| | | |
| | | // 调用Element UI的加载服务 |
| | | const loadingInstance = ElLoading.service(options); |
| | | return loadingInstance; |
| | | // return () => { |
| | | // console.log('?', 'close', '============='); |
| | | |
| | | // loadingInstance.close(); |
| | | // }; |
| | | } |
| | | |
| | | return { $alert, $confirm, $message, $loading }; |
| | | }; |
New file |
| | |
| | | // useWebSocket.js |
| | | import { |
| | | ref, |
| | | reactive, |
| | | onMounted, |
| | | onUnmounted, |
| | | onActivated, |
| | | onDeactivated, |
| | | } from "vue"; |
| | | import getWsUrl from "@/assets/js/getWsUrl"; |
| | | |
| | | export default function (url) { |
| | | url = getWsUrl(url); |
| | | // 重连时间间隔 默认5秒 |
| | | const reConnectDelay = 5 * 1000; |
| | | |
| | | const socket = ref(null); |
| | | const isConnected = ref(false); |
| | | const message = ref(""); |
| | | let timer = null; |
| | | |
| | | const sendCallback = reactive([]); |
| | | |
| | | const connect = () => { |
| | | if (socket.value) { |
| | | socket.value.close(); |
| | | } |
| | | socket.value = new WebSocket(url); |
| | | |
| | | socket.value.onopen = () => { |
| | | isConnected.value = true; |
| | | console.log("WebSocket Connected, url: ", url); |
| | | sendCallback.forEach((v) => v()); |
| | | sendCallback.length = 0; |
| | | }; |
| | | |
| | | socket.value.onmessage = (event) => { |
| | | // 处理接收到的消息 |
| | | // console.log("Received:", event.data); |
| | | // 可以在这里通过 emit 发送消息到组件 |
| | | message.value = event.data; |
| | | }; |
| | | |
| | | socket.value.onerror = (Event) => { |
| | | console.error("WebSocket Error:", Event, url); |
| | | WSClose(Event); |
| | | }; |
| | | |
| | | socket.value.onclose = WSClose; |
| | | |
| | | }; |
| | | |
| | | // 发送数据 |
| | | const sendData = (data) => { |
| | | if (socket.value && socket.value.readyState === socket.value.OPEN) { |
| | | // console.log('send', data, '============='); |
| | | socket.value.send(data); |
| | | } else { |
| | | sendCallback.push(() => sendData(data)); |
| | | } |
| | | }; |
| | | |
| | | function WSClose(Event) { |
| | | isConnected.value = false; |
| | | if (socket.value) { |
| | | switch (socket.value.readyState) { |
| | | case 0: |
| | | socket.value.onopen = () => { |
| | | socket.value.close(); |
| | | console.log('链接关闭', url, 'close事件对象:', Event); |
| | | socket.value = null; |
| | | // 没有event对象 则为手动关闭 |
| | | if (Event) { |
| | | reConnect(); |
| | | } |
| | | } |
| | | break; |
| | | case 1: |
| | | socket.value.close(); |
| | | console.log('链接关闭', url, 'close事件对象:', Event); |
| | | socket.value = null; |
| | | // 没有event对象 则为手动关闭 |
| | | if (Event) { |
| | | reConnect(); |
| | | } |
| | | break; |
| | | case 2: |
| | | socket.value.onclose = () => { |
| | | console.log('链接关闭', url, 'close事件对象:', Event); |
| | | socket.value = null; |
| | | // 没有event对象 则为手动关闭 |
| | | if (Event) { |
| | | reConnect(); |
| | | } |
| | | } |
| | | break; |
| | | case 3: |
| | | console.log('链接关闭', url, 'close事件对象:', Event); |
| | | socket.value = null; |
| | | // 没有event对象 则为手动关闭 |
| | | if (Event) { |
| | | reConnect(); |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 重连 |
| | | function reConnect() { |
| | | if (timer) { |
| | | return false; |
| | | } |
| | | timer = setTimeout(() => { |
| | | timer = null; |
| | | connect(); |
| | | }, reConnectDelay); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | // console.log('socket mount', Date.now(), '============='); |
| | | console.log("on socket mount", url, "============="); |
| | | |
| | | connect(); |
| | | }); |
| | | |
| | | onActivated(() => { |
| | | if (!socket.value) { |
| | | console.log("on socket active", url, "============="); |
| | | connect(); |
| | | } |
| | | }); |
| | | |
| | | onDeactivated(() => { |
| | | if (socket.value) { |
| | | WSClose(); |
| | | } |
| | | }); |
| | | |
| | | onUnmounted(() => { |
| | | if (socket.value) { |
| | | WSClose(); |
| | | } |
| | | }); |
| | | |
| | | // 返回 socket 对象和状态 |
| | | return { socket, isConnected, message, sendData }; |
| | | } |
| | |
| | | @use './reset'; |
| | | @use './variable'; |
| | | @use './light'; |
| | | @use './theme/index.scss'; |
New file |
| | |
| | | /* light */ |
| | | .yc-light { |
| | | position: relative; |
| | | display: inline-block; |
| | | width: 22px; |
| | | height: 22px; |
| | | } |
| | | |
| | | .yc-light:before { |
| | | content: ""; |
| | | display: inline-block; |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | margin-top: -5px; |
| | | margin-left: -5px; |
| | | width: 10px; |
| | | height: 10px; |
| | | border-radius: 10px; |
| | | background-color: #4afd88; |
| | | box-shadow: 0 0 6px 6px #4afd8880; |
| | | } |
| | | |
| | | .yc-light.error-light:before { |
| | | background-color: #fd5b67; |
| | | animation: errorLight 1000ms infinite; |
| | | box-shadow: 0 0 6px 6px #fd586480; |
| | | } |
| | | .yc-light.gray-light:before { |
| | | background-color: #878787; |
| | | width: 12px; |
| | | height: 12px; |
| | | box-shadow: none; |
| | | } |
| | | |
| | | @keyframes errorLight { |
| | | 0% { |
| | | opacity: 1; |
| | | box-shadow: 0 0 6px 6px #fd586480; |
| | | } |
| | | 50% { |
| | | opacity: 0.3; |
| | | box-shadow: 0 0 0 0 #fd586480; |
| | | } |
| | | 100% { |
| | | opacity: 1; |
| | | box-shadow: 0 0 6px 6px #fd586480; |
| | | } |
| | | } |
| | |
| | | <script> |
| | | <script setup> |
| | | import HdwBox from "@/components/HdwBox.vue"; |
| | | import { ref } from "vue"; |
| | | import ycLight from "@/components/ycLight.vue"; |
| | | import toFixed from "@/assets/js/toFixed.js"; |
| | | import const_digits from "@/assets/js/const_digits"; |
| | | |
| | | export default { |
| | | name: "StateInfo" , |
| | | components: {HdwBox}, |
| | | data() { |
| | | return { |
| | | title: "标题" |
| | | }; |
| | | const emit = defineEmits(["editParams", 'start', 'stop', 'clearAlarm']); |
| | | const { VOL, CURR, TEMP, FREQ } = const_digits; |
| | | |
| | | const props = defineProps({ |
| | | // title: { |
| | | // type: String, |
| | | // default: "标题", |
| | | // }, |
| | | info: { |
| | | type: Object, |
| | | // default: () => { |
| | | // return {}; |
| | | // }, |
| | | required: true, |
| | | }, |
| | | } |
| | | }); |
| | | |
| | | </script> |
| | | |
| | | <template> |
| | | <hdw-box :title="title"> |
| | | <hdw-box :title="info.powerName"> |
| | | <template #tools> |
| | | <el-button size="small" type="primary">启动测试</el-button> |
| | | <el-button size="small" type="primary" @click="emit('clearAlarm')">清除故障</el-button> |
| | | <el-button size="small" type="primary" @click="emit('editParams')">修改参数</el-button> |
| | | <el-button size="small" type="primary" v-if="!info.state?.powerWorkstat" @click="emit('start')">开机</el-button> |
| | | <el-button size="small" type="primary" v-else @click="emit('stop')">关机</el-button> |
| | | </template> |
| | | <el-scrollbar> |
| | | <div class="state-info-title">IIC读取数据</div> |
| | | <!-- <div class="state-info-title">IIC读取数据</div> |
| | | <div class="state-info-list-wrapper"> |
| | | <el-row :gutter="0"> |
| | | <el-col :span="8"> |
| | |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | <div class="state-info-title adc">单片机ADC采样</div> |
| | | </div> --> |
| | | <!-- <div class="state-info-title adc">单片机ADC采样</div> --> |
| | | <div class="state-info-list-wrapper"> |
| | | <el-row :gutter="0"> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">A相电压:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.vgridrmsVola, VOL) }} |
| | | </div> |
| | | <div class="state-info-unit">V</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">B相电压:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.vgridrmsVolb, VOL) }} |
| | | </div> |
| | | <div class="state-info-unit">V</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">C相电压:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.vgridrmsVolc, VOL) }} |
| | | </div> |
| | | <div class="state-info-unit">V</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">A相电流:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.igridrmsCurra, CURR) }} |
| | | </div> |
| | | <div class="state-info-unit">A</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">B相电流:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.igridrmsCurrb, CURR) }} |
| | | </div> |
| | | <div class="state-info-unit">A</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">C相电流:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.igridrmsCurrc, CURR) }} |
| | | </div> |
| | | <div class="state-info-unit">A</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-title line"></div> |
| | | <div class="state-info-list-wrapper"> |
| | | <el-row :gutter="0"> |
| | | <el-col :span="8"> |
| | | <!-- <el-col :span="8"> |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">A相功率:</div> |
| | | <div class="state-info-value-wrapper"> |
| | |
| | | <div class="state-info-unit"></div> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-col> --> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">母线电压:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value">{{ toFixed(info.state?.vbusVol, VOL) }}</div> |
| | | <div class="state-info-unit">V</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">交流频率:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value">{{ toFixed(info.state?.gridFreq, FREQ) }}</div> |
| | | <div class="state-info-unit">HZ</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">PCB温度:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.degreeTemppcb, TEMP) }} |
| | | </div> |
| | | <div class="state-info-unit">℃</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">BUS+正电压:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value">{{ toFixed(info.state?.vmidVol, VOL) }}</div> |
| | | <div class="state-info-unit">V</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">A散热器温度:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.degreeTempa, TEMP) }} |
| | | </div> |
| | | <div class="state-info-unit">℃</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">B散热器温度:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.degreeTempb, TEMP) }} |
| | | </div> |
| | | <div class="state-info-unit">℃</div> |
| | | </div> |
| | | </div> |
| | |
| | | <div class="state-info-item-wrapper"> |
| | | <div class="state-info-label">C散热器温度:</div> |
| | | <div class="state-info-value-wrapper"> |
| | | <div class="state-info-value">0</div> |
| | | <div class="state-info-value"> |
| | | {{ toFixed(info.state?.degreeTempc, TEMP) }} |
| | | </div> |
| | | <div class="state-info-unit">℃</div> |
| | | </div> |
| | | </div> |
| | |
| | | <!-- </el-col>--> |
| | | </el-row> |
| | | </div> |
| | | <div class="state-info-title line"></div> |
| | | <div class="state-info-list-wrapper"> |
| | | <el-row :gutter="0"> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">A相过流</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.acinOverCurra"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">B相过流</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.acinOverCurrb"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">C相过流</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.acinOverCurrc"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">A相过压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridOverVola"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">B相过压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridOverVolb"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">C相过压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridOverVolc"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">A相欠压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridUnderVola"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">B相欠压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridUnderVolb"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">C相欠压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vgridUnderVolc"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">BUS过压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.busOverVol"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">BUS欠压</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.busUnderVol"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="8"> </el-col> |
| | | <el-col :span="12"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">A散热器温度过温</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.mosaOverTemp"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">B散热器温度过温</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.mosbOverTemp"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">C散热器温度过温</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.moscOverTemp"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"></el-col> |
| | | <el-col :span="12"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">风机故障</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.fanAlarm"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | <el-col :span="12"> |
| | | <div class="state-info-item-wrapper alarm"> |
| | | <div class="label">12V辅助电源故障</div> |
| | | <div class="value"> |
| | | <yc-light :error="info.state?.vdc12vFault"></yc-light> |
| | | </div> |
| | | </div> |
| | | </el-col> |
| | | </el-row> |
| | | </div> |
| | | </el-scrollbar> |
| | | </hdw-box> |
| | | </template> |
| | |
| | | display: inline-block; |
| | | } |
| | | } |
| | | &.alarm { |
| | | display: flex; |
| | | flex-direction: row; |
| | | align-items: center; |
| | | padding: 0; |
| | | } |
| | | .label { |
| | | flex: 1; |
| | | text-align: right; |
| | | margin-right: 0.6em; |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | .value { |
| | | margin-right: 0.4em; |
| | | } |
| | | } |
| | | } |
| | | .state-info-title { |
| | |
| | | <script> |
| | | import HdwBox from "@/components/HdwBox.vue"; |
| | | <script setup> |
| | | // import HdwBox from "@/components/HdwBox.vue"; |
| | | import StateInfo from "@/views/home/StateInfo.vue"; |
| | | import ParamsContent from "@/views/home/paramsContent.vue"; |
| | | import { ref, watchEffect, onMounted, computed } from "vue"; |
| | | import useWebSocket from "@/hooks/useWebSocket.js"; |
| | | import useElement from "@/hooks/useElement.js"; |
| | | import { |
| | | controllPowerOpen, |
| | | controllPowerClose, |
| | | controllClearAlm, |
| | | } from "@/api/params"; |
| | | const { sendData, message } = useWebSocket("powerSocket"); |
| | | const { $alert, $loading, $message, $confirm } = useElement(); |
| | | const rtData = ref([]); |
| | | const paramsVisible = ref(false); |
| | | const currentIdx = ref(0); |
| | | |
| | | export default { |
| | | name: "HomeView", |
| | | components: {StateInfo, HdwBox}, |
| | | data() { |
| | | return {} |
| | | }, |
| | | methods: { |
| | | |
| | | }, |
| | | mounted() { |
| | | |
| | | watchEffect(() => { |
| | | let _list = []; |
| | | if (message.value) { |
| | | const { code, data, data2 } = JSON.parse(message.value); |
| | | if (code && data) { |
| | | _list = data2; |
| | | } |
| | | } |
| | | rtData.value = _list; |
| | | }); |
| | | |
| | | const title = computed(() => { |
| | | return `设置 模块${currentIdx.value + 1} 参数`; |
| | | }); |
| | | |
| | | function showParams(idx) { |
| | | currentIdx.value = idx; |
| | | paramsVisible.value = true; |
| | | } |
| | | function start(idx) { |
| | | let loading = $loading(); |
| | | controllPowerOpen(rtData.value[idx].state.powerId) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | loading.close(); |
| | | if (code && data) { |
| | | $message.success("操作成功"); |
| | | } else { |
| | | $message.error("操作失败"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | $message.error("操作失败"); |
| | | loading.close(); |
| | | console.log(err); |
| | | }); |
| | | } |
| | | function stop(idx) { |
| | | let loading = $loading(); |
| | | controllPowerClose(rtData.value[idx].state.powerId) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | loading.close(); |
| | | if (code && data) { |
| | | $message.success("操作成功"); |
| | | } else { |
| | | $message.error("操作失败"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | $message.error("操作失败"); |
| | | loading.close(); |
| | | console.log(err); |
| | | }); |
| | | } |
| | | function clearAlarm(idx) { |
| | | let loading = $loading(); |
| | | controllClearAlm(rtData.value[idx].state.powerId) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | loading.close(); |
| | | if (code && data) { |
| | | $message.success("操作成功"); |
| | | } else { |
| | | $message.error("操作失败"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | $message.error("操作失败"); |
| | | loading.close(); |
| | | console.log(err); |
| | | }); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | sendData(""); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="home-view-wrapper"> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | </div> |
| | | <div class="home-item"> |
| | | <state-info></state-info> |
| | | <div class="home-item" v-for="(item, idx) in 8" :key="'item_' + idx"> |
| | | <state-info |
| | | :info="rtData[idx] || {}" |
| | | @clearAlarm="clearAlarm(idx)" |
| | | @editParams="showParams(idx)" |
| | | @start="start(idx)" |
| | | @stop="stop(idx)" |
| | | ></state-info> |
| | | </div> |
| | | </div> |
| | | <!-- 弹窗 --> |
| | | <el-dialog |
| | | :title="title" |
| | | v-model="paramsVisible" |
| | | :close-on-click-modal="false" |
| | | class="dialog-center" |
| | | width="360px" |
| | | center |
| | | > |
| | | <params-content |
| | | v-model="paramsVisible" |
| | | v-if="paramsVisible" |
| | | :info="rtData[currentIdx]" |
| | | @setOk="sendData('')" |
| | | ></params-content> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
New file |
| | |
| | | <script setup> |
| | | import { ref, computed, nextTick } from "vue"; |
| | | import { |
| | | controllTestModel, |
| | | controllLLCBuckCurr, |
| | | controllLLCBuckVol, |
| | | controllVBusVref, |
| | | controllPowerOpen, |
| | | controllPowerClose, |
| | | } from "@/api/params"; |
| | | import useElement from "@/hooks/useElement.js"; |
| | | const { $alert, $loading, $message, $confirm } = useElement(); |
| | | |
| | | const emit = defineEmits(["setOk"]); |
| | | |
| | | const props = defineProps({ |
| | | info: { |
| | | type: Object, |
| | | // default: () => { |
| | | // return {}; |
| | | // }, |
| | | required: true, |
| | | }, |
| | | }); |
| | | const title = ref("设置测试模式"); |
| | | const paramsVisible = ref(false); |
| | | const inputValue = ref(); |
| | | const currentIdx = ref(0); |
| | | const input = ref(); |
| | | |
| | | const testModelab = computed(() => { |
| | | const obj = { |
| | | 3: "逆变并网", |
| | | 6: "PFC工作", |
| | | }; |
| | | const lab = props.info.state?.testModelab || 0; |
| | | return obj[lab] || `未知 (${lab})`; |
| | | }); |
| | | |
| | | function edit(idx) { |
| | | currentIdx.value = idx; |
| | | switch (idx) { |
| | | case 0: |
| | | title.value = "设置测试模式"; |
| | | inputValue.value = props.info.state.testModelab; |
| | | break; |
| | | case 1: |
| | | title.value = "设置VBus电压"; |
| | | inputValue.value = props.info.state.vbusVerfVolSet; |
| | | break; |
| | | case 2: |
| | | title.value = "设置LLC Buck电压"; |
| | | inputValue.value = props.info.state.llcBuckVolSet; |
| | | break; |
| | | case 3: |
| | | title.value = "设置LLC Buck电流"; |
| | | inputValue.value = props.info.state.llcBuckCurrSet; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | paramsVisible.value = true; |
| | | |
| | | if (idx) { |
| | | setTimeout(() => { |
| | | input.value.select(); |
| | | }, 0); |
| | | } |
| | | } |
| | | function setParams() { |
| | | let setFn; |
| | | if (currentIdx.value !== 0 &&inputValue.value.trim() === '') { |
| | | $message.error("请输入参数"); |
| | | return; |
| | | } |
| | | switch (currentIdx.value) { |
| | | case 0: |
| | | setFn = controllTestModel; |
| | | break; |
| | | case 1: |
| | | setFn = controllVBusVref; |
| | | break; |
| | | case 2: |
| | | setFn = controllLLCBuckVol; |
| | | break; |
| | | case 3: |
| | | setFn = controllLLCBuckCurr; |
| | | break; |
| | | default: |
| | | break; |
| | | } |
| | | |
| | | let loading = $loading(); |
| | | setFn(props.info.powerId, inputValue.value) |
| | | .then((res) => { |
| | | let { code, data } = res.data; |
| | | loading.close(); |
| | | if (code && data) { |
| | | console.log(data); |
| | | $message.success("设置成功"); |
| | | emit("setOk"); |
| | | paramsVisible.value = false; |
| | | } else { |
| | | $message.error("设置失败"); |
| | | } |
| | | }) |
| | | .catch((err) => { |
| | | $message.error("设置失败"); |
| | | loading.close(); |
| | | console.log(err); |
| | | }); |
| | | } |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="params"> |
| | | <div class="item"> |
| | | <div class="label">测试模式</div> |
| | | <div class="value">{{ testModelab }}</div> |
| | | <el-button size="small" type="primary" @click="edit(0)">修改</el-button> |
| | | </div> |
| | | <!-- <div class="item"> |
| | | <div class="label">并网输出电流</div> |
| | | <div class="value">{{ info.state.gridIrefCurrSet }}</div> |
| | | <el-button size="small" type="primary" @click="edit">修改</el-button> |
| | | </div> --> |
| | | <!-- <div class="item"> |
| | | <div class="label">VBus电压</div> |
| | | <div class="value">{{ info.state.vbusVerfVolSet }}</div> |
| | | <el-button size="small" type="primary" @click="edit(1)">修改</el-button> |
| | | </div> --> |
| | | <div class="item"> |
| | | <div class="label">LLC Buck电压</div> |
| | | <div class="value">{{ info.state.llcBuckVolSet }}</div> |
| | | <el-button size="small" type="primary" @click="edit(2)">修改</el-button> |
| | | </div> |
| | | <div class="item"> |
| | | <div class="label">LLC Buck电流</div> |
| | | <div class="value">{{ info.state.llcBuckCurrSet }}</div> |
| | | <el-button size="small" type="primary" @click="edit(3)">修改</el-button> |
| | | </div> |
| | | </div> |
| | | <!-- 弹窗 --> |
| | | <el-dialog |
| | | :title="title" |
| | | v-model="paramsVisible" |
| | | :close-on-click-modal="false" |
| | | class="dialog-center" |
| | | width="280px" |
| | | center |
| | | > |
| | | <el-select |
| | | v-model="inputValue" |
| | | v-if="currentIdx === 0" |
| | | placeholder="Select" |
| | | size="small" |
| | | > |
| | | <el-option :value="3" label="逆变并网"></el-option> |
| | | <el-option :value="6" label="PFC工作"></el-option> |
| | | </el-select> |
| | | <el-input |
| | | v-else |
| | | ref="input" |
| | | v-model="inputValue" |
| | | placeholder="Please input" |
| | | /> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button @click="paramsVisible = false">取消</el-button> |
| | | <el-button type="primary" @click="setParams">确定</el-button> |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | </template> |
| | | |
| | | <style scoped lang="scss"> |
| | | .params { |
| | | display: flex; |
| | | flex-direction: column; |
| | | .item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-bottom: 10px; |
| | | .label { |
| | | flex: 1; |
| | | margin-right: 10px; |
| | | text-align: right; |
| | | &::after { |
| | | content: ":"; |
| | | } |
| | | } |
| | | .value { |
| | | width: 8em; |
| | | margin-right: 10px; |
| | | } |
| | | } |
| | | } |
| | | </style> |