From f3e92fa13107b569e0aa4d3ffff013fd2983660b Mon Sep 17 00:00:00 2001 From: "sean.zhou" Date: Tue, 25 Apr 2023 20:28:45 +0800 Subject: [PATCH] initial v1.4.0 --- package-lock.json | 453 ++++++++++- package.json | 5 + src/api/drc.ts | 58 ++ src/api/drone-control/drone.ts | 58 ++ src/api/drone-control/payload.ts | 93 +++ src/api/wayline.ts | 23 +- src/components/GMap.vue | 54 +- .../devices/device-hms/DeviceHmsDrawer.vue | 16 +- .../device-upgrade/DeviceFirmwareUpgrade.vue | 2 +- src/components/g-map/DeviceSettingBox.vue | 4 +- src/components/g-map/DockControlPanel.vue | 10 +- .../g-map/DroneControlInfoPanel.vue | 34 + src/components/g-map/DroneControlPanel.vue | 756 ++++++++++++++++++ src/components/g-map/DroneControlPopover.vue | 115 +++ src/components/g-map/use-connect-mqtt.ts | 71 ++ ...DeviceSetting.ts => use-device-setting.ts} | 0 ...{useDockControl.ts => use-dock-control.ts} | 20 +- .../g-map/use-drone-control-mqtt-event.ts | 61 ++ .../g-map/use-drone-control-ws-event.ts | 97 +++ src/components/g-map/use-drone-control.ts | 40 + src/components/g-map/use-manual-control.ts | 162 ++++ src/components/g-map/use-mqtt.ts | 132 +++ src/components/g-map/use-payload-control.ts | 120 +++ src/components/task/CreatePlan.vue | 3 +- src/components/task/TaskPanel.vue | 59 +- src/event-bus/index.ts | 2 + src/hooks/use-g-map-tsa.ts | 3 +- src/mqtt/config.ts | 12 + src/mqtt/index.ts | 117 +++ src/pages/page-web/projects/Firmwares.vue | 6 +- src/pages/page-web/projects/devices.vue | 17 +- src/pages/page-web/projects/dock.vue | 2 +- src/pages/page-web/projects/livestream.vue | 5 +- src/pages/page-web/projects/tsa.vue | 43 +- src/pages/page-web/projects/workspace.vue | 9 + src/shims-mqtt.d.ts | 4 + src/store/index.ts | 22 +- src/types/device-cmd.ts | 21 +- src/types/device.ts | 103 ++- src/types/drc.ts | 71 ++ src/types/drone-control.ts | 68 ++ src/types/enums.ts | 9 +- src/types/live-stream.ts | 71 ++ src/types/task.ts | 6 +- yarn.lock | 189 ++++- 45 files changed, 3048 insertions(+), 178 deletions(-) create mode 100644 src/api/drc.ts create mode 100644 src/api/drone-control/drone.ts create mode 100644 src/api/drone-control/payload.ts create mode 100644 src/components/g-map/DroneControlInfoPanel.vue create mode 100644 src/components/g-map/DroneControlPanel.vue create mode 100644 src/components/g-map/DroneControlPopover.vue create mode 100644 src/components/g-map/use-connect-mqtt.ts rename src/components/g-map/{useDeviceSetting.ts => use-device-setting.ts} (100%) rename src/components/g-map/{useDockControl.ts => use-dock-control.ts} (75%) create mode 100644 src/components/g-map/use-drone-control-mqtt-event.ts create mode 100644 src/components/g-map/use-drone-control-ws-event.ts create mode 100644 src/components/g-map/use-drone-control.ts create mode 100644 src/components/g-map/use-manual-control.ts create mode 100644 src/components/g-map/use-mqtt.ts create mode 100644 src/components/g-map/use-payload-control.ts create mode 100644 src/mqtt/config.ts create mode 100644 src/mqtt/index.ts create mode 100644 src/shims-mqtt.d.ts create mode 100644 src/types/drc.ts create mode 100644 src/types/drone-control.ts diff --git a/package-lock.json b/package-lock.json index f3082b8..47e9d0c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,7 +15,9 @@ "agora-rtc-sdk-ng": "^4.12.1", "ant-design-vue": "^2.2.8", "axios": "^0.21.1", + "eventemitter3": "^5.0.0", "mitt": "^3.0.0", + "mqtt": "^4.3.7", "query-string": "^7.0.1", "reconnecting-websocket": "^4.4.0", "vconsole": "^3.8.1", @@ -1535,6 +1537,11 @@ "node": ">=0.10.0" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "node_modules/big-integer": { "version": "1.6.51", "resolved": "https://registry.npmmirror.com/big-integer/download/big-integer-1.6.51.tgz", @@ -1576,6 +1583,16 @@ "node": ">=8" } }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "node_modules/bluebird": { "version": "3.7.2", "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz", @@ -1635,6 +1652,20 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "node_modules/buffer-indexof-polyfill": { "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/buffer-indexof-polyfill/download/buffer-indexof-polyfill-1.0.2.tgz", @@ -2000,6 +2031,15 @@ "node": ">= 10" } }, + "node_modules/commist": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "dependencies": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, "node_modules/component-emitter": { "version": "1.3.0", "resolved": "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz", @@ -2019,6 +2059,20 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "license": "MIT" }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, "node_modules/constant-case": { "version": "3.0.4", "resolved": "https://registry.npm.taobao.org/constant-case/download/constant-case-3.0.4.tgz?cache=0&sync_timestamp=1606867325763&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconstant-case%2Fdownload%2Fconstant-case-3.0.4.tgz", @@ -2467,6 +2521,17 @@ "safe-buffer": "~5.1.0" } }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, "node_modules/electron-to-chromium": { "version": "1.4.43", "resolved": "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.4.43.tgz", @@ -2490,6 +2555,14 @@ "node": ">= 4" } }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dependencies": { + "once": "^1.4.0" + } + }, "node_modules/enquirer": { "version": "2.3.6", "resolved": "https://registry.npm.taobao.org/enquirer/download/enquirer-2.3.6.tgz", @@ -3421,6 +3494,11 @@ "node": ">= 0.6" } }, + "node_modules/eventemitter3": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.0.tgz", + "integrity": "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==" + }, "node_modules/expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz", @@ -3745,7 +3823,6 @@ "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true, "license": "ISC" }, "node_modules/fsevents": { @@ -3858,7 +3935,6 @@ "version": "7.2.0", "resolved": "https://registry.npmmirror.com/glob/download/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -4120,6 +4196,15 @@ "dev": true, "license": "0BSD" }, + "node_modules/help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "dependencies": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "node_modules/htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmmirror.com/htmlparser2/download/htmlparser2-3.10.1.tgz?cache=0&sync_timestamp=1636640933377&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-3.10.1.tgz", @@ -4135,6 +4220,11 @@ "readable-stream": "^3.1.1" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "node_modules/ignore": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/ignore/download/ignore-5.2.0.tgz", @@ -4196,7 +4286,6 @@ "version": "1.0.6", "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "license": "ISC", "dependencies": { "once": "^1.3.0", @@ -4207,7 +4296,6 @@ "version": "2.0.4", "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz", "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", - "dev": true, "license": "ISC" }, "node_modules/internal-slot": { @@ -4611,6 +4699,11 @@ "dev": true, "license": "BSD-3-Clause" }, + "node_modules/js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==" + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.nlark.com/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1619345098261&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz", @@ -4692,6 +4785,14 @@ "node": ">=0.10.0" } }, + "node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/levn": { "version": "0.4.1", "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.4.1.tgz", @@ -4801,7 +4902,6 @@ "version": "6.0.0", "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz?cache=0&sync_timestamp=1599054167787&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-6.0.0.tgz", "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=", - "dev": true, "license": "ISC", "dependencies": { "yallist": "^4.0.0" @@ -4979,6 +5079,48 @@ "node": "*" } }, + "node_modules/mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "dependencies": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + }, + "bin": { + "mqtt": "bin/mqtt.js", + "mqtt_pub": "bin/pub.js", + "mqtt_sub": "bin/sub.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "dependencies": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz", @@ -5159,6 +5301,15 @@ "url": "https://github.com/fb55/nth-check?sponsor=1" } }, + "node_modules/number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmmirror.com/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "dependencies": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz", @@ -5374,7 +5525,6 @@ "version": "1.4.0", "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -5525,7 +5675,6 @@ "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -5695,7 +5844,6 @@ "version": "2.0.1", "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz", "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", - "dev": true, "license": "MIT" }, "node_modules/progress": { @@ -5708,6 +5856,15 @@ "node": ">=0.4.0" } }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "node_modules/punycode": { "version": "2.1.1", "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", @@ -5760,7 +5917,6 @@ "version": "3.6.0", "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz", "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=", - "dev": true, "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -5873,6 +6029,11 @@ "url": "https://github.com/sponsors/mysticatea" } }, + "node_modules/reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, "node_modules/repeat-element": { "version": "1.1.4", "resolved": "https://registry.nlark.com/repeat-element/download/repeat-element-1.1.4.tgz", @@ -5963,6 +6124,11 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmmirror.com/rimraf/download/rimraf-3.0.2.tgz", @@ -6541,6 +6707,14 @@ "node": ">=0.10.0" } }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dependencies": { + "readable-stream": "^3.0.0" + } + }, "node_modules/sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz", @@ -6649,6 +6823,11 @@ "node": ">=0.10.0" } }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "node_modules/strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-2.0.0.tgz", @@ -6662,7 +6841,6 @@ "version": "1.3.0", "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz", "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=", - "dev": true, "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -6672,7 +6850,6 @@ "version": "5.2.1", "resolved": "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.2.1.tgz", "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=", - "dev": true, "funding": [ { "type": "github", @@ -7343,6 +7520,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "node_modules/typescript": { "version": "4.5.4", "resolved": "https://registry.npmmirror.com/typescript/download/typescript-4.5.4.tgz", @@ -7577,7 +7759,6 @@ "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true, "license": "MIT" }, "node_modules/v8-compile-cache": { @@ -7970,14 +8151,40 @@ "version": "1.0.2", "resolved": "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz?cache=0&sync_timestamp=1619133505879&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrappy%2Fdownload%2Fwrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true, "license": "ISC" }, + "node_modules/ws": { + "version": "7.5.9", + "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz", "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=", - "dev": true, "license": "ISC" } }, @@ -9002,6 +9209,11 @@ } } }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, "big-integer": { "version": "1.6.51", "resolved": "https://registry.npmmirror.com/big-integer/download/big-integer-1.6.51.tgz", @@ -9030,6 +9242,16 @@ "integrity": "sha1-dfUC7q+f/eQvyYgpZFvk6na9ni0=", "devOptional": true }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz", @@ -9071,6 +9293,20 @@ "picocolors": "^1.0.0" } }, + "buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + }, "buffer-indexof-polyfill": { "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/buffer-indexof-polyfill/download/buffer-indexof-polyfill-1.0.2.tgz", @@ -9354,6 +9590,15 @@ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", "dev": true }, + "commist": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/commist/-/commist-1.1.0.tgz", + "integrity": "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==", + "requires": { + "leven": "^2.1.0", + "minimist": "^1.1.0" + } + }, "component-emitter": { "version": "1.3.0", "resolved": "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz", @@ -9370,6 +9615,17 @@ "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmmirror.com/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, "constant-case": { "version": "3.0.4", "resolved": "https://registry.npm.taobao.org/constant-case/download/constant-case-3.0.4.tgz?cache=0&sync_timestamp=1606867325763&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconstant-case%2Fdownload%2Fconstant-case-3.0.4.tgz", @@ -9700,6 +9956,17 @@ } } }, + "duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmmirror.com/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "requires": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, "electron-to-chromium": { "version": "1.4.43", "resolved": "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.4.43.tgz", @@ -9717,6 +9984,14 @@ "integrity": "sha1-VXBmIEatKeLpFucariYKvf9Pang=", "dev": true }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "requires": { + "once": "^1.4.0" + } + }, "enquirer": { "version": "2.3.6", "resolved": "https://registry.npm.taobao.org/enquirer/download/enquirer-2.3.6.tgz", @@ -10310,6 +10585,11 @@ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", "dev": true }, + "eventemitter3": { + "version": "5.0.0", + "resolved": "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.0.tgz", + "integrity": "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==" + }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz", @@ -10545,8 +10825,7 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npm.taobao.org/fs.realpath/download/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { "version": "2.3.2", @@ -10624,7 +10903,6 @@ "version": "7.2.0", "resolved": "https://registry.npmmirror.com/glob/download/glob-7.2.0.tgz", "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -10806,6 +11084,15 @@ } } }, + "help-me": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/help-me/-/help-me-3.0.0.tgz", + "integrity": "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==", + "requires": { + "glob": "^7.1.6", + "readable-stream": "^3.6.0" + } + }, "htmlparser2": { "version": "3.10.1", "resolved": "https://registry.npmmirror.com/htmlparser2/download/htmlparser2-3.10.1.tgz?cache=0&sync_timestamp=1636640933377&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-3.10.1.tgz", @@ -10820,6 +11107,11 @@ "readable-stream": "^3.1.1" } }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "ignore": { "version": "5.2.0", "resolved": "https://registry.npmmirror.com/ignore/download/ignore-5.2.0.tgz", @@ -10858,7 +11150,6 @@ "version": "1.0.6", "resolved": "https://registry.npm.taobao.org/inflight/download/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -10867,8 +11158,7 @@ "inherits": { "version": "2.0.4", "resolved": "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz", - "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=", - "dev": true + "integrity": "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" }, "internal-slot": { "version": "1.0.3", @@ -11132,6 +11422,11 @@ "integrity": "sha512-pZe//GGmwJndub7ZghVHz7vjb2LgC1m8B07Au3eYqeqv9emhESByMXxaEgkUkEqJe87oBbSniGYoQNIBklc7IQ==", "dev": true }, + "js-sdsl": { + "version": "4.3.0", + "resolved": "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz", + "integrity": "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==" + }, "js-tokens": { "version": "4.0.0", "resolved": "https://registry.nlark.com/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1619345098261&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz", @@ -11188,6 +11483,11 @@ "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", "dev": true }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmmirror.com/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==" + }, "levn": { "version": "0.4.1", "resolved": "https://registry.npm.taobao.org/levn/download/levn-0.4.1.tgz", @@ -11276,7 +11576,6 @@ "version": "6.0.0", "resolved": "https://registry.npm.taobao.org/lru-cache/download/lru-cache-6.0.0.tgz?cache=0&sync_timestamp=1599054167787&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Flru-cache%2Fdownload%2Flru-cache-6.0.0.tgz", "integrity": "sha1-bW/mVw69lqr5D8rR2vo7JWbbOpQ=", - "dev": true, "requires": { "yallist": "^4.0.0" } @@ -11401,6 +11700,40 @@ "resolved": "https://registry.npmmirror.com/moment/download/moment-2.29.1.tgz", "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" }, + "mqtt": { + "version": "4.3.7", + "resolved": "https://registry.npmmirror.com/mqtt/-/mqtt-4.3.7.tgz", + "integrity": "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==", + "requires": { + "commist": "^1.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.1.1", + "duplexify": "^4.1.1", + "help-me": "^3.0.0", + "inherits": "^2.0.3", + "lru-cache": "^6.0.0", + "minimist": "^1.2.5", + "mqtt-packet": "^6.8.0", + "number-allocator": "^1.0.9", + "pump": "^3.0.0", + "readable-stream": "^3.6.0", + "reinterval": "^1.1.0", + "rfdc": "^1.3.0", + "split2": "^3.1.0", + "ws": "^7.5.5", + "xtend": "^4.0.2" + } + }, + "mqtt-packet": { + "version": "6.10.0", + "resolved": "https://registry.npmmirror.com/mqtt-packet/-/mqtt-packet-6.10.0.tgz", + "integrity": "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==", + "requires": { + "bl": "^4.0.2", + "debug": "^4.1.1", + "process-nextick-args": "^2.0.1" + } + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz", @@ -11536,6 +11869,15 @@ "boolbase": "^1.0.0" } }, + "number-allocator": { + "version": "1.0.14", + "resolved": "https://registry.npmmirror.com/number-allocator/-/number-allocator-1.0.14.tgz", + "integrity": "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==", + "requires": { + "debug": "^4.3.1", + "js-sdsl": "4.3.0" + } + }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz", @@ -11688,7 +12030,6 @@ "version": "1.4.0", "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -11809,8 +12150,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npm.taobao.org/path-is-absolute/download/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "3.1.1", @@ -11926,8 +12266,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz", - "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=", - "dev": true + "integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" }, "progress": { "version": "2.0.3", @@ -11935,6 +12274,15 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, "punycode": { "version": "2.1.1", "resolved": "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz", @@ -11961,7 +12309,6 @@ "version": "3.6.0", "resolved": "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz", "integrity": "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=", - "dev": true, "requires": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", @@ -12039,6 +12386,11 @@ "integrity": "sha1-BCWido2PI7rXDKS5BGH6LxIT4bI=", "dev": true }, + "reinterval": { + "version": "1.1.0", + "resolved": "https://registry.npmmirror.com/reinterval/-/reinterval-1.1.0.tgz", + "integrity": "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + }, "repeat-element": { "version": "1.1.4", "resolved": "https://registry.nlark.com/repeat-element/download/repeat-element-1.1.4.tgz", @@ -12095,6 +12447,11 @@ "resolved": "https://registry.npm.taobao.org/reusify/download/reusify-1.0.4.tgz", "integrity": "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=" }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmmirror.com/rimraf/download/rimraf-3.0.2.tgz", @@ -12516,6 +12873,14 @@ } } }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "requires": { + "readable-stream": "^3.0.0" + } + }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz", @@ -12600,6 +12965,11 @@ } } }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + }, "strict-uri-encode": { "version": "2.0.0", "resolved": "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-2.0.0.tgz", @@ -12609,7 +12979,6 @@ "version": "1.3.0", "resolved": "https://registry.npm.taobao.org/string_decoder/download/string_decoder-1.3.0.tgz", "integrity": "sha1-QvEUWUpGzxqOMLCoT1bHjD7awh4=", - "dev": true, "requires": { "safe-buffer": "~5.2.0" }, @@ -12617,8 +12986,7 @@ "safe-buffer": { "version": "5.2.1", "resolved": "https://registry.nlark.com/safe-buffer/download/safe-buffer-5.2.1.tgz", - "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=", - "dev": true + "integrity": "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY=" } } }, @@ -13093,6 +13461,11 @@ "integrity": "sha1-G/IH9LKPkVg2ZstfvTJ4hzAc1fQ=", "dev": true }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + }, "typescript": { "version": "4.5.4", "resolved": "https://registry.npmmirror.com/typescript/download/typescript-4.5.4.tgz", @@ -13282,8 +13655,7 @@ "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npm.taobao.org/util-deprecate/download/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" }, "v8-compile-cache": { "version": "2.3.0", @@ -13544,14 +13916,23 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz?cache=0&sync_timestamp=1619133505879&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrappy%2Fdownload%2Fwrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "ws": { + "version": "7.5.9", + "resolved": "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz", + "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "requires": {} + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" }, "yallist": { "version": "4.0.0", "resolved": "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz", - "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=", - "dev": true + "integrity": "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=" } } } diff --git a/package.json b/package.json index 2b5640f..34c4aa0 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,9 @@ "agora-rtc-sdk-ng": "^4.12.1", "ant-design-vue": "^2.2.8", "axios": "^0.21.1", + "eventemitter3": "^5.0.0", "mitt": "^3.0.0", + "mqtt": "^4.3.7", "query-string": "^7.0.1", "reconnecting-websocket": "^4.4.0", "vconsole": "^3.8.1", @@ -97,9 +99,12 @@ "ant-design-vue/es/tree/style/css", "ant-design-vue/es/upload/style/css", "axios", + "eventemitter3", "lodash", "mitt", "moment", + "mqtt", + "mqtt/dist/mqtt.min", "reconnecting-websocket", "vconsole", "vue", diff --git a/src/api/drc.ts b/src/api/drc.ts new file mode 100644 index 0000000..ea415a9 --- /dev/null +++ b/src/api/drc.ts @@ -0,0 +1,58 @@ +import request, { IWorkspaceResponse } from '/@/api/http/request' +import { ELocalStorageKey } from '/@/types' + +// DRC 链路 +const DRC_API_PREFIX = '/control/api/v1' +const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || '' + +export interface PostDrcBody { + client_id?: string // token过期时,用于续期则必填 + expire_sec?: number // 过期时间,单位秒,默认3600 +} + +export interface DrcParams { + address: string + username: string + password: string + client_id: string + expire_time: number // 过期时间 + enable_tls: boolean // 是否开启tls +} + +// 获取 mqtt 连接认证 +export async function postDrc (body: PostDrcBody): Promise> { + const resp = await request.post(`${DRC_API_PREFIX}/workspaces/${workspaceId}/drc/connect`, body) + return resp.data +} + +export interface DrcEnterBody { + client_id: string + dock_sn: string + expire_sec?: number // 过期时间,单位秒,默认3600 + device_info?: { + osd_frequency?: number + hsi_frequency?: number + } +} + +export interface DrcEnterResp { + sub: string[] // 需要订阅接收的topic + pub: string[] // 推送的topic地址 +} + +// 进入飞行控制 (建立drc连接&获取云控控制权) +export async function postDrcEnter (body: DrcEnterBody): Promise> { + const resp = await request.post(`${DRC_API_PREFIX}/workspaces/${workspaceId}/drc/enter`, body) + return resp.data +} + +export interface DrcExitBody { + client_id: string + dock_sn: string +} + +// 退出飞行控制 (退出drc连接&退出云控控制权) +export async function postDrcExit (body: DrcExitBody): Promise> { + const resp = await request.post(`${DRC_API_PREFIX}/workspaces/${workspaceId}/drc/exit`, body) + return resp.data +} diff --git a/src/api/drone-control/drone.ts b/src/api/drone-control/drone.ts new file mode 100644 index 0000000..7539a4d --- /dev/null +++ b/src/api/drone-control/drone.ts @@ -0,0 +1,58 @@ +import request, { IWorkspaceResponse } from '/@/api/http/request' +// import { ELocalStorageKey } from '/@/types' + +const API_PREFIX = '/control/api/v1' +// const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || ' + +// 获取飞行控制权 +export async function postFlightAuth (sn: string): Promise> { + const resp = await request.post(`${API_PREFIX}/devices/${sn}/authority/flight`) + return resp.data +} +export enum WaylineLostControlActionInCommandFlight { + CONTINUE = 0, + EXEC_LOST_ACTION = 1 +} +export enum LostControlActionInCommandFLight { + HOVER = 0, // 悬停 + Land = 1, // 着陆 + RETURN_HOME = 2, // 返航 +} +export interface PointBody { + latitude: number; + longitude: number; + height: number; +} +export interface PostFlyToPointBody { + max_speed: number, + points: PointBody[] +} + +// 飞向目标点 +export async function postFlyToPoint (sn: string, body: PostFlyToPointBody): Promise> { + const resp = await request.post(`${API_PREFIX}/devices/${sn}/jobs/fly-to-point`, body) + return resp.data +} + +// 停止飞向目标点 +export async function deleteFlyToPoint (sn: string): Promise> { + const resp = await request.delete(`${API_PREFIX}/devices/${sn}/jobs/fly-to-point`) + return resp.data +} + +export interface PostTakeoffToPointBody{ + target_height: number; + target_latitude: number; + target_longitude: number; + security_takeoff_height: number; // 安全起飞高 + max_speed: number; // flyto过程中能达到的最大速度, 单位m/s 跟飞机档位有关 + rc_lost_action: LostControlActionInCommandFLight; // 失控行为 + rth_altitude: number; // 返航高度 + exit_wayline_when_rc_lost: WaylineLostControlActionInCommandFlight +} + +// 一键起飞 +export async function postTakeoffToPoint (sn: string, body: PostTakeoffToPointBody): Promise> { + const resp = await request.post(`${API_PREFIX}/devices/${sn}/jobs/takeoff-to-point`, body) + return resp.data +} diff --git a/src/api/drone-control/payload.ts b/src/api/drone-control/payload.ts new file mode 100644 index 0000000..03b89c5 --- /dev/null +++ b/src/api/drone-control/payload.ts @@ -0,0 +1,93 @@ +import request, { IWorkspaceResponse } from '/@/api/http/request' +import { CameraType, CameraMode } from '/@/types/live-stream' +import { GimbalResetMode } from '/@/types/drone-control' +// import { ELocalStorageKey } from '/@/types' + +const API_PREFIX = '/control/api/v1' +// const workspaceId: string = localStorage.getItem(ELocalStorageKey.WorkspaceId) || ' + +export interface PostPayloadAuthBody { + payload_index: string +} + +// 获取负载控制权 +export async function postPayloadAuth (sn: string, body: PostPayloadAuthBody): Promise> { + const resp = await request.post(`${API_PREFIX}/devices/${sn}/authority/payload`, body) + return resp.data +} + +// TODO: 画面拖动控制 +export enum PayloadCommandsEnum { + CameraModeSwitch = 'camera_mode_switch', + CameraPhotoTake = 'camera_photo_take', + CameraRecordingStart = 'camera_recording_start', + CameraRecordingStop = 'camera_recording_stop', + CameraFocalLengthSet = 'camera_focal_length_set', + GimbalReset = 'gimbal_reset', + CameraAim = 'camera_aim' +} + +export interface PostCameraModeBody { + payload_index: string + camera_mode: CameraMode +} + +export interface PostCameraPhotoBody { + payload_index: string +} + +export interface PostCameraRecordingBody { + payload_index: string +} + +export interface DeleteCameraRecordingParams { + payload_index: string +} + +export interface PostCameraFocalLengthBody { + payload_index: string, + camera_type: CameraType, + zoom_factor: number +} + +export interface PostGimbalResetBody{ + payload_index: string, + reset_mode: GimbalResetMode, +} + +export interface PostCameraAimBody{ + payload_index: string, + camera_type: CameraType, + locked: boolean, + x: number, + y: number, +} + +export type PostPayloadCommandsBody = { + cmd: PayloadCommandsEnum.CameraModeSwitch, + data: PostCameraModeBody +} | { + cmd: PayloadCommandsEnum.CameraPhotoTake, + data: PostCameraPhotoBody +} | { + cmd: PayloadCommandsEnum.CameraRecordingStart, + data: PostCameraRecordingBody +} | { + cmd: PayloadCommandsEnum.CameraRecordingStop, + data: DeleteCameraRecordingParams +} | { + cmd: PayloadCommandsEnum.CameraFocalLengthSet, + data: PostCameraFocalLengthBody +} | { + cmd: PayloadCommandsEnum.GimbalReset, + data: PostGimbalResetBody +} | { + cmd: PayloadCommandsEnum.CameraAim, + data: PostCameraAimBody +} + +// 发送负载名称 +export async function postPayloadCommands (sn: string, body: PostPayloadCommandsBody): Promise> { + const resp = await request.post(`${API_PREFIX}/devices/${sn}/payload/commands`, body) + return resp.data +} diff --git a/src/api/wayline.ts b/src/api/wayline.ts index b7d4987..a917804 100644 --- a/src/api/wayline.ts +++ b/src/api/wayline.ts @@ -42,7 +42,8 @@ export interface CreatePlan { dock_sn: string, task_type: TaskType, // 任务类型 wayline_type: WaylineType, // 航线类型 - execute_time?: number // 执行时间(毫秒) + task_days?: number[] // 执行任务的日期(秒) + task_periods?: number[][] // 执行任务的时间点(秒) rth_altitude: number // 相对机场返航高度 20 - 500 out_of_control_action: OutOfControlAction // 失控动作 } @@ -90,7 +91,7 @@ export interface DeleteTaskParams { job_id: string } -// 取消机场任务 +// 删除机场任务 export async function deleteTask (workspaceId: string, params: DeleteTaskParams): Promise> { const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs` const result = await request.delete(url, { @@ -99,6 +100,24 @@ export async function deleteTask (workspaceId: string, params: DeleteTaskParams) return result.data } +export enum UpdateTaskStatus { + Suspend = 0, // 暂停 + Resume = 1, // 恢复 +} +export interface UpdateTaskStatusBody { + job_id: string + status: UpdateTaskStatus +} + +// 更新机场任务状态 +export async function updateTaskStatus (workspaceId: string, body: UpdateTaskStatusBody): Promise> { + const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs/${body.job_id}` + const result = await request.put(url, { + status: body.status + }) + return result.data +} + // Upload Wayline file export const importKmzFile = async function (workspaceId: string, file: {}): Promise> { const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/waylines/file/upload` diff --git a/src/components/GMap.vue b/src/components/GMap.vue index cb8653e..1a99fcc 100644 --- a/src/components/GMap.vue +++ b/src/components/GMap.vue @@ -1,8 +1,10 @@ @@ -444,7 +449,9 @@ import { } from '@ant-design/icons-vue' import { EDeviceTypeName } from '../types' import DockControlPanel from './g-map/DockControlPanel.vue' -import { useDockControl } from './g-map/useDockControl' +import { useDockControl } from './g-map/use-dock-control' +import DroneControlPanel from './g-map/DroneControlPanel.vue' +import { useConnectMqtt } from './g-map/use-connect-mqtt' export default defineComponent({ components: { @@ -466,6 +473,7 @@ export default defineComponent({ ArrowUpOutlined, ArrowDownOutlined, DockControlPanel, + DroneControlPanel, CarryOutOutlined, RocketOutlined }, @@ -567,7 +575,7 @@ export default defineComponent({ deviceTsaUpdateHook.initMarker(EDeviceTypeName.Dock, [EDeviceTypeName.Dock], data.currentSn, data.dockInfo[data.currentSn].basic_osd?.longitude, data.dockInfo[data.currentSn].basic_osd?.latitude) if (osdVisible.value.visible && osdVisible.value.is_dock && osdVisible.value.gateway_sn !== '') { deviceInfo.dock = data.dockInfo[osdVisible.value.gateway_sn] - deviceInfo.device = data.deviceInfo[deviceInfo.dock.basic_osd?.sub_device?.device_sn ?? osdVisible.value.sn] + deviceInfo.device = data.deviceInfo[deviceInfo.dock.basic_osd.sub_device?.device_sn ?? osdVisible.value.sn] } } }, { @@ -634,21 +642,21 @@ export default defineComponent({ mouseMode.value = bool } - // dock 控制指令 + // dock 控制面板 const { - controlPanelVisible, - setControlPanelVisible, - sendDockControlCmd, - dockDebugOnOff, + dockControlPanelVisible, + setDockControlPanelVisible, + onCloseControlPanel, } = useDockControl() + // 连接或断开drc + useConnectMqtt() + onMounted(() => { const app = getApp() useGMapManageHook.globalPropertiesConfig(app) - setInterval(() => { - console.info(deviceInfo.dock) - }, 1000) }) + function getDrawCallback ({ obj }) { switch (state.currentType) { case MapDoodleEnum.PIN: @@ -816,9 +824,9 @@ export default defineComponent({ EModeCode, str, EDockModeCode, - controlPanelVisible, - dockDebugOnOff, - setControlPanelVisible, + dockControlPanelVisible, + setDockControlPanelVisible, + onCloseControlPanel, NetworkStateTypeEnum, NetworkStateQualityEnum, RainfallEnum, @@ -834,7 +842,7 @@ export default defineComponent({ height: 100%; width: 100%; - .g-action-panle { + .g-action-panel { position: absolute; top: 16px; right: 16px; @@ -870,12 +878,12 @@ export default defineComponent({ left: 10px; top: 10px; width: 480px; - background: black; - color: white; + background: #000; + color: #fff; border-radius: 2px; - opacity: 0.7; + opacity: 0.8; } -.osd > div { +.osd > div:not(.dock-control-panel) { margin-top: 5px; padding-left: 5px; } diff --git a/src/components/devices/device-hms/DeviceHmsDrawer.vue b/src/components/devices/device-hms/DeviceHmsDrawer.vue index 7ff68fc..808b7cb 100644 --- a/src/components/devices/device-hms/DeviceHmsDrawer.vue +++ b/src/components/devices/device-hms/DeviceHmsDrawer.vue @@ -67,7 +67,12 @@ + @@ -77,7 +82,7 @@ + + diff --git a/src/components/g-map/DroneControlPanel.vue b/src/components/g-map/DroneControlPanel.vue new file mode 100644 index 0000000..af2311f --- /dev/null +++ b/src/components/g-map/DroneControlPanel.vue @@ -0,0 +1,756 @@ + + + + + diff --git a/src/components/g-map/DroneControlPopover.vue b/src/components/g-map/DroneControlPopover.vue new file mode 100644 index 0000000..9948c28 --- /dev/null +++ b/src/components/g-map/DroneControlPopover.vue @@ -0,0 +1,115 @@ + + + + + diff --git a/src/components/g-map/use-connect-mqtt.ts b/src/components/g-map/use-connect-mqtt.ts new file mode 100644 index 0000000..a032168 --- /dev/null +++ b/src/components/g-map/use-connect-mqtt.ts @@ -0,0 +1,71 @@ + +import { + ref, + watch, + computed, + onUnmounted, +} from 'vue' +import { useMyStore } from '/@/store' +import { postDrc } from '/@/api/drc' +import { + UranusMqtt, +} from '/@/mqtt' + +type StatusOptions = { + status: 'close'; + event?: CloseEvent; +} | { + status: 'open'; + retryCount: number; +} | { + status: 'pending'; +} + +export function useConnectMqtt () { + const store = useMyStore() + const dockOsdVisible = computed(() => { + return store.state.osdVisible && store.state.osdVisible.visible && store.state.osdVisible.is_dock + }) + const mqttState = ref(null) + + // 监听已打开的设备小窗 窗口数量 + watch(() => dockOsdVisible.value, async (val) => { + // 1.打开小窗 + // 2.设备拥有飞行控制权 + // 3.请求建立mqtt连接的认证信息 + if (val) { + if (mqttState.value) return + const result = await postDrc({}) + if (result?.code === 0) { + const { address, client_id, username, password, expire_time } = result.data + // @TODO: 校验 expire_time + mqttState.value = new UranusMqtt(address, { + clientId: client_id, + username, + password, + }) + mqttState.value?.initMqtt() + mqttState.value?.on('onStatus', (statusOptions: StatusOptions) => { + // @TODO: 异常case + }) + + store.commit('SET_MQTT_STATE', mqttState.value) + store.commit('SET_CLIENT_ID', client_id) + } + // @TODO: 认证失败case + return + } + // 关闭所有小窗后 + // 1.销毁mqtt连接重置mqtt状态 + if (mqttState?.value) { + mqttState.value?.destroyed() + mqttState.value = null + store.commit('SET_MQTT_STATE', null) + store.commit('SET_CLIENT_ID', '') + } + }, { immediate: true }) + + onUnmounted(() => { + mqttState.value?.destroyed() + }) +} diff --git a/src/components/g-map/useDeviceSetting.ts b/src/components/g-map/use-device-setting.ts similarity index 100% rename from src/components/g-map/useDeviceSetting.ts rename to src/components/g-map/use-device-setting.ts diff --git a/src/components/g-map/useDockControl.ts b/src/components/g-map/use-dock-control.ts similarity index 75% rename from src/components/g-map/useDockControl.ts rename to src/components/g-map/use-dock-control.ts index 5e8c38c..3cf9b1a 100644 --- a/src/components/g-map/useDockControl.ts +++ b/src/components/g-map/use-dock-control.ts @@ -4,10 +4,10 @@ import { postSendCmd } from '/@/api/device-cmd' import { DeviceCmd, DeviceCmdItemAction } from '/@/types/device-cmd' export function useDockControl () { - const controlPanelVisible = ref(false) + const dockControlPanelVisible = ref(false) - function setControlPanelVisible (visible: boolean) { - controlPanelVisible.value = visible + function setDockControlPanelVisible (visible: boolean) { + dockControlPanelVisible.value = visible } // 远程调试开关 @@ -16,9 +16,6 @@ export function useDockControl () { sn: sn, cmd: on ? DeviceCmd.DebugModeOpen : DeviceCmd.DebugModeClose }, false) - if (result) { - setControlPanelVisible(on) - } return result } @@ -47,10 +44,17 @@ export function useDockControl () { } } + // 控制面板关闭 + async function onCloseControlPanel (sn: string) { + await dockDebugOnOff(sn, false) + setDockControlPanelVisible(false) + } + return { - controlPanelVisible, - setControlPanelVisible, + dockControlPanelVisible, + setDockControlPanelVisible, sendDockControlCmd, dockDebugOnOff, + onCloseControlPanel, } } diff --git a/src/components/g-map/use-drone-control-mqtt-event.ts b/src/components/g-map/use-drone-control-mqtt-event.ts new file mode 100644 index 0000000..4a3d299 --- /dev/null +++ b/src/components/g-map/use-drone-control-mqtt-event.ts @@ -0,0 +1,61 @@ +import { ref, onMounted, onBeforeUnmount } from 'vue' +import EventBus from '/@/event-bus/' +import { + DRC_METHOD, + DRCHsiInfo, + DRCOsdInfo, + DRCDelayTimeInfo, +} from '/@/types/drc' + +export function useDroneControlMqttEvent (sn: string) { + const drcInfo = ref('') + const hsiInfo = ref('') + const osdInfo = ref('') + const delayInfo = ref('') + + function handleHsiInfo (data: DRCHsiInfo) { + hsiInfo.value = `method: ${DRC_METHOD.HSI_INFO_PUSH}\r\n ${JSON.stringify(data)}\r\n ` + } + + function handleOsdInfo (data: DRCOsdInfo) { + osdInfo.value = `method: ${DRC_METHOD.OSD_INFO_PUSH}\r\n ${JSON.stringify(data)}\r\n ` + } + + function handleDelayTimeInfo (data: DRCDelayTimeInfo) { + delayInfo.value = `method: ${DRC_METHOD.DELAY_TIME_INFO_PUSH}\r\n ${JSON.stringify(data)}\r\n ` + } + + function handleDroneControlMqttEvent (payload: any) { + if (!payload || !payload.method) { + return + } + + switch (payload.method) { + case DRC_METHOD.HSI_INFO_PUSH: { + handleHsiInfo(payload.data) + break + } + case DRC_METHOD.OSD_INFO_PUSH: { + handleOsdInfo(payload.data) + break + } + case DRC_METHOD.DELAY_TIME_INFO_PUSH: { + handleDelayTimeInfo(payload.data) + break + } + } + drcInfo.value = hsiInfo.value + osdInfo.value + delayInfo.value + } + + onMounted(() => { + EventBus.on('droneControlMqttInfo', handleDroneControlMqttEvent) + }) + + onBeforeUnmount(() => { + EventBus.off('droneControlMqttInfo', handleDroneControlMqttEvent) + }) + + return { + drcInfo: drcInfo + } +} diff --git a/src/components/g-map/use-drone-control-ws-event.ts b/src/components/g-map/use-drone-control-ws-event.ts new file mode 100644 index 0000000..34981c2 --- /dev/null +++ b/src/components/g-map/use-drone-control-ws-event.ts @@ -0,0 +1,97 @@ +import { message, notification } from 'ant-design-vue' +import { ref, onMounted, onBeforeUnmount } from 'vue' +import EventBus from '/@/event-bus/' +import { EBizCode } from '/@/types' +import { ControlSource } from '/@/types/device' +import { ControlSourceChangeType, ControlSourceChangeInfo, FlyToPointMessage, TakeoffToPointMessage, DrcModeExitNotifyMessage, DrcStatusNotifyMessage } from '/@/types/drone-control' + +export interface UseDroneControlWsEventParams { +} + +export function useDroneControlWsEvent (sn: string, payloadSn: string, funcs?: UseDroneControlWsEventParams) { + const droneControlSource = ref(ControlSource.A) + const payloadControlSource = ref(ControlSource.B) + function onControlSourceChange (data: ControlSourceChangeInfo) { + if (data.type === ControlSourceChangeType.Flight && data.sn === sn) { + droneControlSource.value = data.control_source + message.info(`Flight control is changed to ${droneControlSource.value}`) + return + } + if (data.type === ControlSourceChangeType.Payload && data.sn === payloadSn) { + payloadControlSource.value = data.control_source + message.info(`Payload control is changed to ${ payloadControlSource.value }.`) + return + } + } + + function handleProgress(key: string, message: string, error: number) { + if (error !== 0) { + notification.error({ + key: key, + message: key + 'Error code:' + error, + description: message, + duration: null + }) + } else { + notification.info({ + key: key, + message: key, + description: message, + duration: 30 + }) + } + } + + function handleDroneControlWsEvent (payload: any) { + if (!payload) { + return + } + + switch (payload.biz_code) { + case EBizCode.ControlSourceChange: { + onControlSourceChange(payload.data) + break + } + case EBizCode.FlyToPointProgress: { + const { sn: deviceSn, result, message: msg } = payload.data as FlyToPointMessage + if (deviceSn !== sn) return + handleProgress(EBizCode.FlyToPointProgress, `device(sn: ${deviceSn}) ${msg}`, result) + break + } + case EBizCode.TakeoffToPointProgress: { + const { sn: deviceSn, result, message: msg } = payload.data as TakeoffToPointMessage + if (deviceSn !== sn) return + handleProgress(EBizCode.TakeoffToPointProgress, `device(sn: ${deviceSn}) ${msg}`, result) + break + } + case EBizCode.JoystickInvalidNotify: { + const { sn: deviceSn, result, message: msg } = payload.data as DrcModeExitNotifyMessage + if (deviceSn !== sn) return + handleProgress(EBizCode.JoystickInvalidNotify, `device(sn: ${deviceSn}) ${msg}`, result) + break + } + case EBizCode.DrcStatusNotify: { + const { sn: deviceSn, result, message: msg } = payload.data as DrcStatusNotifyMessage + if (deviceSn !== sn) return + // handleProgress(EBizCode.DrcStatusNotify, `device(sn: ${deviceSn}) ${msg}`, result) + + break + } + } + // eslint-disable-next-line no-unused-expressions + // console.log('payload.biz_code', payload.data) + } + + onMounted(() => { + EventBus.on('droneControlWs', handleDroneControlWsEvent) + }) + + onBeforeUnmount(() => { + EventBus.off('droneControlWs', handleDroneControlWsEvent) + }) + + return { + droneControlSource: droneControlSource, + payloadControlSource: payloadControlSource + } +} diff --git a/src/components/g-map/use-drone-control.ts b/src/components/g-map/use-drone-control.ts new file mode 100644 index 0000000..dee8366 --- /dev/null +++ b/src/components/g-map/use-drone-control.ts @@ -0,0 +1,40 @@ +import { ref } from 'vue' +import { postFlyToPoint, PostFlyToPointBody, deleteFlyToPoint, postTakeoffToPoint, PostTakeoffToPointBody } from '/@/api/drone-control/drone' +import { message } from 'ant-design-vue' + +export function useDroneControl () { + const droneControlPanelVisible = ref(false) + + function setDroneControlPanelVisible (visible: boolean) { + droneControlPanelVisible.value = visible + } + + async function flyToPoint (sn: string, body: PostFlyToPointBody) { + const { code } = await postFlyToPoint(sn, body) + if (code === 0) { + message.success('Fly to') + } + } + + async function stopFlyToPoint (sn: string) { + const { code } = await deleteFlyToPoint(sn) + if (code === 0) { + message.success('Stop fly to') + } + } + + async function takeoffToPoint (sn: string, body: PostTakeoffToPointBody) { + const { code } = await postTakeoffToPoint(sn, body) + if (code === 0) { + message.success('Take off successfully') + } + } + + return { + droneControlPanelVisible, + setDroneControlPanelVisible, + flyToPoint, + stopFlyToPoint, + takeoffToPoint + } +} diff --git a/src/components/g-map/use-manual-control.ts b/src/components/g-map/use-manual-control.ts new file mode 100644 index 0000000..eb178a8 --- /dev/null +++ b/src/components/g-map/use-manual-control.ts @@ -0,0 +1,162 @@ +import { + ref, + onUnmounted, + watch, + Ref, +} from 'vue' +import { message } from 'ant-design-vue' +import { + DRC_METHOD, + DroneControlProtocol, +} from '/@/types/drc' +import { + useMqtt, + DeviceTopicInfo +} from './use-mqtt' + +let myInterval: any + +export enum KeyCode { + KEY_W = 'KeyW', + KEY_A = 'KeyA', + KEY_S = 'KeyS', + KEY_D = 'KeyD', + KEY_Q = 'KeyQ', + KEY_E = 'KeyE', + ARROW_UP = 'ArrowUp', + ARROW_DOWN = 'ArrowDown', +} + +export function useManualControl (deviceTopicInfo: DeviceTopicInfo, isCurrentFlightController: Ref) { + const activeCodeKey = ref(null) as Ref + const mqttHooks = useMqtt(deviceTopicInfo) + + function handlePublish (params: DroneControlProtocol) { + const body = { + method: DRC_METHOD.DRONE_CONTROL, + data: params, + } + handleClearInterval() + myInterval = setInterval(() => { + window.console.log('keyCode>>>>', activeCodeKey.value, body) + body.data.seq = new Date().getTime() + mqttHooks?.publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 0 }) + }, 50) + } + + function handleKeyup (keyCode: KeyCode) { + if (!deviceTopicInfo.pubTopic) { + message.error('请确保已经建立DRC链路') + return + } + const SPEED = 5 // check + const HEIGHT = 5 // check + const W_SPEED = 20 // 机头角速度 + switch (keyCode) { + case 'KeyA': + if (activeCodeKey.value === keyCode) return + handlePublish({ y: -SPEED }) + activeCodeKey.value = keyCode + break + case 'KeyW': + if (activeCodeKey.value === keyCode) return + handlePublish({ x: SPEED }) + activeCodeKey.value = keyCode + break + case 'KeyS': + if (activeCodeKey.value === keyCode) return + handlePublish({ x: -SPEED }) + activeCodeKey.value = keyCode + break + case 'KeyD': + if (activeCodeKey.value === keyCode) return + handlePublish({ y: SPEED }) + activeCodeKey.value = keyCode + break + case 'ArrowUp': + if (activeCodeKey.value === keyCode) return + handlePublish({ h: HEIGHT }) + activeCodeKey.value = keyCode + break + case 'ArrowDown': + if (activeCodeKey.value === keyCode) return + handlePublish({ h: -HEIGHT }) + activeCodeKey.value = keyCode + break + case 'KeyQ': + if (activeCodeKey.value === keyCode) return + handlePublish({ w: -W_SPEED }) + activeCodeKey.value = keyCode + break + case 'KeyE': + if (activeCodeKey.value === keyCode) return + handlePublish({ w: W_SPEED }) + activeCodeKey.value = keyCode + break + default: + break + } + } + + function handleClearInterval () { + clearInterval(myInterval) + myInterval = undefined + } + + function resetControlState () { + activeCodeKey.value = null + handleClearInterval() + } + + function onKeyup () { + resetControlState() + } + + function onKeydown (e: KeyboardEvent) { + handleKeyup(e.code as KeyCode) + } + + function startKeyboardManualControl () { + window.addEventListener('keydown', onKeydown) + window.addEventListener('keyup', onKeyup) + } + + function closeKeyboardManualControl () { + resetControlState() + window.removeEventListener('keydown', onKeydown) + window.removeEventListener('keyup', onKeyup) + } + + watch(() => isCurrentFlightController.value, (val) => { + if (val && deviceTopicInfo.pubTopic) { + startKeyboardManualControl() + } else { + closeKeyboardManualControl() + } + }, { immediate: true }) + + onUnmounted(() => { + closeKeyboardManualControl() + }) + + function handleEmergencyStop () { + if (!deviceTopicInfo.pubTopic) { + message.error('请确保已经建立DRC链路') + return + } + const body = { + method: DRC_METHOD.DRONE_EMERGENCY_STOP, + data: {} + } + resetControlState() + window.console.log('handleEmergencyStop>>>>', deviceTopicInfo.pubTopic, body) + mqttHooks?.publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 1 }) + } + + return { + activeCodeKey, + handleKeyup, + handleEmergencyStop, + resetControlState, + } +} diff --git a/src/components/g-map/use-mqtt.ts b/src/components/g-map/use-mqtt.ts new file mode 100644 index 0000000..c02f537 --- /dev/null +++ b/src/components/g-map/use-mqtt.ts @@ -0,0 +1,132 @@ +import { + ref, + reactive, + computed, + watch, + onUnmounted, +} from 'vue' +import { + IClientPublishOptions, + IPublishPacket, +} from '/@/mqtt' +import { useMyStore } from '/@/store' +import { + DRC_METHOD, +} from '/@/types/drc' +import EventBus from '/@/event-bus' + +export interface DeviceTopicInfo{ + sn: string + pubTopic: string + subTopic: string +} + +type MessageMqtt = (topic: string, payload: Buffer, packet: IPublishPacket) => void | Promise + +export function useMqtt (deviceTopicInfo: DeviceTopicInfo) { + let cacheSubscribeArr: { + topic: string; + callback?: MessageMqtt; + }[] = [] + + const store = useMyStore() + + const mqttState = computed(() => { + return store.state.mqttState + }) + + function publishMqtt (topic: string, body: object, ots?: IClientPublishOptions) { + // const buffer = Buffer.from(JSON.stringify(body)) + mqttState.value?.publishMqtt(topic, JSON.stringify(body), ots) + } + + function subscribeMqtt (topic: string, handleMessageMqtt?: MessageMqtt) { + mqttState.value?.subscribeMqtt(topic) + const handler = handleMessageMqtt || onMessageMqtt + mqttState.value?.on('onMessageMqtt', handler) + cacheSubscribeArr.push({ + topic, + callback: handler, + }) + } + + function onMessageMqtt (message: any) { + if (cacheSubscribeArr.findIndex(item => item.topic === message?.topic) !== -1) { + const payloadStr = new TextDecoder('utf-8').decode(message?.payload) + const payloadObj = JSON.parse(payloadStr) + switch (payloadObj?.method) { + case DRC_METHOD.HEART_BEAT: + break + case DRC_METHOD.DELAY_TIME_INFO_PUSH: + case DRC_METHOD.HSI_INFO_PUSH: + case DRC_METHOD.OSD_INFO_PUSH: + EventBus.emit('droneControlMqttInfo', payloadObj) + break + default: + break + } + } + } + + function unsubscribeDrc () { + // 销毁已订阅事件 + cacheSubscribeArr.forEach(item => { + mqttState.value?.off('onMessageMqtt', item.callback) + mqttState.value?.unsubscribeMqtt(item.topic) + }) + cacheSubscribeArr = [] + } + + // 心跳 + const heartBeatSeq = ref(0) + const state = reactive({ + heartState: new Map(), + }) + + // 监听云控控制权 + watch(() => deviceTopicInfo, (val, oldVal) => { + if (val.subTopic !== '') { + // 1.订阅topic + subscribeMqtt(deviceTopicInfo.subTopic) + // 2.发心跳 + publishDrcPing(deviceTopicInfo.sn) + } else { + clearInterval(state.heartState.get(deviceTopicInfo.sn)?.pingInterval) + state.heartState.delete(deviceTopicInfo.sn) + heartBeatSeq.value = 0 + } + }, { immediate: true, deep: true }) + + function publishDrcPing (sn: string) { + const body = { + method: DRC_METHOD.HEART_BEAT, + data: { + ts: new Date().getTime(), + seq: heartBeatSeq.value, + }, + } + const pingInterval = setInterval(() => { + if (!mqttState.value) return + heartBeatSeq.value += 1 + body.data.ts = new Date().getTime() + body.data.seq = heartBeatSeq.value + publishMqtt(deviceTopicInfo.pubTopic, body, { qos: 0 }) + }, 1000) + state.heartState.set(sn, { + pingInterval, + }) + } + + onUnmounted(() => { + unsubscribeDrc() + heartBeatSeq.value = 0 + }) + + return { + mqttState, + publishMqtt, + subscribeMqtt, + } +} diff --git a/src/components/g-map/use-payload-control.ts b/src/components/g-map/use-payload-control.ts new file mode 100644 index 0000000..d702c00 --- /dev/null +++ b/src/components/g-map/use-payload-control.ts @@ -0,0 +1,120 @@ +import { message } from 'ant-design-vue' +import { + postPayloadAuth, + postPayloadCommands, + PayloadCommandsEnum, + PostCameraModeBody, + PostCameraFocalLengthBody, + PostGimbalResetBody, + PostCameraAimBody, +} from '/@/api/drone-control/payload' +import { ControlSource } from '/@/types/device' + +export function usePayloadControl () { + function checkPayloadAuth (controlSource?: ControlSource) { + if (controlSource !== ControlSource.A) { + message.error('Get Payload Control first') + return false + } + return true + } + + async function authPayload (sn: string, payloadIndx: string) { + const { code } = await postPayloadAuth(sn, { + payload_index: payloadIndx + }) + if (code === 0) { + message.success('Get Payload Control successfully') + return true + } + return false + } + + async function resetGimbal (sn: string, data: PostGimbalResetBody) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.GimbalReset, + data: data + }) + if (code === 0) { + message.success('Gimbal Reset successfully') + } + } + + async function switchCameraMode (sn: string, data: PostCameraModeBody) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraModeSwitch, + data: data + }) + if (code === 0) { + message.success('Camera Mode Switch successfully') + } + } + + async function takeCameraPhoto (sn: string, payloadIndx: string) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraPhotoTake, + data: { + payload_index: payloadIndx + } + }) + if (code === 0) { + message.success('Take Photo successfully') + } + } + + async function startCameraRecording (sn: string, payloadIndx: string) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraRecordingStart, + data: { + payload_index: payloadIndx + } + }) + if (code === 0) { + message.success('Start Recording successfully') + } + } + + async function stopCameraRecording (sn: string, payloadIndx: string) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraRecordingStop, + data: { + payload_index: payloadIndx + } + }) + if (code === 0) { + message.success('Stop Recording successfully') + } + } + + async function changeCameraFocalLength (sn: string, data: PostCameraFocalLengthBody) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraFocalLengthSet, + data: data, + }) + if (code === 0) { + message.success('Zoom successfully') + } + } + + async function cameraAim (sn: string, data: PostCameraAimBody) { + const { code } = await postPayloadCommands(sn, { + cmd: PayloadCommandsEnum.CameraAim, + data: data, + }) + if (code === 0) { + message.success('Zoom Aim successfully') + } + } + + return { + checkPayloadAuth, + authPayload, + resetGimbal, + switchCameraMode, + takeCameraPhoto, + startCameraRecording, + stopCameraRecording, + changeCameraFocalLength, + cameraAim, + } +} diff --git a/src/components/task/CreatePlan.vue b/src/components/task/CreatePlan.vue index 37f0ae7..becc1be 100644 --- a/src/components/task/CreatePlan.vue +++ b/src/components/task/CreatePlan.vue @@ -182,7 +182,8 @@ function onSubmit () { disabled.value = true const createPlanBody = { ...planBody } as unknown as CreatePlan if (planBody.select_execute_time) { - createPlanBody.execute_time = moment(planBody.select_execute_time).valueOf() + createPlanBody.task_days = [moment(planBody.select_execute_time).unix()] + createPlanBody.task_periods = [createPlanBody.task_days] } createPlanBody.rth_altitude = Number(createPlanBody.rth_altitude) if (wayline.value && wayline.value.template_types && wayline.value.template_types.length > 0) { diff --git a/src/components/task/TaskPanel.vue b/src/components/task/TaskPanel.vue index e7874e5..fd6a204 100644 --- a/src/components/task/TaskPanel.vue +++ b/src/components/task/TaskPanel.vue @@ -5,7 +5,7 @@ :pagination="paginationProp" :scroll="{ x: '100%', y: 600 }" @change="refreshData"> @@ -84,7 +102,7 @@ import { message } from 'ant-design-vue' import { TableState } from 'ant-design-vue/lib/table/interface' import { onMounted } from 'vue' import { IPage } from '/@/api/http/type' -import { deleteTask, getWaylineJobs, Task, uploadMediaFileNow } from '/@/api/wayline' +import { deleteTask, updateTaskStatus, UpdateTaskStatus, getWaylineJobs, Task, uploadMediaFileNow } from '/@/api/wayline' import { useMyStore } from '/@/store' import { ELocalStorageKey } from '/@/types/enums' import { useFormatTask } from './use-format-task' @@ -272,6 +290,30 @@ async function onDeleteTask (jobId: string) { } } +// 挂起任务 +async function onSuspendTask (jobId: string) { + const { code } = await updateTaskStatus(workspaceId, { + job_id: jobId, + status: UpdateTaskStatus.Suspend + }) + if (code === 0) { + message.success('Suspended successfully') + getPlans() + } +} + +// 解除挂起任务 +async function onResumeTask (jobId: string) { + const { code } = await updateTaskStatus(workspaceId, { + job_id: jobId, + status: UpdateTaskStatus.Resume + }) + if (code === 0) { + message.success('Resumed successfully') + getPlans() + } +} + // 立即上传媒体 async function onUploadMediaFileNow (jobId: string) { const { code } = await uploadMediaFileNow(workspaceId, jobId) @@ -291,8 +333,13 @@ async function onUploadMediaFileNow (jobId: string) { margin-top: 10px; } .action-area { - color: $primary; - cursor: pointer; + + &::v-deep { + .ant-btn { + margin-right: 10px; + margin-bottom: 10px; + } + } } .circle-icon { diff --git a/src/event-bus/index.ts b/src/event-bus/index.ts index 72feae5..fbe0933 100644 --- a/src/event-bus/index.ts +++ b/src/event-bus/index.ts @@ -4,6 +4,8 @@ type Events = { deviceUpgrade: any; // 设备升级 deviceLogUploadProgress: any // 设备日志上传 flightTaskWs: any // 机场任务消息 + droneControlWs: any // 飞行指令信息 + droneControlMqttInfo: any // drc 链路通知 }; const emitter: Emitter = mitt() diff --git a/src/hooks/use-g-map-tsa.ts b/src/hooks/use-g-map-tsa.ts index c36779b..f71217c 100644 --- a/src/hooks/use-g-map-tsa.ts +++ b/src/hooks/use-g-map-tsa.ts @@ -1,12 +1,11 @@ import store from '/@/store' import { getRoot } from '/@/root' -import { ELocalStorageKey } from '/@/types' +import { ELocalStorageKey, EDeviceTypeName } from '/@/types' import { getDeviceBySn } from '/@/api/manage' import { message } from 'ant-design-vue' import dockIcon from '/@/assets/icons/dock.png' import rcIcon from '/@/assets/icons/rc.png' import droneIcon from '/@/assets/icons/drone.png' -import { EDeviceTypeName } from '/@/types' export function deviceTsaUpdate () { const root = getRoot() diff --git a/src/mqtt/config.ts b/src/mqtt/config.ts new file mode 100644 index 0000000..1af7df6 --- /dev/null +++ b/src/mqtt/config.ts @@ -0,0 +1,12 @@ + +import { + IClientOptions, +} from 'mqtt' + +export const OPTIONS: IClientOptions = { + clean: true, // true: 清除会话, false: 保留会话 + connectTimeout: 10000, // mqtt 超时时间 + resubscribe: true, // 断开重连后,再次订阅原订阅 + reconnectPeriod: 10000, // 重连间隔时间: 5s + keepalive: 1, // 心跳间隔时间:1s +} diff --git a/src/mqtt/index.ts b/src/mqtt/index.ts new file mode 100644 index 0000000..f6570df --- /dev/null +++ b/src/mqtt/index.ts @@ -0,0 +1,117 @@ +import EventEmitter from 'eventemitter3' +import { + OPTIONS, +} from './config' +import { + connect, + MqttClient, + IClientPublishOptions, + IPublishPacket, + Packet, + ISubscriptionGrant, + IClientOptions, +} from 'mqtt/dist/mqtt.min' + +export class UranusMqtt extends EventEmitter { + _url: string + _options?: IClientOptions + _client: MqttClient | null + _hasInit: boolean + + constructor (url?: string, options?: IClientOptions) { + super() + this._url = url || '' + this._options = options + this._client = null + this._hasInit = false + } + + initMqtt = () => { + // 仅初始化一次 + if (this._hasInit) return + // 建立连接 + this._client = connect(this._url, { + ...OPTIONS, + ...this._options, + }) + this._hasInit = true + if (this._client) { + this._client.on('reconnect', this._onReconnect) + + // 消息监听 + this._client.on('message', this._onMessage) + + // 连接关闭 + this._client.on('close', this._onClose) + + // 连接异常 + this._client.on('error', this._onError) + } + } + + // 发布 + publishMqtt = (topic: string, body: string | Buffer, opts?: IClientPublishOptions) => { + if (!this._client?.connected) { + this.initMqtt() + } + this._client?.publish(topic, body, opts || {}, (error?: Error, packet?: Packet) => { + if (error) { + window.console.error('mqtt publish error,', error, packet) + } + }) + } + + // 订阅 + subscribeMqtt = (topic: string) => { + if (!this._client?.connected) { + this.initMqtt() + } + window.console.log('subscribeMqtt>>>>>', topic) + this._client?.subscribe(topic, (error: Error, granted: ISubscriptionGrant[]) => { + window.console.log('mqtt subscribe,', error, granted) + }) + } + + // 取消订阅 + unsubscribeMqtt = (topic: string) => { + window.console.log('mqtt unsubscribeMqtt,', topic) + this._client?.unsubscribe(topic) + } + + // 关闭 mqtt 客户端 + destroyed = () => { + window.console.log('mqtt destroyed') + this._client?.end() + } + + _onReconnect = () => { + if (this._client) { window.console.error('mqtt reconnect,') } + } + + _onMessage = (topic: string, payload: Buffer, packet: IPublishPacket) => { + this.emit('onMessageMqtt', { topic, payload, packet }) + } + + _onClose = () => { + // 连接异常关闭会自动重连 + window.console.error('mqtt close,') + this.emit('onStatus', { + status: 'close', + }) + } + + _onError = (error: Error) => { + // 连接错误会自动重连 + window.console.error('mqtt error,', error) + this.emit('onStatus', { + status: 'error', + data: error, + }) + } +} + +export { + IClientOptions, + IPublishPacket, + IClientPublishOptions, +} diff --git a/src/pages/page-web/projects/Firmwares.vue b/src/pages/page-web/projects/Firmwares.vue index d3e6757..54fd590 100644 --- a/src/pages/page-web/projects/Firmwares.vue +++ b/src/pages/page-web/projects/Firmwares.vue @@ -242,7 +242,7 @@ const uploadFile = async () => { if (fileList.value.length === 0) { message.error('Please select at least one file.') } - const uploading: string = 'uploading' + let uploading: string formRef.value.validate().then(async () => { const file: FileItem = fileList.value[0] const fileData = new FormData() @@ -257,6 +257,8 @@ const uploadFile = async () => { fileData.append(key, val.toString()) } }) + const timestamp = new Date().getTime() + uploading = (file.name ?? 'uploding') + timestamp notification.open({ key: uploading, message: `Uploading ${moment().format()}`, @@ -267,7 +269,7 @@ const uploadFile = async () => { if (res.code === 0) { notification.success({ message: `Uploaded ${moment().format()}`, - description: `[${file.name}] file uploaded successfully.`, + description: `[${file.name}] file uploaded successfully. Duration: ${moment.duration(new Date().getTime() - timestamp).asSeconds()}`, duration: null }) getAllFirmwares(pageParam) diff --git a/src/pages/page-web/projects/devices.vue b/src/pages/page-web/projects/devices.vue index 768e86f..07c722d 100644 --- a/src/pages/page-web/projects/devices.vue +++ b/src/pages/page-web/projects/devices.vue @@ -20,7 +20,9 @@ style="margin: -5px 0" /> @@ -127,7 +129,7 @@ import { useDeviceUpgradeEvent } from '/@/components/devices/device-upgrade/use- import { DeviceCmdExecuteInfo, DeviceCmdExecuteStatus } from '/@/types/device-cmd' import DeviceLogUploadRecordDrawer from '/@/components/devices/device-log/DeviceLogUploadRecordDrawer.vue' import DeviceHmsDrawer from '/@/components/devices/device-hms/DeviceHmsDrawer.vue' -import { message } from 'ant-design-vue' +import { message, notification } from 'ant-design-vue' interface DeviceData { device: Device[] @@ -268,13 +270,18 @@ function updateDevicesByWs (devices: Device[], payload: DeviceCmdExecuteInfo) { for (let i = 0; i < devices.length; i++) { if (devices[i].device_sn === payload.sn) { if (!payload.output) return - const { status, progress } = payload.output + const { status, progress, ext } = payload.output if (status === DeviceCmdExecuteStatus.Sent || status === DeviceCmdExecuteStatus.InProgress) { // 升级中 + const rate = ext?.rate ? (ext.rate / 1024).toFixed(2) + 'kb/s' : '' devices[i].firmware_status = DeviceFirmwareStatusEnum.DuringUpgrade - devices[i].firmware_progress = progress?.percent || 0 + devices[i].firmware_progress = (progress?.percent || 0) + '% ' + rate } else { // 终态:成功,失败,超时 if (status === DeviceCmdExecuteStatus.Failed || status === DeviceCmdExecuteStatus.Timeout) { - message.error(`设备(${payload.sn}) 升级失败`) + notification.error({ + message: `(${payload.sn}) Upgrade failed`, + description: `Error Code: ${payload.result}`, + duration: null + }) } // 拉取列表 getDevices(current.value[0], true) diff --git a/src/pages/page-web/projects/dock.vue b/src/pages/page-web/projects/dock.vue index 6e4febf..e31c88c 100644 --- a/src/pages/page-web/projects/dock.vue +++ b/src/pages/page-web/projects/dock.vue @@ -58,7 +58,7 @@ onMounted(() => { getDocks() const key = setInterval(() => { const data = document.getElementById('data')?.lastElementChild as HTMLDivElement - if (body.total === 0 || Math.ceil(body.total / body.page_size) <= body.page || scorllHeight.value <= data?.clientHeight + data?.offsetTop) { + if (body.total === 0 || Math.ceil(body.total / body.page_size) <= body.page || scorllHeight.value + 50 <= data?.clientHeight + data?.offsetTop) { clearInterval(key) return } diff --git a/src/pages/page-web/projects/livestream.vue b/src/pages/page-web/projects/livestream.vue index ad9a9f9..f2c3414 100644 --- a/src/pages/page-web/projects/livestream.vue +++ b/src/pages/page-web/projects/livestream.vue @@ -31,8 +31,8 @@ import { CloseOutlined } from '@ant-design/icons-vue' import { getRoot } from '/@/root' import { ERouterName } from '/@/types' const root = getRoot() -const routeName = ref() -const showLive = ref(false) +const routeName = ref('LiveOthers') +const showLive = ref(root.$route.name === ERouterName.LIVING) const options = [ { key: 0, label: 'Agora Live', path: '/' + ERouterName.LIVESTREAM + '/' + ERouterName.LIVING, routeName: 'LiveAgora' }, @@ -40,6 +40,7 @@ const options = [ ] const selectLivestream = (route: string) => { + showLive.value = root.$route.name === ERouterName.LIVING routeName.value = route } diff --git a/src/pages/page-web/projects/tsa.vue b/src/pages/page-web/projects/tsa.vue index 3668f68..9ab2216 100644 --- a/src/pages/page-web/projects/tsa.vue +++ b/src/pages/page-web/projects/tsa.vue @@ -20,15 +20,15 @@
- {{ dock.gateway.callsign }} - {{ dock.callsign ?? 'No Drone' }} +
{{ dock.gateway.callsign }} - {{ dock.callsign ?? 'No Drone' }}
- +
{{ dockInfo[dock.gateway.sn] ? EDockModeCode[dockInfo[dock.gateway.sn].basic_osd?.mode_code] : EDockModeCode[EDockModeCode.Disconnected] }} - +
@@ -75,11 +75,11 @@
-
+
- +
{{ deviceInfo[dock.sn] ? EModeCode[deviceInfo[dock.sn].mode_code] : EModeCode[EModeCode.Disconnected] }} - +
@@ -173,11 +173,11 @@
-
+
- {{ device.gateway.model }} - {{ device.gateway.callsign }} +
{{ device.gateway.model }} - {{ device.gateway.callsign }}
@@ -194,10 +194,9 @@ import { computed, onMounted, reactive, ref, watch, WritableComputedRef } from ' import { EDeviceTypeName, ELocalStorageKey } from '/@/types' import noData from '/@/assets/icons/no-data.png' import rc from '/@/assets/icons/rc.png' -import { DeviceStatus, EModeCode, OSDVisible, EDockModeCode, DeviceOsd } from '/@/types/device' +import { OnlineDevice, EModeCode, OSDVisible, EDockModeCode, DeviceOsd } from '/@/types/device' import { useMyStore } from '/@/store' import { getDeviceTopo, getUnreadDeviceHms, updateDeviceHms } from '/@/api/manage' -import { message } from 'ant-design-vue' import { RocketOutlined, EyeInvisibleOutlined, EyeOutlined, RobotOutlined, DoubleRightOutlined } from '@ant-design/icons-vue' import { EHmsLevel } from '/@/types/enums' @@ -208,22 +207,6 @@ const osdVisible = ref({} as OSDVisible) const hmsVisible = new Map() const scorllHeight = ref() -interface OnlineDevice { - model: string, - callsign: string, - sn: string, - mode: number, - gateway: { - model: string, - callsign: string, - sn: string, - domain: string, - }, - payload: { - model: string - }[] -} - const onlineDevices = reactive({ data: [] as OnlineDevice[] }) @@ -286,7 +269,12 @@ function getOnlineTopo () { } child?.payloads_list.forEach((payload: any) => { device.payload.push({ - model: payload.payload_name + index: payload.index, + model: payload.model, + payload_name: payload.payload_name, + payload_sn: payload.payload_sn, + control_source: payload.control_source, + payload_index: payload.payload_index }) }) if (EDeviceTypeName.Dock === gateway.domain) { @@ -316,6 +304,7 @@ function switchVisible (e: any, device: OnlineDevice, isDock: boolean, isClick: osdVisible.value.gateway_sn = device.gateway.sn osdVisible.value.is_dock = isDock osdVisible.value.gateway_callsign = device.gateway.callsign + osdVisible.value.payloads = device.payload } store.commit('SET_OSD_VISIBLE_INFO', osdVisible) } diff --git a/src/pages/page-web/projects/workspace.vue b/src/pages/page-web/projects/workspace.vue index 4d965f0..d302112 100644 --- a/src/pages/page-web/projects/workspace.vue +++ b/src/pages/page-web/projects/workspace.vue @@ -100,6 +100,15 @@ const messageHandler = async (payload: any) => { }) break } + case EBizCode.ControlSourceChange: + case EBizCode.FlyToPointProgress: + case EBizCode.TakeoffToPointProgress: + case EBizCode.JoystickInvalidNotify: + case EBizCode.DrcStatusNotify: + { + EventBus.emit('droneControlWs', payload) + break + } default: break } diff --git a/src/shims-mqtt.d.ts b/src/shims-mqtt.d.ts new file mode 100644 index 0000000..45ab849 --- /dev/null +++ b/src/shims-mqtt.d.ts @@ -0,0 +1,4 @@ +declare module 'mqtt/dist/mqtt.min' { + import MQTT from 'mqtt' + export = MQTT +} diff --git a/src/store/index.ts b/src/store/index.ts index d7f4673..6dbf7ba 100644 --- a/src/store/index.ts +++ b/src/store/index.ts @@ -67,13 +67,14 @@ const initStateFunc = () => ({ currentSn: '', currentType: -1 }, - osdVisible: { + osdVisible: { // osd 显示设备相关信息 sn: '', callsign: '', model: '', visible: false, gateway_sn: '', is_dock: false, + payloads: null } as OSDVisible, waylineInfo: { @@ -86,7 +87,9 @@ const initStateFunc = () => ({ }, // 机场指令执行状态信息 devicesCmdExecuteInfo: { - } as DevicesCmdExecuteInfo + } as DevicesCmdExecuteInfo, + mqttState: null as any, // mqtt 实例 + clientId: '', // mqtt 连接 唯一客户端id }) export type RootStateType = ReturnType @@ -117,15 +120,18 @@ const mutations: MutationTree = { state.deviceState.currentSn = info.sn state.deviceState.currentType = EDeviceTypeName.Dock const dock = state.deviceState.dockInfo[info.sn] + if (info.host.mode_code !== undefined) { + dock.basic_osd = info.host + return + } if (info.host.sdr) { dock.link_osd = info.host return } - if (info.host.job_number) { + if (info.host.job_number !== undefined) { dock.work_osd = info.host return } - dock.basic_osd = info.host }, SET_DRAW_VISIBLE_INFO (state, bool) { state.drawVisible = bool @@ -182,7 +188,13 @@ const mutations: MutationTree = { } else { state.devicesCmdExecuteInfo[info.sn] = [info] } - } + }, + SET_MQTT_STATE (state, mqttState) { + state.mqttState = mqttState + }, + SET_CLIENT_ID (state, clientId) { + state.clientId = clientId + }, } const actions: ActionTree = { diff --git a/src/types/device-cmd.ts b/src/types/device-cmd.ts index d8804cd..c1e545d 100644 --- a/src/types/device-cmd.ts +++ b/src/types/device-cmd.ts @@ -39,6 +39,16 @@ export interface DeviceCmdItem{ loading: boolean // 按钮loading disabled?: boolean // 按钮disabled } +export const noDebugCmdList: DeviceCmdItem[] = [ + { + label: 'Return Home', + status: '--', + operateText: 'Return Home', + cmdKey: DeviceCmd.ReturnHome, + func: 'returnHome', + loading: false, + }, +] // 机场指令 export const cmdList: DeviceCmdItem[] = [ @@ -90,14 +100,6 @@ export const cmdList: DeviceCmdItem[] = [ func: 'chargeStatus', loading: false, }, - { - label: '一键返航', - status: '--', - operateText: '返航', - cmdKey: DeviceCmd.ReturnHome, - func: 'returnHome', - loading: false, - }, { label: '机场存储', status: '--', @@ -281,6 +283,9 @@ export interface DeviceCmdExecuteInfo { percent: number, step_key: string, step_result: number + }, + ext?: { + rate?: number } } result: number, diff --git a/src/types/device.ts b/src/types/device.ts index f23f27e..fdbeb67 100644 --- a/src/types/device.ts +++ b/src/types/device.ts @@ -1,6 +1,8 @@ import { commonColor } from '/@/utils/color' import { NightLightsStateEnum, DistanceLimitStatus, ObstacleAvoidance } from './device-setting' import { AlarmModeEnum, BatteryStoreModeEnum, DroneBatteryStateEnum, FourGLinkStateEnum, SdrLinkStateEnum, LinkWorkModeEnum } from './airport-tsa' +import { CameraMode } from '/@/types/live-stream' + export interface DeviceValue { key: string; // 'domain-type-subtype' domain: string; // 表示一个领域,作为一个命名空间,暂时分 飞机类-0, 负载类-1,RC类-2,机场类-3 4种 @@ -20,10 +22,6 @@ export enum DOMAIN { export enum DRONE_TYPE { M30 = 67, M300 = 60, - Phantom4 = 11, - Phantom4Pro = 18, - Phantom4RTK = 59, - Phantom4Advanced = 27, Mavic3EnterpriseAdvanced= 77, } @@ -76,10 +74,6 @@ export const DEVICE_MODEL_KEY = { M3T: `${DOMAIN.DRONE}-${DRONE_TYPE.Mavic3EnterpriseAdvanced}-${DEVICE_SUB_TYPE.ONE}`, M300: `${DOMAIN.DRONE}-${DRONE_TYPE.M300}-${DEVICE_SUB_TYPE.ZERO}`, - Phantom4: `${DOMAIN.DRONE}-${DRONE_TYPE.Phantom4}-${DEVICE_SUB_TYPE.ZERO}`, - Phantom4Pro: `${DOMAIN.DRONE}-${DRONE_TYPE.Phantom4Pro}-${DEVICE_SUB_TYPE.ZERO}`, - Phantom4RTK: `${DOMAIN.DRONE}-${DRONE_TYPE.Phantom4RTK}-${DEVICE_SUB_TYPE.ZERO}`, - Phantom4Advanced: `${DOMAIN.DRONE}-${DRONE_TYPE.Phantom4Advanced}-${DEVICE_SUB_TYPE.ZERO}`, FPV: `${DOMAIN.PAYLOAD}-${PAYLOAD_TYPE.FPV}-${DEVICE_SUB_TYPE.ZERO}`, H20: `${DOMAIN.PAYLOAD}-${PAYLOAD_TYPE.H20}-${DEVICE_SUB_TYPE.ZERO}`, @@ -113,10 +107,6 @@ export const DEVICE_NAME = { [DEVICE_MODEL_KEY.M3T]: 'Mavic 3T', // [DEVICE_MODEL_KEY.M3M]: 'Mavic 3M', [DEVICE_MODEL_KEY.M300]: 'M300 RTK', - [DEVICE_MODEL_KEY.Phantom4]: 'Phantom 4', - [DEVICE_MODEL_KEY.Phantom4Pro]: 'Phantom 4 Pro', - [DEVICE_MODEL_KEY.Phantom4RTK]: 'Phantom 4 RTK', - [DEVICE_MODEL_KEY.Phantom4Advanced]: 'Phantom 4 Advanced', // payload [DEVICE_MODEL_KEY.FPV]: 'FPV', @@ -143,6 +133,36 @@ export const DEVICE_NAME = { [DEVICE_MODEL_KEY.Dock]: 'Dock', } +// 控制权 +export enum ControlSource { + A = 'A', + B = 'B' +} + +export interface PayloadInfo { + index: number, + model: string, + control_source?: ControlSource, + payload_sn?: string, + payload_index?: string, + payload_name?: string, +} + +// 设备信息 +export interface OnlineDevice { + model: string, + callsign: string, + sn: string, + mode: number, + gateway: { + model: string, + callsign: string, + sn: string, + domain: string, + }, + payload: PayloadInfo[] +} + // 固件升级类型 export enum DeviceFirmwareTypeEnum { ToUpgraded = 3, // 普通升级 @@ -184,7 +204,7 @@ export interface Device { children?: Device[], domain: number, type: number, - firmware_progress?: number, // 升级进度 + firmware_progress?: string, // 升级进度 } export interface DeviceStatus { @@ -207,6 +227,7 @@ export interface OSDVisible { is_dock: boolean, gateway_sn: string, gateway_callsign: string, + payloads: null | PayloadInfo [], } export interface GatewayOsd { @@ -215,6 +236,24 @@ export interface GatewayOsd { longitude: number, latitude: number, } + +export interface OsdCameraLiveview { + bottom: number, + left: number, + right: number, + top: number, +} +export interface DeviceOsdCamera { + camera_mode: CameraMode, + payload_index: string, + photo_state: number, + record_time: number, + recording_state: number, + remain_photo_num: number, + remain_record_duration: number, + liveview_world_region: OsdCameraLiveview +} + export interface DeviceOsd { longitude: number, latitude: number, @@ -242,6 +281,7 @@ export interface DeviceOsd { height_limit?: number;// 限高设置 distance_limit_status?: DistanceLimitStatus;// 限远开关 obstacle_avoidance?: ObstacleAvoidance;// 飞行器避障开关设置 + cameras?: DeviceOsdCamera[] } export enum NetworkStateTypeEnum { @@ -263,16 +303,16 @@ export enum RainfallEnum { } export enum DroneInDockEnum { - INSIDE, OUTSIDE + OUTSIDE, INSIDE } export interface DockBasicOsd { - network_state: { + network_state?: { type: NetworkStateTypeEnum, quality: number, rate: number, }, - drone_charge_state: { + drone_charge_state?: { state: number, capacity_percent: number, }, @@ -285,7 +325,7 @@ export interface DockBasicOsd { latitude: number, longitude: number, height: number, - alternate_land_point: { + alternate_land_point?: { latitude: number, longitude: number, height: number, @@ -293,14 +333,14 @@ export interface DockBasicOsd { is_configured: number } first_power_on: number, - positionState: { + positionState?: { gps_number: number, is_fixed: number, rtk_number: number, is_calibration: number, quality: number, }, - storage: { + storage?: { total: number, used: number, }, @@ -308,25 +348,32 @@ export interface DockBasicOsd { cover_state: number, supplement_light_state: number, emergency_stop_state: number, - air_conditioner: { + air_conditioner?: { air_conditioner_state: number, switch_time: number, } battery_store_mode?: BatteryStoreModeEnum; // 电池保养(存储)模式 alarm_state?: AlarmModeEnum; // 机场声光报警状态 putter_state: number, - sub_device: { + sub_device?: { device_sn?: string, device_model_key?: string, device_online_status: number, device_paired: number, }, + // live_capacity?: LiveCapacity; // 直播能力 + // live_status?: Array; // 直播状态 +} +export enum DrcStateEnum { + DISCONNECT = 0, + CONNECTING = 1, + CONNECTED = 2 } - export interface DockLinkOsd { + drc_state: DrcStateEnum, flighttask_prepare_capacity: number, flighttask_step_code: number, - media_file_detail: { + media_file_detail?: { remain_upload: number }, sdr: { @@ -334,7 +381,7 @@ export interface DockLinkOsd { down_quality: string, frequency_band: number, }, - wireless_link?:{ + wireless_link?:{ // 图传链路<会包括4G和sdr信息 dongle_number: number, // dongle 数量 ['4g_link_state']: FourGLinkStateEnum, // 4g_link_state sdr_link_state: SdrLinkStateEnum, // sdr链路连接状态 @@ -359,13 +406,13 @@ export interface DockWorkOsd { job_number: number, acc_time: number, activation_time: number, - maintain_status: { + maintain_status?: { maintain_status_array: MaintainStatus[] } electric_supply_voltage: number, working_voltage: string, working_current: string, - backup_battery: { + backup_battery?: { voltage: number, temperature: number, switch: number, @@ -379,7 +426,7 @@ export interface DockWorkOsd { export interface DockOsd { basic_osd: DockBasicOsd, link_osd: DockLinkOsd, - work_osd: DockWorkOsd + work_osd: DockWorkOsd } export enum EModeCode { @@ -460,7 +507,7 @@ export interface DeviceHms { } // TODO: 设备拓扑管理优化 -// 设备信息 +// 设备osd信息 export interface DeviceInfoType { gateway: GatewayOsd, // 遥控器 dock: DockOsd, // 机场 diff --git a/src/types/drc.ts b/src/types/drc.ts new file mode 100644 index 0000000..e31b55f --- /dev/null +++ b/src/types/drc.ts @@ -0,0 +1,71 @@ +export enum DRC_METHOD { + HEART_BEAT = 'heart_beat', + DRONE_CONTROL = 'drone_control', // 飞行控制-虚拟摇杆 + DRONE_EMERGENCY_STOP = 'drone_emergency_stop', // 急停 + OSD_INFO_PUSH = 'osd_info_push', // 高频osd信息上报 + HSI_INFO_PUSH = 'hsi_info_push', // 避障信息上报 + DELAY_TIME_INFO_PUSH = 'delay_info_push', // 图传链路延时信息上报 +} + +// 手动控制 +export interface DroneControlProtocol { + x?: number; // 水平方向速度,正值为A指令 负值为D指令 单位:m/s + y?: number; // 前进后退方向速度,正值为W指令 负值为S指令 单位:m/s + h?: number;// 上下高度值,正值为上升指令 负值为下降指令 单位:m + w?: number; // 机头角速度,正值为顺时针,负值为逆时针 单位:degree/s (web端暂无此设计) + step_x?: number; // 水平方向步长 + step_y?: number; // 前后方向步长 + step_h?: number; // 高度方向步长 + step_w?: number; // 机头转向步长 + seq?: number; // 从0计时 + freq?: number; // 指令发送频率 + delay_time?: number; // 指令从发送到设备端接收可容忍的时间 发送频率+链路传输时长 +} + +// 低延时osd +export interface DRCOsdInfo { + attitude_head: number;// 飞机姿态head角,单位:度 + latitude: number;// 飞机经纬度 + longitude: number; + altitude: number; + speed_x: number; + speed_y: number; + speed_z: number; + gimbal_pitch: number;// 云台pitch角 + gimbal_roll: number;// 云台roll角 + gimbal_yaw: number;// 云台yaw角 +} + +// 态势感知-HSI +export interface DRCHsiInfo { + up_distance: number;// 上方的障碍物距离,单位:mm + down_distance: number;// 下方的障碍物距离,单位:mm + around_distances: number[]; // 水平方向观察点,分布在[0,360)区间,表示障碍物与飞机距离,单位为mm。 0对应机头方向正前方,顺时针分布,例如0度为机头正前方,90度为飞机正右方 + up_enable: boolean; // 上视避障开关状态,true:已开启 false:已关闭 + up_work: boolean; // 上视避障工作状态,true:正常工作 false:异常或离线 + down_enable: boolean; // 下视避障开关状态,true:已开启 false:已关闭 + down_work: boolean; // 下视避障工作状态,true:正常工作 false:异常或离线 + left_enable: boolean; // 左视避障开关状态,true:已开启 false:已关闭 + left_work: boolean; // 左视避障工作状态,true:正常工作 false:异常或离线 + right_enable: boolean; // 右视避障开关状态,true:已开启 false:已关闭 + right_work: boolean; // 右视避障工作状态,true:正常工作 false:异常或离线 + front_enable: boolean; // 前视避障开关状态,true:已开启 false:已关闭 + front_work: boolean; // 前视避障工作状态,true:正常工作 false:异常或离线 + back_enable: boolean; // 后视避障开关状态,true:已开启 false:已关闭 + back_work: boolean; // 后视避障工作状态,true:正常工作 false:异常或离线 + vertical_enable: boolean; // 垂直方向综合开关状态,当本协议中上、下视开关状态均为true时,输出true:已开启,否则输出false:已关闭 + vertical_work: boolean; // 垂直方向避障工作状态,当本协议中上、下视工作均为true时,输出true:正常工作,否则输出false:异常或离线 + horizontal_enable: boolean; // 水平方向综合开关状态,当本协议中前、后、左、右、开关状态均为true时,输出true:已开启,否则输出false:已关闭 + horizontal_work: boolean; // 水平方向避障工作综合状态,当本协议中前、后、左、右视工作均为true时,输出true:正常工作,否则输出false:异常或离线 +} + +export interface LiveViewDelayItem { + video_id: string; + liveview_delay_time: number; +} + +// 链路时延信息 +export interface DRCDelayTimeInfo { + sdr_cmd_delay: number; // sdr链路命令延时,单位:ms + liveview_delay_list: LiveViewDelayItem[]; +} diff --git a/src/types/drone-control.ts b/src/types/drone-control.ts new file mode 100644 index 0000000..4c16619 --- /dev/null +++ b/src/types/drone-control.ts @@ -0,0 +1,68 @@ +import { ControlSource } from './device' +import { LostControlActionInCommandFLight, WaylineLostControlActionInCommandFlight } from '/@/api/drone-control/drone' + +export enum ControlSourceChangeType { + Flight = 1, + Payload = 2, +} + +// 控制权变化消息 +export interface ControlSourceChangeInfo { + sn: string, + type: ControlSourceChangeType, + control_source: ControlSource +} + +// 飞向目标点结果 +export interface FlyToPointMessage { + sn: string, + result: number, + message: string, +} + +// 一键起飞结果 +export interface TakeoffToPointMessage { + sn: string, + result: number, + message: string, +} + +// 设备端退出drc模式 +export interface DrcModeExitNotifyMessage { + sn: string, + result: number, + message: string, +} + +// 飞行控制模式状态 +export interface DrcStatusNotifyMessage { + sn: string, + result: number, + message: string, +} + +export const WaylineLostControlActionInCommandFlightOptions = [ + { label: 'Continue', value: WaylineLostControlActionInCommandFlight.CONTINUE }, + { label: 'Execute Lost Action', value: WaylineLostControlActionInCommandFlight.EXEC_LOST_ACTION } +] + +export const LostControlActionInCommandFLightOptions = [ + { label: 'Return Home', value: LostControlActionInCommandFLight.RETURN_HOME }, + { label: 'Hover', value: LostControlActionInCommandFLight.HOVER }, + { label: 'Landing', value: LostControlActionInCommandFLight.Land } +] + +// 云台重置模式 +export enum GimbalResetMode { + Recenter = 0, + Down = 1, + RecenterGimbalPan = 2, + PitchDown = 3, +} + +export const GimbalResetModeOptions = [ + { label: 'Gimbal Recenter', value: GimbalResetMode.Recenter }, + { label: 'Gimbal down', value: GimbalResetMode.Down }, + { label: 'Recenter Gimbal Pan', value: GimbalResetMode.RecenterGimbalPan }, + { label: 'Gimbal Pitch Down', value: GimbalResetMode.PitchDown } +] diff --git a/src/types/enums.ts b/src/types/enums.ts index 9dc6365..43248fa 100644 --- a/src/types/enums.ts +++ b/src/types/enums.ts @@ -115,7 +115,14 @@ export enum EBizCode { DeviceUpgrade = 'ota_progress', // 设备升级 // 设备日志 - DeviceLogUploadProgress = 'fileupload_progress' // 设备日志上传上传 + DeviceLogUploadProgress = 'fileupload_progress', // 设备日志上传 + + // 飞行指令消息 + ControlSourceChange = 'control_source_change', // 控制权更新 + FlyToPointProgress = 'fly_to_point_progress', // 飞向目标点 + TakeoffToPointProgress = 'takeoff_to_point_progress', // 一键起飞 + JoystickInvalidNotify = 'joystick_invalid_notify', // 设备端退出drc模式 + DrcStatusNotify = 'drc_status_notify', // 飞行控制模式状态 } export enum EDeviceTypeName { diff --git a/src/types/live-stream.ts b/src/types/live-stream.ts index 2103910..4a02799 100644 --- a/src/types/live-stream.ts +++ b/src/types/live-stream.ts @@ -53,3 +53,74 @@ export enum ELiveTypeName { RTSP = 'RTSP', GB28181 = 'GB28181' } + +export enum CameraMode { + Photo = 0, // 拍照 + Video = 1, // 录像 +} + +// 镜头类型 +export enum VideoType { + NORMAL = 'normal', + WIDE = 'wide', + ZOOM = 'zoom', + IR = 'ir' +} + +// 镜头类型 +export enum CameraType { + WIDE = 'wide', + ZOOM = 'zoom', + IR = 'ir' +} + +export const CameraTypeOptions = [ + { label: CameraType.WIDE, value: CameraType.WIDE }, + { label: CameraType.ZOOM, value: CameraType.ZOOM }, + { label: CameraType.IR, value: CameraType.IR }, +] + +export const ZoomCameraTypeOptions = [ + { label: CameraType.ZOOM, value: CameraType.ZOOM }, + { label: CameraType.IR, value: CameraType.IR }, +] + +export interface VideoListItem { + video_index: string; + video_type: VideoType; + switchable_video_types?: Array; +} + +export interface CameraListItem { + available_video_number: number; + camera_index: string; + camera_name: string; + coexist_video_number_max: number; + video_list: VideoListItem[]; + // 自定义 + switchCamera?: boolean; + content?: string; + // 该camera由哪个控上报的 + camera_carrier_sns?: string[]; +} + +export interface DeviceListItem { + sn: string; + available_video_number: number; + coexist_video_number_max: number; + camera_list: CameraListItem[]; +} + +// export interface LiveCapacity { +// available_video_number: number; +// coexist_video_number_max: number; +// device_list: DeviceListItem[]; +// } + +// export interface LiveStatus { +// live_time: number; // 直播时间 该路码流已推流时间 unit: s +// live_trendline: number; // 直播带宽的使用状态 代表直播性能趋势,0-4表示overuse,其中,数值越小,表示overuse程度越大,5表示normal状态,6~10表示underuse,其中,数值越大,表示有更多比例的带宽未能充分利用 +// video_id: string; // 直播码流标识符 某路在推视频码流的标识符,格式为 #{uav_sn}/#{camera_id}/#{video_index} +// video_quality: number; // 直播码流的质量 0: 自动, 1: 流畅, 2: 高清, 3: 超清 +// error_status?: number; // 设备端当前状态,是错误码,需要匹配到文案上 +// } diff --git a/src/types/task.ts b/src/types/task.ts index cd5d97a..a37fe73 100644 --- a/src/types/task.ts +++ b/src/types/task.ts @@ -37,6 +37,7 @@ export enum TaskStatus { Success = 3, // 完成 CanCel = 4, // 取消 Fail = 5, // 失败 + Paused = 6, // 暂停 } export const TaskStatusMap = { @@ -45,6 +46,8 @@ export const TaskStatusMap = { [TaskStatus.Success]: 'Task completed', [TaskStatus.CanCel]: 'Task canceled', [TaskStatus.Fail]: 'Task failed', + [TaskStatus.Paused]: 'Paused', + } export const TaskStatusColor = { @@ -53,6 +56,7 @@ export const TaskStatusColor = { [TaskStatus.Success]: commonColor.NORMAL, [TaskStatus.CanCel]: commonColor.FAIL, [TaskStatus.Fail]: commonColor.FAIL, + [TaskStatus.Paused]: commonColor.BLUE, } // 任务执行 ws 消息状态 @@ -93,7 +97,7 @@ export const TaskProgressWsStatusMap = { [TaskProgressStatus.Failed]: TaskStatus.Fail, [TaskProgressStatus.Canceled]: TaskStatus.CanCel, [TaskProgressStatus.Timeout]: TaskStatus.Fail, - [TaskProgressStatus.Paused]: TaskStatus.Wait, + [TaskProgressStatus.Paused]: TaskStatus.Paused, } // 根据媒体文件上传进度信息,前端自己判断出的状态 diff --git a/yarn.lock b/yarn.lock index 9a9d2c5..5d27955 100644 --- a/yarn.lock +++ b/yarn.lock @@ -819,6 +819,11 @@ "mixin-deep" "^1.2.0" "pascalcase" "^0.1.1" +"base64-js@^1.3.1": + "integrity" "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + "resolved" "https://registry.npmmirror.com/base64-js/-/base64-js-1.5.1.tgz" + "version" "1.5.1" + "big-integer@^1.6.17": "integrity" "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==" "resolved" "https://registry.npmmirror.com/big-integer/download/big-integer-1.6.51.tgz" @@ -842,6 +847,15 @@ "buffers" "~0.1.1" "chainsaw" "~0.1.0" +"bl@^4.0.2": + "integrity" "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==" + "resolved" "https://registry.npmmirror.com/bl/-/bl-4.1.0.tgz" + "version" "4.1.0" + dependencies: + "buffer" "^5.5.0" + "inherits" "^2.0.4" + "readable-stream" "^3.4.0" + "bluebird@^3.5.0": "integrity" "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=" "resolved" "https://registry.npm.taobao.org/bluebird/download/bluebird-3.7.2.tgz" @@ -899,11 +913,24 @@ "node-releases" "^2.0.1" "picocolors" "^1.0.0" +"buffer-from@^1.0.0": + "integrity" "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" + "resolved" "https://registry.npmmirror.com/buffer-from/-/buffer-from-1.1.2.tgz" + "version" "1.1.2" + "buffer-indexof-polyfill@~1.0.0": "integrity" "sha1-0nMhNcWZnGSyd/z5savjSYJUcpw=" "resolved" "https://registry.npm.taobao.org/buffer-indexof-polyfill/download/buffer-indexof-polyfill-1.0.2.tgz" "version" "1.0.2" +"buffer@^5.5.0": + "integrity" "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==" + "resolved" "https://registry.npmmirror.com/buffer/-/buffer-5.7.1.tgz" + "version" "5.7.1" + dependencies: + "base64-js" "^1.3.1" + "ieee754" "^1.1.13" + "buffers@~0.1.1": "integrity" "sha1-skV5w77U1tOWru5tmorn9Ugqt7s=" "resolved" "https://registry.npm.taobao.org/buffers/download/buffers-0.1.1.tgz" @@ -1079,6 +1106,14 @@ "resolved" "https://registry.npmmirror.com/commander/download/commander-7.2.0.tgz" "version" "7.2.0" +"commist@^1.0.0": + "integrity" "sha512-rraC8NXWOEjhADbZe9QBNzLAN5Q3fsTPQtBV+fEVj6xKIgDgNiEVE6ZNfHpZOqfQ21YUzfVNUXLOEZquYvQPPg==" + "resolved" "https://registry.npmmirror.com/commist/-/commist-1.1.0.tgz" + "version" "1.1.0" + dependencies: + "leven" "^2.1.0" + "minimist" "^1.1.0" + "component-emitter@^1.2.1": "integrity" "sha1-FuQHD7qK4ptnnyIVhT7hgasuq8A=" "resolved" "https://registry.npm.taobao.org/component-emitter/download/component-emitter-1.3.0.tgz" @@ -1094,6 +1129,16 @@ "resolved" "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz" "version" "0.0.1" +"concat-stream@^2.0.0": + "integrity" "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==" + "resolved" "https://registry.npmmirror.com/concat-stream/-/concat-stream-2.0.0.tgz" + "version" "2.0.0" + dependencies: + "buffer-from" "^1.0.0" + "inherits" "^2.0.3" + "readable-stream" "^3.0.2" + "typedarray" "^0.0.6" + "constant-case@^3.0.4": "integrity" "sha1-O4Sprq9M8x7EXmv13pG9+wWJ+vE=" "resolved" "https://registry.npm.taobao.org/constant-case/download/constant-case-3.0.4.tgz?cache=0&sync_timestamp=1606867325763&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fconstant-case%2Fdownload%2Fconstant-case-3.0.4.tgz" @@ -1216,7 +1261,7 @@ dependencies: "ms" "^2.1.1" -"debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.2", "debug@^4.3.3": +"debug@^4.0.1", "debug@^4.1.0", "debug@^4.1.1", "debug@^4.3.1", "debug@^4.3.2", "debug@^4.3.3": "integrity" "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==" "resolved" "https://registry.npmmirror.com/debug/download/debug-4.3.3.tgz" "version" "4.3.3" @@ -1366,6 +1411,16 @@ dependencies: "readable-stream" "^2.0.2" +"duplexify@^4.1.1": + "integrity" "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==" + "resolved" "https://registry.npmmirror.com/duplexify/-/duplexify-4.1.2.tgz" + "version" "4.1.2" + dependencies: + "end-of-stream" "^1.4.1" + "inherits" "^2.0.3" + "readable-stream" "^3.1.1" + "stream-shift" "^1.0.0" + "electron-to-chromium@^1.4.17": "integrity" "sha512-PO3kEfcxPrti/4STbXvCkNIF4fgWvCKl2508e6UI7KomCDffpIfeBZLXsh5DK/XGsjUw3kwq6WEsi0MJTlGAdg==" "resolved" "https://registry.npmmirror.com/electron-to-chromium/download/electron-to-chromium-1.4.43.tgz" @@ -1381,6 +1436,13 @@ "resolved" "https://registry.npm.taobao.org/emojis-list/download/emojis-list-3.0.0.tgz" "version" "3.0.0" +"end-of-stream@^1.1.0", "end-of-stream@^1.4.1": + "integrity" "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==" + "resolved" "https://registry.npmmirror.com/end-of-stream/-/end-of-stream-1.4.4.tgz" + "version" "1.4.4" + dependencies: + "once" "^1.4.0" + "enquirer@^2.3.5": "integrity" "sha1-Kn/l3WNKHkElqXXsmU/1RW3Dc00=" "resolved" "https://registry.npm.taobao.org/enquirer/download/enquirer-2.3.6.tgz" @@ -1728,6 +1790,11 @@ "resolved" "https://registry.npm.taobao.org/etag/download/etag-1.8.1.tgz" "version" "1.8.1" +"eventemitter3@^5.0.0": + "integrity" "sha512-riuVbElZZNXLeLEoprfNYoDSwTBRR44X3mnhdI1YcnENpWTCsTTVZ2zFuqQcpoyqPQIUXdiPEU0ECAq0KQRaHg==" + "resolved" "https://registry.npmmirror.com/eventemitter3/-/eventemitter3-5.0.0.tgz" + "version" "5.0.0" + "expand-brackets@^2.1.4": "integrity" "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=" "resolved" "https://registry.npm.taobao.org/expand-brackets/download/expand-brackets-2.1.4.tgz" @@ -1950,7 +2017,7 @@ dependencies: "is-glob" "^4.0.1" -"glob@^7.1.3": +"glob@^7.1.3", "glob@^7.1.6": "integrity" "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==" "resolved" "https://registry.npmmirror.com/glob/download/glob-7.2.0.tgz" "version" "7.2.0" @@ -2081,6 +2148,14 @@ "capital-case" "^1.0.4" "tslib" "^2.0.3" +"help-me@^3.0.0": + "integrity" "sha512-hx73jClhyk910sidBB7ERlnhMlFsJJIBqSVMFDwPN8o2v9nmp5KgLq1Xz1Bf1fCMMZ6mPrX159iG0VLy/fPMtQ==" + "resolved" "https://registry.npmmirror.com/help-me/-/help-me-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "glob" "^7.1.6" + "readable-stream" "^3.6.0" + "htmlparser2@^3.8.3": "integrity" "sha1-vWedw/WYl7ajS7EHSchVu1OpOS8=" "resolved" "https://registry.npmmirror.com/htmlparser2/download/htmlparser2-3.10.1.tgz?cache=0&sync_timestamp=1636640933377&other_urls=https%3A%2F%2Fregistry.npmmirror.com%2Fhtmlparser2%2Fdownload%2Fhtmlparser2-3.10.1.tgz" @@ -2093,6 +2168,11 @@ "inherits" "^2.0.1" "readable-stream" "^3.1.1" +"ieee754@^1.1.13": + "integrity" "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "resolved" "https://registry.npmmirror.com/ieee754/-/ieee754-1.2.1.tgz" + "version" "1.2.1" + "ignore@^4.0.6": "integrity" "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" "resolved" "https://registry.npmmirror.com/ignore/download/ignore-4.0.6.tgz" @@ -2134,7 +2214,7 @@ "once" "^1.3.0" "wrappy" "1" -"inherits@^2.0.1", "inherits@^2.0.3", "inherits@~2.0.0", "inherits@~2.0.3", "inherits@2": +"inherits@^2.0.1", "inherits@^2.0.3", "inherits@^2.0.4", "inherits@~2.0.0", "inherits@~2.0.3", "inherits@2": "integrity" "sha1-D6LGT5MpF8NDOg3tVTY6rjdBa3w=" "resolved" "https://registry.npm.taobao.org/inherits/download/inherits-2.0.4.tgz" "version" "2.0.4" @@ -2402,6 +2482,11 @@ "resolved" "https://registry.npmmirror.com/js-base64/download/js-base64-2.6.4.tgz" "version" "2.6.4" +"js-sdsl@4.3.0": + "integrity" "sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==" + "resolved" "https://registry.npmmirror.com/js-sdsl/-/js-sdsl-4.3.0.tgz" + "version" "4.3.0" + "js-tokens@^3.0.0 || ^4.0.0", "js-tokens@^4.0.0": "integrity" "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=" "resolved" "https://registry.nlark.com/js-tokens/download/js-tokens-4.0.0.tgz?cache=0&sync_timestamp=1619345098261&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fjs-tokens%2Fdownload%2Fjs-tokens-4.0.0.tgz" @@ -2494,6 +2579,11 @@ "resolved" "https://registry.npm.taobao.org/kind-of/download/kind-of-6.0.3.tgz" "version" "6.0.3" +"leven@^2.1.0": + "integrity" "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==" + "resolved" "https://registry.npmmirror.com/leven/-/leven-2.1.0.tgz" + "version" "2.1.0" + "levn@^0.4.1": "integrity" "sha1-rkViwAdHO5MqYgDUAyaN0v/8at4=" "resolved" "https://registry.npm.taobao.org/levn/download/levn-0.4.1.tgz" @@ -2635,7 +2725,7 @@ dependencies: "brace-expansion" "^1.1.7" -"minimist@^1.2.0", "minimist@^1.2.5": +"minimist@^1.1.0", "minimist@^1.2.0", "minimist@^1.2.5": "integrity" "sha1-Z9ZgFLZqaoqqDAg8X9WN9OTpdgI=" "resolved" "https://registry.npm.taobao.org/minimist/download/minimist-1.2.5.tgz" "version" "1.2.5" @@ -2665,6 +2755,38 @@ "resolved" "https://registry.npmmirror.com/moment/download/moment-2.29.1.tgz" "version" "2.29.1" +"mqtt-packet@^6.8.0": + "integrity" "sha512-ja8+mFKIHdB1Tpl6vac+sktqy3gA8t9Mduom1BA75cI+R9AHnZOiaBQwpGiWnaVJLDGRdNhQmFaAqd7tkKSMGA==" + "resolved" "https://registry.npmmirror.com/mqtt-packet/-/mqtt-packet-6.10.0.tgz" + "version" "6.10.0" + dependencies: + "bl" "^4.0.2" + "debug" "^4.1.1" + "process-nextick-args" "^2.0.1" + +"mqtt@^4.3.7": + "integrity" "sha512-ew3qwG/TJRorTz47eW46vZ5oBw5MEYbQZVaEji44j5lAUSQSqIEoul7Kua/BatBW0H0kKQcC9kwUHa1qzaWHSw==" + "resolved" "https://registry.npmmirror.com/mqtt/-/mqtt-4.3.7.tgz" + "version" "4.3.7" + dependencies: + "commist" "^1.0.0" + "concat-stream" "^2.0.0" + "debug" "^4.1.1" + "duplexify" "^4.1.1" + "help-me" "^3.0.0" + "inherits" "^2.0.3" + "lru-cache" "^6.0.0" + "minimist" "^1.2.5" + "mqtt-packet" "^6.8.0" + "number-allocator" "^1.0.9" + "pump" "^3.0.0" + "readable-stream" "^3.6.0" + "reinterval" "^1.1.0" + "rfdc" "^1.3.0" + "split2" "^3.1.0" + "ws" "^7.5.5" + "xtend" "^4.0.2" + "ms@^2.1.1", "ms@2.1.2": "integrity" "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk=" "resolved" "https://registry.npmmirror.com/ms/download/ms-2.1.2.tgz" @@ -2737,6 +2859,14 @@ dependencies: "boolbase" "^1.0.0" +"number-allocator@^1.0.9": + "integrity" "sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==" + "resolved" "https://registry.npmmirror.com/number-allocator/-/number-allocator-1.0.14.tgz" + "version" "1.0.14" + dependencies: + "debug" "^4.3.1" + "js-sdsl" "4.3.0" + "object-assign@^4", "object-assign@^4.1.0": "integrity" "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" "resolved" "https://registry.npm.taobao.org/object-assign/download/object-assign-4.1.1.tgz" @@ -2799,7 +2929,7 @@ "resolved" "https://registry.npm.taobao.org/omit.js/download/omit.js-2.0.2.tgz" "version" "2.0.2" -"once@^1.3.0": +"once@^1.3.0", "once@^1.3.1", "once@^1.4.0": "integrity" "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=" "resolved" "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz" "version" "1.4.0" @@ -2980,7 +3110,7 @@ "resolved" "https://registry.npm.taobao.org/prelude-ls/download/prelude-ls-1.2.1.tgz" "version" "1.2.1" -"process-nextick-args@~2.0.0": +"process-nextick-args@^2.0.1", "process-nextick-args@~2.0.0": "integrity" "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=" "resolved" "https://registry.npm.taobao.org/process-nextick-args/download/process-nextick-args-2.0.1.tgz" "version" "2.0.1" @@ -2990,6 +3120,14 @@ "resolved" "https://registry.npmmirror.com/progress/download/progress-2.0.3.tgz" "version" "2.0.3" +"pump@^3.0.0": + "integrity" "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==" + "resolved" "https://registry.npmmirror.com/pump/-/pump-3.0.0.tgz" + "version" "3.0.0" + dependencies: + "end-of-stream" "^1.1.0" + "once" "^1.3.1" + "punycode@^2.1.0": "integrity" "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=" "resolved" "https://registry.npm.taobao.org/punycode/download/punycode-2.1.1.tgz" @@ -3031,7 +3169,7 @@ "string_decoder" "~1.1.1" "util-deprecate" "~1.0.1" -"readable-stream@^3.1.1": +"readable-stream@^3.0.0", "readable-stream@^3.0.2", "readable-stream@^3.1.1", "readable-stream@^3.4.0", "readable-stream@^3.6.0": "integrity" "sha1-M3u9o63AcGvT4CRCaihtS0sskZg=" "resolved" "https://registry.npm.taobao.org/readable-stream/download/readable-stream-3.6.0.tgz" "version" "3.6.0" @@ -3083,6 +3221,11 @@ "resolved" "https://registry.nlark.com/regexpp/download/regexpp-3.2.0.tgz" "version" "3.2.0" +"reinterval@^1.1.0": + "integrity" "sha512-QIRet3SYrGp0HUHO88jVskiG6seqUGC5iAG7AwI/BV4ypGcuqk9Du6YQBUOUqm9c8pw1eyLoIaONifRua1lsEQ==" + "resolved" "https://registry.npmmirror.com/reinterval/-/reinterval-1.1.0.tgz" + "version" "1.1.0" + "repeat-element@^1.1.2": "integrity" "sha1-vmgVIIR6tYx1aKx1+/rSjtQtOek=" "resolved" "https://registry.nlark.com/repeat-element/download/repeat-element-1.1.4.tgz" @@ -3132,6 +3275,11 @@ "resolved" "https://registry.npm.taobao.org/reusify/download/reusify-1.0.4.tgz" "version" "1.0.4" +"rfdc@^1.3.0": + "integrity" "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + "resolved" "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz" + "version" "1.3.0" + "rimraf@^3.0.2": "integrity" "sha1-8aVAK6YiCtUswSgrrBrjqkn9Bho=" "resolved" "https://registry.npmmirror.com/rimraf/download/rimraf-3.0.2.tgz" @@ -3375,6 +3523,13 @@ dependencies: "extend-shallow" "^3.0.0" +"split2@^3.1.0": + "integrity" "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==" + "resolved" "https://registry.npmmirror.com/split2/-/split2-3.2.2.tgz" + "version" "3.2.2" + dependencies: + "readable-stream" "^3.0.0" + "sprintf-js@~1.0.2": "integrity" "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" "resolved" "https://registry.npm.taobao.org/sprintf-js/download/sprintf-js-1.0.3.tgz" @@ -3393,6 +3548,11 @@ "define-property" "^0.2.5" "object-copy" "^0.1.0" +"stream-shift@^1.0.0": + "integrity" "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==" + "resolved" "https://registry.npmmirror.com/stream-shift/-/stream-shift-1.0.1.tgz" + "version" "1.0.1" + "strict-uri-encode@^1.0.0": "integrity" "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" "resolved" "https://registry.npm.taobao.org/strict-uri-encode/download/strict-uri-encode-1.1.0.tgz" @@ -3636,6 +3796,11 @@ "resolved" "https://registry.npmmirror.com/type-fest/download/type-fest-0.20.2.tgz" "version" "0.20.2" +"typedarray@^0.0.6": + "integrity" "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==" + "resolved" "https://registry.npmmirror.com/typedarray/-/typedarray-0.0.6.tgz" + "version" "0.0.6" + "typescript@^4.5.4", "typescript@>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta": "integrity" "sha512-VgYs2A2QIRuGphtzFV7aQJduJ2gyfTljngLzjpfW9FoYZF6xuw1W0vW9ghCKLfcWrCFxK81CSGRAvS1pn4fIUg==" "resolved" "https://registry.npmmirror.com/typescript/download/typescript-4.5.4.tgz" @@ -3933,6 +4098,16 @@ "resolved" "https://registry.nlark.com/wrappy/download/wrappy-1.0.2.tgz?cache=0&sync_timestamp=1619133505879&other_urls=https%3A%2F%2Fregistry.nlark.com%2Fwrappy%2Fdownload%2Fwrappy-1.0.2.tgz" "version" "1.0.2" +"ws@^7.5.5": + "integrity" "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==" + "resolved" "https://registry.npmmirror.com/ws/-/ws-7.5.9.tgz" + "version" "7.5.9" + +"xtend@^4.0.2": + "integrity" "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==" + "resolved" "https://registry.npmmirror.com/xtend/-/xtend-4.0.2.tgz" + "version" "4.0.2" + "yallist@^4.0.0": "integrity" "sha1-m7knkNnA7/7GO+c1GeEaNQGaOnI=" "resolved" "https://registry.npm.taobao.org/yallist/download/yallist-4.0.0.tgz"