25 files modified
2 files renamed
18 files added
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "license": "MIT", |
| | | "engines": { |
| | | "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": { |
| | |
| | | "type": "opencollective", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "resolved": "https://registry.npm.taobao.org/concat-map/download/concat-map-0.0.1.tgz", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "license": "MIT", |
| | | "engines": { |
| | | "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": { |
| | |
| | | "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", |
| | |
| | | "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": { |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "inherits": "^2.0.1", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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": { |
| | |
| | | "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", |
| | |
| | | "integrity": "sha1-cpyR4thXt6QZofmqZWhcTDP1hF0=", |
| | | "dev": true, |
| | | "license": "MIT", |
| | | "engines": { |
| | | "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" |
| | | } |
| | |
| | | "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" |
| | |
| | | "license": "MIT", |
| | | "engines": { |
| | | "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": { |
| | |
| | | }, |
| | | "funding": { |
| | | "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": "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" |
| | |
| | | "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" |
| | |
| | | "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": { |
| | |
| | | "license": "MIT", |
| | | "engines": { |
| | | "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": "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", |
| | |
| | | "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", |
| | |
| | | "iojs": ">=1.0.0", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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" |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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": { |
| | |
| | | "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" |
| | | } |
| | | }, |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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", |
| | |
| | | "resolved": "https://registry.nlark.com/binary-extensions/download/binary-extensions-2.2.0.tgz", |
| | | "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", |
| | |
| | | "node-releases": "^2.0.1", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "version": "0.0.1", |
| | | "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", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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", |
| | |
| | | "resolved": "https://registry.npm.taobao.org/emojis-list/download/emojis-list-3.0.0.tgz", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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", |
| | |
| | | "inherits": "^2.0.1", |
| | | "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", |
| | |
| | | "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" |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "resolved": "https://registry.npm.taobao.org/kind-of/download/kind-of-5.1.0.tgz", |
| | | "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", |
| | |
| | | "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" |
| | | } |
| | |
| | | "version": "2.29.1", |
| | | "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", |
| | |
| | | "dev": true, |
| | | "requires": { |
| | | "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": "1.4.0", |
| | | "resolved": "https://registry.npm.taobao.org/once/download/once-1.4.0.tgz", |
| | | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", |
| | | "dev": true, |
| | | "requires": { |
| | | "wrappy": "1" |
| | | } |
| | |
| | | "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", |
| | |
| | | "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", |
| | | "resolved": "https://registry.npmmirror.com/progress/download/progress-2.0.3.tgz", |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "version": "1.0.4", |
| | | "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", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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", |
| | |
| | | } |
| | | } |
| | | }, |
| | | "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", |
| | |
| | | "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" |
| | | }, |
| | |
| | | "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=" |
| | | } |
| | | } |
| | | }, |
| | |
| | | "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", |
| | |
| | | "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", |
| | |
| | | "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=" |
| | | } |
| | | } |
| | | } |
| | |
| | | "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", |
| | |
| | | "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", |
| New file |
| | |
| | | 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<IWorkspaceResponse<DrcParams>> { |
| | | 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<IWorkspaceResponse<DrcEnterResp>> { |
| | | 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<IWorkspaceResponse<null>> { |
| | | const resp = await request.post(`${DRC_API_PREFIX}/workspaces/${workspaceId}/drc/exit`, body) |
| | | return resp.data |
| | | } |
| New file |
| | |
| | | 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<IWorkspaceResponse<null>> { |
| | | 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<IWorkspaceResponse<null>> { |
| | | const resp = await request.post(`${API_PREFIX}/devices/${sn}/jobs/fly-to-point`, body) |
| | | return resp.data |
| | | } |
| | | |
| | | // 停止飞向目标点 |
| | | export async function deleteFlyToPoint (sn: string): Promise<IWorkspaceResponse<null>> { |
| | | 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<IWorkspaceResponse<null>> { |
| | | const resp = await request.post(`${API_PREFIX}/devices/${sn}/jobs/takeoff-to-point`, body) |
| | | return resp.data |
| | | } |
| New file |
| | |
| | | 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<IWorkspaceResponse<null>> { |
| | | 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<IWorkspaceResponse<null>> { |
| | | const resp = await request.post(`${API_PREFIX}/devices/${sn}/payload/commands`, body) |
| | | return resp.data |
| | | } |
| | |
| | | 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 // 失控动作 |
| | | } |
| | |
| | | job_id: string |
| | | } |
| | | |
| | | // 取消机场任务 |
| | | // 删除机场任务 |
| | | export async function deleteTask (workspaceId: string, params: DeleteTaskParams): Promise<IWorkspaceResponse<{}>> { |
| | | const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/jobs` |
| | | const result = await request.delete(url, { |
| | |
| | | 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<IWorkspaceResponse<{}>> { |
| | | 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<IWorkspaceResponse<any>> { |
| | | const url = `${HTTP_PREFIX}/workspaces/${workspaceId}/waylines/file/upload` |
| | |
| | | <template> |
| | | <div class="g-map-wrapper"> |
| | | <!-- 地图区域 --> |
| | | <div id="g-container" :style="{ width: '100%', height: '100%' }" /> |
| | | <!-- 绘制面板 --> |
| | | <div |
| | | class="g-action-panle" |
| | | class="g-action-panel" |
| | | :style="{ right: drawVisible ? '316px' : '16px' }" |
| | | > |
| | | <div :class="state.currentType === 'pin' ? 'g-action-item selection' : 'g-action-item'" @click="draw('pin', true)"> |
| | |
| | | <a style="color: red;"><CloseOutlined /></a> |
| | | </div> |
| | | </div> |
| | | <!-- 飞机OSD --> |
| | | <div v-if="osdVisible.visible && !osdVisible.is_dock" class="osd-panel fz12"> |
| | | <div class="pl5 pr5 flex-align-center flex-row flex-justify-between" style="border-bottom: 1px solid #515151; height: 18%;"> |
| | | <span>{{ osdVisible.callsign }}</span> |
| | |
| | | </a-row> |
| | | <a-row class="p5"> |
| | | <a-col span="24"> |
| | | <a-button type="primary" :disabled="controlPanelVisible" size="small" @click="setControlPanelVisible(true)"> |
| | | 设备操作 |
| | | <a-button type="primary" :disabled="dockControlPanelVisible" size="small" @click="setDockControlPanelVisible(true)"> |
| | | Actions |
| | | </a-button> |
| | | </a-col> |
| | | </a-row> |
| | | <DockControlPanel v-if="controlPanelVisible" :sn="osdVisible.gateway_sn" :deviceInfo="deviceInfo" @close-control-panel="dockDebugOnOff"> |
| | | <!-- 机场控制面板 --> |
| | | <DockControlPanel v-if="dockControlPanelVisible" :sn="osdVisible.gateway_sn" :deviceInfo="deviceInfo" @close-control-panel="onCloseControlPanel"> |
| | | </DockControlPanel> |
| | | </div> |
| | | </div> |
| | |
| | | {{ 10 > (deviceInfo.device.battery.remain_flight_time % 60) ? '0' : ''}}{{deviceInfo.device.battery.remain_flight_time % 60 }} |
| | | </div> |
| | | </div> |
| | | |
| | | <!-- 飞行指令 --> |
| | | <DroneControlPanel :sn="osdVisible.gateway_sn" :deviceInfo="deviceInfo" :payloads="osdVisible.payloads"></DroneControlPanel> |
| | | </div> |
| | | </div> |
| | | </template> |
| | |
| | | } 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: { |
| | |
| | | ArrowUpOutlined, |
| | | ArrowDownOutlined, |
| | | DockControlPanel, |
| | | DroneControlPanel, |
| | | CarryOutOutlined, |
| | | RocketOutlined |
| | | }, |
| | |
| | | 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] |
| | | } |
| | | } |
| | | }, { |
| | |
| | | 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: |
| | |
| | | EModeCode, |
| | | str, |
| | | EDockModeCode, |
| | | controlPanelVisible, |
| | | dockDebugOnOff, |
| | | setControlPanelVisible, |
| | | dockControlPanelVisible, |
| | | setDockControlPanelVisible, |
| | | onCloseControlPanel, |
| | | NetworkStateTypeEnum, |
| | | NetworkStateQualityEnum, |
| | | RainfallEnum, |
| | |
| | | height: 100%; |
| | | width: 100%; |
| | | |
| | | .g-action-panle { |
| | | .g-action-panel { |
| | | position: absolute; |
| | | top: 16px; |
| | | right: 16px; |
| | |
| | | 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; |
| | | } |
| | |
| | | </template> |
| | | <template v-for="col in ['code', 'message']" #[col]="{ text }" :key="col"> |
| | | <a-tooltip :title="text"> |
| | | <span>{{ text }}</span> |
| | | <div >{{ text }}</div> |
| | | </a-tooltip> |
| | | </template> |
| | | <template #domain="{text}"> |
| | | <a-tooltip :title="EDeviceTypeName[text]"> |
| | | <div >{{ EDeviceTypeName[text] }}</div> |
| | | </a-tooltip> |
| | | </template> |
| | | </a-table> |
| | |
| | | |
| | | <!-- 暂时只抽取该组件 --> |
| | | <script lang="ts" setup> |
| | | import { watchEffect, reactive, ref, defineProps, defineEmits } from 'vue' |
| | | import { watchEffect, reactive, ref, defineProps, defineEmits, watch } from 'vue' |
| | | import { getDeviceHms, HmsQueryBody } from '/@/api/manage' |
| | | import moment, { Moment } from 'moment' |
| | | import { ColumnProps, TableState } from 'ant-design-vue/lib/table/interface' |
| | |
| | | // 健康状态 |
| | | const sVisible = ref(false) |
| | | |
| | | watchEffect(() => { |
| | | watch(props, () => { |
| | | sVisible.value = props.visible |
| | | // 显示弹框时,获取设备hms信息 |
| | | if (props.visible) { |
| | |
| | | const hmsColumns: ColumnProps[] = [ |
| | | { title: 'Alarm Begin | End Time', dataIndex: 'create_time', width: '25%', className: 'titleStyle', slots: { customRender: 'time' } }, |
| | | { title: 'Level', dataIndex: 'level', width: '120px', className: 'titleStyle', slots: { customRender: 'level' } }, |
| | | { title: 'Device', dataIndex: 'domain', width: '12%', className: 'titleStyle' }, |
| | | { title: 'Error Code', dataIndex: 'key', width: '20%', className: 'titleStyle', slots: { customRender: 'code' } }, |
| | | { title: 'Device', dataIndex: 'domain', width: '12%', className: 'titleStyle', slots: { customRender: 'domain' } }, |
| | | { title: 'Error Code', dataIndex: 'key', width: '20%', className: 'titleStyle', ellipsis: true, slots: { customRender: 'code' } }, |
| | | { title: 'Hms Message', dataIndex: 'message_en', className: 'titleStyle', ellipsis: true, slots: { customRender: 'message' } }, |
| | | { title: 'Hms Message', dataIndex: 'message_zh', className: 'titleStyle', ellipsis: true, slots: { customRender: 'message' } }, |
| | | ] |
| | | |
| | | interface DeviceHmsData { |
| | |
| | | </span> |
| | | <!-- 进度 --> |
| | | <span v-if="device.firmware_status === DeviceFirmwareStatusEnum.DuringUpgrade"> |
| | | {{ `${device.firmware_progress}%`}} |
| | | {{ `${device.firmware_progress}`}} |
| | | </span> |
| | | </div> |
| | | </template> |
| | |
| | | <template> |
| | | <div class="device-setting-wrapper"> |
| | | <div class="device-setting-header">设备属性设置</div> |
| | | <div class="device-setting-header">Device Property Set</div> |
| | | <div class="device-setting-box"> |
| | | <!-- 飞行器夜航灯 --> |
| | | <div class="control-setting-item"> |
| | |
| | | import { cloneDeep } from 'lodash' |
| | | import { initDeviceSetting, initDeviceSettingFormModel, DeviceSettingKeyEnum } from '/@/types/device-setting' |
| | | import { updateDeviceSettingInfoByOsd, updateDeviceSettingFormModelByOsd } from '/@/utils/device-setting' |
| | | import { useDeviceSetting } from './useDeviceSetting' |
| | | import { useDeviceSetting } from './use-device-setting' |
| | | import DeviceSettingPopover from './DeviceSettingPopover.vue' |
| | | |
| | | const props = defineProps<{ |
| | |
| | | <div class="dock-control-panel"> |
| | | <!-- title --> |
| | | <div class="dock-control-panel-header fz16 pl5 pr5 flex-align-center flex-row flex-justify-between"> |
| | | <span>设备操作 {{ props.sn}}</span> |
| | | <span>Device Control<span class="fz12 pl15">{{ props.sn}}</span></span> |
| | | <span @click="closeControlPanel"> |
| | | <CloseOutlined /> |
| | | </span> |
| | |
| | | <!-- cmd --> |
| | | <div class="control-cmd-wrapper"> |
| | | <div class="control-cmd-header"> |
| | | 远程调试 |
| | | Device Remote Debug |
| | | <a-switch class="debug-btn" checked-children="开" un-checked-children="关" v-model:checked="debugStatus" @change="onDeviceStatusChange"/> |
| | | </div> |
| | | <div class="control-cmd-box"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | |
| | | </template> |
| | |
| | | import { |
| | | CloseOutlined |
| | | } from '@ant-design/icons-vue' |
| | | import { useDockControl } from './useDockControl' |
| | | import { useDockControl } from './use-dock-control' |
| | | import { DeviceInfoType, EDockModeCode } from '/@/types/device' |
| | | import { cmdList as baseCmdList, DeviceCmdItem } from '/@/types/device-cmd' |
| | | import { useMyStore } from '/@/store' |
| | |
| | | const emit = defineEmits(['close-control-panel']) |
| | | |
| | | function closeControlPanel () { |
| | | emit('close-control-panel', props.sn, false) |
| | | emit('close-control-panel', props.sn) |
| | | } |
| | | |
| | | // dock 控制指令 |
| New file |
| | |
| | | <template> |
| | | <div class="drone-control-info-wrap"> |
| | | <a-textarea v-model:value="info" placeholder="drc info" :rows="5" disabled/> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { ref, defineProps, watch } from 'vue' |
| | | |
| | | const props = defineProps<{ |
| | | message?: string, |
| | | }>() |
| | | |
| | | const info = ref('') |
| | | watch(() => props.message, message => { |
| | | info.value = message || '' |
| | | }, { |
| | | immediate: true |
| | | }) |
| | | |
| | | // const emit = defineEmits(['cancel', 'confirm']) |
| | | </script> |
| | | |
| | | <style lang="scss" scoped> |
| | | .drone-control-info-wrap { |
| | | &::v-deep{ |
| | | textarea.ant-input { |
| | | background-color: #000; |
| | | color: #fff; |
| | | white-space: pre-wrap; |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <div class="drone-control-wrapper"> |
| | | <div class="drone-control-header">Drone Flight Control</div> |
| | | <div class="drone-control-box"> |
| | | <div class="box"> |
| | | <div class="row"> |
| | | <div class="drone-control"><Button :ghost="!flightController" size="small" @click="onClickFightControl">{{ flightController ? 'Exit Remote Control' : 'Enter Remote Control'}}</Button></div> |
| | | </div> |
| | | <div class="row"> |
| | | <div class="drone-control-direction"> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_Q)" @onmouseup="onMouseUp"> |
| | | <template #icon><UndoOutlined /></template><span class="word">Q</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_W)" @onmouseup="onMouseUp"> |
| | | <template #icon><UpOutlined/></template><span class="word">W</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_E)" @onmouseup="onMouseUp"> |
| | | <template #icon><RedoOutlined /></template><span class="word">E</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_UP)" @onmouseup="onMouseUp"> |
| | | <template #icon><ArrowUpOutlined /></template> |
| | | </Button> |
| | | <br /> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_A)" @onmouseup="onMouseUp"> |
| | | <template #icon><LeftOutlined/></template><span class="word">A</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_S)" @onmouseup="onMouseUp"> |
| | | <template #icon><DownOutlined/></template><span class="word">S</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.KEY_D)" @onmouseup="onMouseUp"> |
| | | <template #icon><RightOutlined/></template><span class="word">D</span> |
| | | </Button> |
| | | <Button size="small" ghost @mousedown="onMouseDown(KeyCode.ARROW_DOWN)" @onmouseup="onMouseUp"> |
| | | <template #icon><ArrowDownOutlined /></template> |
| | | </Button> |
| | | </div> |
| | | <Button type="primary" size="small" danger ghost @click="handleEmergencyStop" > |
| | | <template #icon><PauseCircleOutlined/></template><span>Break</span> |
| | | </Button> |
| | | </div> |
| | | <div class="row"> |
| | | <DroneControlPopover |
| | | :visible="flyToPointPopoverData.visible" |
| | | :loading="flyToPointPopoverData.loading" |
| | | @confirm="($event) => onFlyToConfirm(true)" |
| | | @cancel="($event) =>onFlyToConfirm(false)" |
| | | > |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <div> |
| | | <span class="form-label">latitude:</span> |
| | | <a-input-number v-model:value="flyToPointPopoverData.latitude"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">longitude:</span> |
| | | <a-input-number v-model:value="flyToPointPopoverData.longitude"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">height(m):</span> |
| | | <a-input-number v-model:value="flyToPointPopoverData.height"/> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <Button size="small" ghost @click="onShowFlyToPopover" > |
| | | <span>Fly to</span> |
| | | </Button> |
| | | </DroneControlPopover> |
| | | <Button size="small" ghost @click="onStopFlyToPoint" > |
| | | <span>Stop Fly to</span> |
| | | </Button> |
| | | <DroneControlPopover |
| | | :visible="takeoffToPointPopoverData.visible" |
| | | :loading="takeoffToPointPopoverData.loading" |
| | | @confirm="($event) => onTakeoffToPointConfirm(true)" |
| | | @cancel="($event) =>onTakeoffToPointConfirm(false)" |
| | | > |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <div> |
| | | <span class="form-label">latitude:</span> |
| | | <a-input-number v-model:value="takeoffToPointPopoverData.latitude"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">longitude:</span> |
| | | <a-input-number v-model:value="takeoffToPointPopoverData.longitude"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">height(m):</span> |
| | | <a-input-number v-model:value="takeoffToPointPopoverData.height"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">Safe Takeoff Altitude(m):</span> |
| | | <a-input-number v-model:value="takeoffToPointPopoverData.securityTakeoffHeight"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">Return-to-Home Altitude(m):</span> |
| | | <a-input-number v-model:value="takeoffToPointPopoverData.rthAltitude"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">Lost Action:</span> |
| | | <a-select |
| | | v-model:value="takeoffToPointPopoverData.rcLostAction" |
| | | style="width: 120px" |
| | | :options="LostControlActionInCommandFLightOptions" |
| | | ></a-select> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">Wayline Lost Action:</span> |
| | | <a-select |
| | | v-model:value="takeoffToPointPopoverData.exitWaylineWhenRcLost" |
| | | style="width: 120px" |
| | | :options="WaylineLostControlActionInCommandFlightOptions" |
| | | ></a-select> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <Button size="small" ghost @click="onShowTakeoffToPointPopover" > |
| | | <span>Take off</span> |
| | | </Button> |
| | | </DroneControlPopover> |
| | | <Button :loading="cmdItem.loading" size="small" ghost @click="sendControlCmd(cmdItem, index)"> |
| | | {{ cmdItem.operateText }} |
| | | </Button> |
| | | </div> |
| | | </div> |
| | | <div class="box"> |
| | | <div class="row"> |
| | | <Select v-model:value="payloadSelectInfo.value" style="width: 110px; marginRight: 5px" :options="payloadSelectInfo.options" @change="handlePayloadChange"/> |
| | | <div class="drone-control"> |
| | | <Button type="primary" size="small" @click="onAuthPayload">Payload Control</Button> |
| | | </div> |
| | | </div> |
| | | <div class="row"> |
| | | <DroneControlPopover |
| | | :visible="gimbalResetPopoverData.visible" |
| | | :loading="gimbalResetPopoverData.loading" |
| | | @confirm="($event) => onGimbalResetConfirm(true)" |
| | | @cancel="($event) =>onGimbalResetConfirm(false)" |
| | | > |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <div> |
| | | <span class="form-label">reset mode:</span> |
| | | <a-select |
| | | v-model:value="gimbalResetPopoverData.resetMode" |
| | | style="width: 180px" |
| | | :options="GimbalResetModeOptions" |
| | | ></a-select> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <Button size="small" ghost @click="onShowGimbalResetPopover"> |
| | | <span>Gimbal Reset</span> |
| | | </Button> |
| | | </DroneControlPopover> |
| | | <Button size="small" ghost @click="onSwitchCameraMode"> |
| | | <span>Camera Mode Switch</span> |
| | | </Button> |
| | | </div> |
| | | <div class="row"> |
| | | <Button size="small" ghost @click="onStartCameraRecording"> |
| | | <span>Start Recording</span> |
| | | </Button> |
| | | <Button size="small" ghost @click="onStopCameraRecording"> |
| | | <span>Stop Recording</span> |
| | | </Button> |
| | | </div> |
| | | <div class="row"> |
| | | <Button size="small" ghost @click="onTakeCameraPhoto"> |
| | | <span>Take Photo</span> |
| | | </Button> |
| | | <DroneControlPopover |
| | | :visible="zoomFactorPopoverData.visible" |
| | | :loading="zoomFactorPopoverData.loading" |
| | | @confirm="($event) => onZoomFactorConfirm(true)" |
| | | @cancel="($event) =>onZoomFactorConfirm(false)" |
| | | > |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <div> |
| | | <span class="form-label">camera type:</span> |
| | | <a-select |
| | | v-model:value="zoomFactorPopoverData.cameraType" |
| | | style="width: 120px" |
| | | :options="ZoomCameraTypeOptions" |
| | | ></a-select> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">zoom factor:</span> |
| | | <a-input-number v-model:value="zoomFactorPopoverData.zoomFactor" :min="2" :max="200" /> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <Button size="small" ghost @click="($event) => onShowZoomFactorPopover()"> |
| | | <span class="word" @click=";">Zoom</span> |
| | | </Button> |
| | | </DroneControlPopover> |
| | | <DroneControlPopover |
| | | :visible="cameraAimPopoverData.visible" |
| | | :loading="cameraAimPopoverData.loading" |
| | | @confirm="($event) => onCameraAimConfirm(true)" |
| | | @cancel="($event) =>onCameraAimConfirm(false)" |
| | | > |
| | | <template #formContent> |
| | | <div class="form-content"> |
| | | <div> |
| | | <span class="form-label">camera type:</span> |
| | | <a-select |
| | | v-model:value="cameraAimPopoverData.cameraType" |
| | | style="width: 120px" |
| | | :options="CameraTypeOptions" |
| | | ></a-select> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">locked:</span> |
| | | <a-switch v-model:checked="cameraAimPopoverData.locked"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">x:</span> |
| | | <a-input-number v-model:value="cameraAimPopoverData.x" :min="0" :max="1"/> |
| | | </div> |
| | | <div> |
| | | <span class="form-label">y:</span> |
| | | <a-input-number v-model:value="cameraAimPopoverData.y" :min="0" :max="1"/> |
| | | </div> |
| | | </div> |
| | | </template> |
| | | <Button size="small" ghost @click="($event) => onShowCameraAimPopover()"> |
| | | <span class="word" @click=";">AIM</span> |
| | | </Button> |
| | | </DroneControlPopover> |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <!-- 信息提示 --> |
| | | <DroneControlInfoPanel :message="drcInfo"></DroneControlInfoPanel> |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup lang="ts"> |
| | | import { defineProps, reactive, ref, watch, computed, onMounted, watchEffect } from 'vue' |
| | | import { Select, message, Button } from 'ant-design-vue' |
| | | import { PayloadInfo, DeviceInfoType, ControlSource, DeviceOsdCamera, DrcStateEnum } from '/@/types/device' |
| | | import { useMyStore } from '/@/store' |
| | | import { postDrcEnter, postDrcExit } from '/@/api/drc' |
| | | import { useMqtt, DeviceTopicInfo } from './use-mqtt' |
| | | import { DownOutlined, UpOutlined, LeftOutlined, RightOutlined, PauseCircleOutlined, UndoOutlined, RedoOutlined, ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons-vue' |
| | | import { useManualControl, KeyCode } from './use-manual-control' |
| | | import { usePayloadControl } from './use-payload-control' |
| | | import { CameraMode, CameraType, CameraTypeOptions, ZoomCameraTypeOptions, CameraListItem } from '/@/types/live-stream' |
| | | import { useDroneControlWsEvent } from './use-drone-control-ws-event' |
| | | import { useDroneControlMqttEvent } from './use-drone-control-mqtt-event' |
| | | import { postFlightAuth, LostControlActionInCommandFLight, WaylineLostControlActionInCommandFlight } from '/@/api/drone-control/drone' |
| | | import { useDroneControl } from './use-drone-control' |
| | | import { GimbalResetMode, GimbalResetModeOptions, LostControlActionInCommandFLightOptions, WaylineLostControlActionInCommandFlightOptions } from '/@/types/drone-control' |
| | | import DroneControlPopover from './DroneControlPopover.vue' |
| | | import DroneControlInfoPanel from './DroneControlInfoPanel.vue' |
| | | import { noDebugCmdList as baseCmdList, DeviceCmdItem, DeviceCmd } from '/@/types/device-cmd' |
| | | import { useDockControl } from './use-dock-control' |
| | | |
| | | const props = defineProps<{ |
| | | sn: string, |
| | | deviceInfo: DeviceInfoType, |
| | | payloads: null | PayloadInfo[] |
| | | }>() |
| | | |
| | | const store = useMyStore() |
| | | const clientId = computed(() => { |
| | | return store.state.clientId |
| | | }) |
| | | |
| | | const initCmdList = baseCmdList.find(item => item.cmdKey === DeviceCmd.ReturnHome) |
| | | const cmdItem = ref(initCmdList) |
| | | |
| | | const { |
| | | sendDockControlCmd |
| | | } = useDockControl() |
| | | |
| | | async function sendControlCmd (cmdItem: DeviceCmdItem, index: number) { |
| | | cmdItem.loading = true |
| | | const result = await sendDockControlCmd({ |
| | | sn: props.sn, |
| | | cmd: cmdItem.cmdKey, |
| | | action: cmdItem.action |
| | | }, false) |
| | | if (result && flightController.value) { |
| | | exitFlightCOntrol() |
| | | } |
| | | cmdItem.loading = false |
| | | } |
| | | |
| | | const { flyToPoint, stopFlyToPoint, takeoffToPoint } = useDroneControl() |
| | | const MAX_SPEED = 14 |
| | | |
| | | const flyToPointPopoverData = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | latitude: null as null | number, |
| | | longitude: null as null | number, |
| | | height: null as null | number, |
| | | maxSpeed: MAX_SPEED, |
| | | }) |
| | | |
| | | function onShowFlyToPopover () { |
| | | flyToPointPopoverData.visible = !flyToPointPopoverData.visible |
| | | flyToPointPopoverData.loading = false |
| | | flyToPointPopoverData.latitude = null |
| | | flyToPointPopoverData.longitude = null |
| | | flyToPointPopoverData.height = null |
| | | } |
| | | |
| | | async function onFlyToConfirm (confirm: boolean) { |
| | | if (confirm) { |
| | | if (!flyToPointPopoverData.height || !flyToPointPopoverData.latitude || !flyToPointPopoverData.longitude) { |
| | | message.error('Input error') |
| | | return |
| | | } |
| | | try { |
| | | await flyToPoint(props.sn, { |
| | | max_speed: flyToPointPopoverData.maxSpeed, |
| | | points: [ |
| | | { |
| | | latitude: flyToPointPopoverData.latitude, |
| | | longitude: flyToPointPopoverData.longitude, |
| | | height: flyToPointPopoverData.height |
| | | } |
| | | ] |
| | | }) |
| | | } catch (error) { |
| | | } |
| | | } |
| | | flyToPointPopoverData.visible = false |
| | | } |
| | | |
| | | async function onStopFlyToPoint () { |
| | | await stopFlyToPoint(props.sn) |
| | | } |
| | | |
| | | const takeoffToPointPopoverData = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | latitude: null as null | number, |
| | | longitude: null as null | number, |
| | | height: null as null | number, |
| | | securityTakeoffHeight: null as null | number, |
| | | maxSpeed: MAX_SPEED, |
| | | rthAltitude: null as null | number, |
| | | rcLostAction: LostControlActionInCommandFLight.RETURN_HOME, |
| | | exitWaylineWhenRcLost: WaylineLostControlActionInCommandFlight.RETURN_HOME |
| | | }) |
| | | |
| | | function onShowTakeoffToPointPopover () { |
| | | takeoffToPointPopoverData.visible = !takeoffToPointPopoverData.visible |
| | | takeoffToPointPopoverData.loading = false |
| | | takeoffToPointPopoverData.latitude = null |
| | | takeoffToPointPopoverData.longitude = null |
| | | takeoffToPointPopoverData.securityTakeoffHeight = null |
| | | takeoffToPointPopoverData.rthAltitude = null |
| | | takeoffToPointPopoverData.rcLostAction = LostControlActionInCommandFLight.RETURN_HOME |
| | | takeoffToPointPopoverData.exitWaylineWhenRcLost = WaylineLostControlActionInCommandFlight.RETURN_HOME |
| | | } |
| | | |
| | | async function onTakeoffToPointConfirm (confirm: boolean) { |
| | | if (confirm) { |
| | | if (!takeoffToPointPopoverData.height || |
| | | !takeoffToPointPopoverData.latitude || |
| | | !takeoffToPointPopoverData.longitude || |
| | | !takeoffToPointPopoverData.securityTakeoffHeight || |
| | | !takeoffToPointPopoverData.rthAltitude) { |
| | | message.error('Input error') |
| | | return |
| | | } |
| | | try { |
| | | await takeoffToPoint(props.sn, { |
| | | target_latitude: takeoffToPointPopoverData.latitude, |
| | | target_longitude: takeoffToPointPopoverData.longitude, |
| | | target_height: takeoffToPointPopoverData.height, |
| | | security_takeoff_height: takeoffToPointPopoverData.securityTakeoffHeight, |
| | | rth_altitude: takeoffToPointPopoverData.rthAltitude, |
| | | max_speed: takeoffToPointPopoverData.maxSpeed, |
| | | rc_lost_action: takeoffToPointPopoverData.rcLostAction, |
| | | exit_wayline_when_rc_lost: takeoffToPointPopoverData.exitWaylineWhenRcLost |
| | | }) |
| | | } catch (error) { |
| | | } |
| | | } |
| | | takeoffToPointPopoverData.visible = false |
| | | } |
| | | |
| | | const deviceTopicInfo: DeviceTopicInfo = reactive({ |
| | | sn: props.sn, |
| | | pubTopic: '', |
| | | subTopic: '' |
| | | }) |
| | | |
| | | useMqtt(deviceTopicInfo) |
| | | |
| | | // 飞行控制 |
| | | const drcState = computed(() => { |
| | | return store.state.deviceState?.dockInfo[props.sn]?.link_osd?.drc_state === DrcStateEnum.CONNECTED |
| | | }) |
| | | const flightController = ref(drcState.value) |
| | | |
| | | async function onClickFightControl () { |
| | | if (flightController.value) { |
| | | exitFlightCOntrol() |
| | | return |
| | | } |
| | | enterFlightControl() |
| | | } |
| | | |
| | | // 进入飞行控制 |
| | | async function enterFlightControl () { |
| | | try { |
| | | const { code, data } = await postDrcEnter({ |
| | | client_id: clientId.value, |
| | | dock_sn: props.sn, |
| | | }) |
| | | if (code === 0) { |
| | | flightController.value = true |
| | | if (data.sub && data.sub.length > 0) { |
| | | deviceTopicInfo.subTopic = data.sub[0] |
| | | } |
| | | if (data.pub && data.pub.length > 0) { |
| | | deviceTopicInfo.pubTopic = data.pub[0] |
| | | } |
| | | // 获取飞行控制权 |
| | | if (droneControlSource.value !== ControlSource.A) { |
| | | await postFlightAuth(props.sn) |
| | | } |
| | | message.success('Get flight control successfully') |
| | | } |
| | | } catch (error: any) { |
| | | } |
| | | } |
| | | |
| | | // 退出飞行控制 |
| | | async function exitFlightCOntrol () { |
| | | try { |
| | | const { code } = await postDrcExit({ |
| | | client_id: clientId.value, |
| | | dock_sn: props.sn, |
| | | }) |
| | | if (code === 0) { |
| | | flightController.value = false |
| | | deviceTopicInfo.subTopic = '' |
| | | deviceTopicInfo.pubTopic = '' |
| | | message.success('Exit flight control') |
| | | } |
| | | } catch (error: any) { |
| | | } |
| | | } |
| | | |
| | | // drc mqtt message |
| | | const { drcInfo } = useDroneControlMqttEvent(props.sn) |
| | | |
| | | const { |
| | | handleKeyup, |
| | | handleEmergencyStop, |
| | | resetControlState, |
| | | } = useManualControl(deviceTopicInfo, flightController) |
| | | |
| | | function onMouseDown (type: KeyCode) { |
| | | handleKeyup(type) |
| | | } |
| | | |
| | | function onMouseUp () { |
| | | resetControlState() |
| | | } |
| | | |
| | | // 负载控制 |
| | | const payloadSelectInfo = { |
| | | value: null as any, |
| | | controlSource: undefined as undefined | ControlSource, |
| | | options: [] as any, |
| | | payloadIndex: '' as string, |
| | | camera: undefined as undefined | DeviceOsdCamera // 当前负载osd信息 |
| | | } |
| | | |
| | | const handlePayloadChange = (value: string) => { |
| | | const payload = props.payloads?.find(item => item.payload_sn === value) |
| | | if (payload) { |
| | | payloadSelectInfo.payloadIndex = payload.payload_index || '' |
| | | payloadSelectInfo.controlSource = payload.control_source |
| | | payloadSelectInfo.camera = undefined |
| | | } |
| | | } |
| | | |
| | | // function getCurrentCamera (cameraList: CameraListItem[], cameraIndex?: string):CameraListItem | null { |
| | | // let camera = null |
| | | // cameraList.forEach(item => { |
| | | // if (item.camera_index === cameraIndex) { |
| | | // camera = item |
| | | // } |
| | | // }) |
| | | // return camera |
| | | // } |
| | | |
| | | // const currentCamera = computed(() => { |
| | | // return getCurrentCamera(props.deviceInfo.dock.basic_osd.live_capacity?.device_list[0]?.camera_list as CameraListItem[], camera_index) |
| | | // }) |
| | | // 更新负载信息 |
| | | watch(() => props.payloads, (payloads) => { |
| | | if (payloads && payloads.length > 0) { |
| | | payloadSelectInfo.value = payloads[0].payload_sn |
| | | payloadSelectInfo.controlSource = payloads[0].control_source || ControlSource.B |
| | | payloadSelectInfo.payloadIndex = payloads[0].payload_index || '' |
| | | payloadSelectInfo.options = payloads.map(item => ({ label: item.payload_name, value: item.payload_sn })) |
| | | payloadSelectInfo.camera = undefined |
| | | } else { |
| | | payloadSelectInfo.value = null |
| | | payloadSelectInfo.controlSource = undefined |
| | | payloadSelectInfo.options = [] |
| | | payloadSelectInfo.payloadIndex = '' |
| | | payloadSelectInfo.camera = undefined |
| | | } |
| | | }, { |
| | | immediate: true, |
| | | deep: true |
| | | }) |
| | | watch(() => props.deviceInfo.device, (droneOsd) => { |
| | | if (droneOsd && droneOsd.cameras) { |
| | | payloadSelectInfo.camera = droneOsd.cameras.find(item => item.payload_index === payloadSelectInfo.payloadIndex) |
| | | } else { |
| | | payloadSelectInfo.camera = undefined |
| | | } |
| | | }, { |
| | | immediate: true, |
| | | deep: true |
| | | }) |
| | | |
| | | // ws 消息通知 |
| | | const { droneControlSource, payloadControlSource } = useDroneControlWsEvent(props.sn, payloadSelectInfo.value) |
| | | watch(() => payloadControlSource, (controlSource) => { |
| | | payloadSelectInfo.controlSource = controlSource.value |
| | | }, { |
| | | immediate: true, |
| | | deep: true |
| | | }) |
| | | const { |
| | | checkPayloadAuth, |
| | | authPayload, |
| | | resetGimbal, |
| | | switchCameraMode, |
| | | takeCameraPhoto, |
| | | startCameraRecording, |
| | | stopCameraRecording, |
| | | changeCameraFocalLength, |
| | | cameraAim, |
| | | } = usePayloadControl() |
| | | |
| | | async function onAuthPayload () { |
| | | const result = await authPayload(props.sn, payloadSelectInfo.payloadIndex) |
| | | if (result) { |
| | | payloadControlSource.value = ControlSource.A |
| | | } |
| | | } |
| | | |
| | | const gimbalResetPopoverData = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | resetMode: null as null | GimbalResetMode, |
| | | }) |
| | | |
| | | function onShowGimbalResetPopover () { |
| | | gimbalResetPopoverData.visible = !gimbalResetPopoverData.visible |
| | | gimbalResetPopoverData.loading = false |
| | | gimbalResetPopoverData.resetMode = null |
| | | } |
| | | |
| | | async function onGimbalResetConfirm (confirm: boolean) { |
| | | if (confirm) { |
| | | if (gimbalResetPopoverData.resetMode === null) { |
| | | message.error('Please select reset mode') |
| | | return |
| | | } |
| | | gimbalResetPopoverData.loading = true |
| | | try { |
| | | await resetGimbal(props.sn, { |
| | | payload_index: payloadSelectInfo.payloadIndex, |
| | | reset_mode: gimbalResetPopoverData.resetMode |
| | | }) |
| | | } catch (err) { |
| | | } |
| | | } |
| | | gimbalResetPopoverData.visible = false |
| | | } |
| | | |
| | | async function onSwitchCameraMode () { |
| | | if (!checkPayloadAuth(payloadSelectInfo.controlSource)) { |
| | | return |
| | | } |
| | | const currentCameraMode = payloadSelectInfo.camera?.camera_mode |
| | | await switchCameraMode(props.sn, { |
| | | payload_index: payloadSelectInfo.payloadIndex, |
| | | camera_mode: currentCameraMode === CameraMode.Photo ? CameraMode.Video : CameraMode.Photo |
| | | }) |
| | | } |
| | | |
| | | async function onTakeCameraPhoto () { |
| | | if (!checkPayloadAuth(payloadSelectInfo.controlSource)) { |
| | | return |
| | | } |
| | | await takeCameraPhoto(props.sn, payloadSelectInfo.payloadIndex) |
| | | } |
| | | |
| | | async function onStartCameraRecording () { |
| | | if (!checkPayloadAuth(payloadSelectInfo.controlSource)) { |
| | | return |
| | | } |
| | | await startCameraRecording(props.sn, payloadSelectInfo.payloadIndex) |
| | | } |
| | | |
| | | async function onStopCameraRecording () { |
| | | if (!checkPayloadAuth(payloadSelectInfo.controlSource)) { |
| | | return |
| | | } |
| | | await stopCameraRecording(props.sn, payloadSelectInfo.payloadIndex) |
| | | } |
| | | |
| | | const zoomFactorPopoverData = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | cameraType: null as null | CameraType, |
| | | zoomFactor: null as null | number, |
| | | }) |
| | | |
| | | function onShowZoomFactorPopover () { |
| | | zoomFactorPopoverData.visible = !zoomFactorPopoverData.visible |
| | | zoomFactorPopoverData.loading = false |
| | | zoomFactorPopoverData.cameraType = null |
| | | zoomFactorPopoverData.zoomFactor = null |
| | | } |
| | | |
| | | async function onZoomFactorConfirm (confirm: boolean) { |
| | | if (confirm) { |
| | | if (!zoomFactorPopoverData.zoomFactor || zoomFactorPopoverData.cameraType === null) { |
| | | message.error('Please input Zoom Factor') |
| | | return |
| | | } |
| | | zoomFactorPopoverData.loading = true |
| | | try { |
| | | await changeCameraFocalLength(props.sn, { |
| | | payload_index: payloadSelectInfo.payloadIndex, |
| | | camera_type: zoomFactorPopoverData.cameraType, |
| | | zoom_factor: zoomFactorPopoverData.zoomFactor |
| | | }) |
| | | } catch (err) { |
| | | } |
| | | } |
| | | zoomFactorPopoverData.visible = false |
| | | } |
| | | |
| | | const cameraAimPopoverData = reactive({ |
| | | visible: false, |
| | | loading: false, |
| | | cameraType: null as null | CameraType, |
| | | locked: false, |
| | | x: null as null | number, |
| | | y: null as null | number, |
| | | }) |
| | | |
| | | function onShowCameraAimPopover () { |
| | | cameraAimPopoverData.visible = !cameraAimPopoverData.visible |
| | | cameraAimPopoverData.loading = false |
| | | cameraAimPopoverData.cameraType = null |
| | | cameraAimPopoverData.locked = false |
| | | cameraAimPopoverData.x = null |
| | | cameraAimPopoverData.y = null |
| | | } |
| | | |
| | | async function onCameraAimConfirm (confirm: boolean) { |
| | | if (confirm) { |
| | | if (cameraAimPopoverData.cameraType === null || cameraAimPopoverData.x === null || cameraAimPopoverData.y === null) { |
| | | message.error('Input error') |
| | | return |
| | | } |
| | | try { |
| | | await cameraAim(props.sn, { |
| | | payload_index: payloadSelectInfo.payloadIndex, |
| | | camera_type: cameraAimPopoverData.cameraType, |
| | | locked: cameraAimPopoverData.locked, |
| | | x: cameraAimPopoverData.x, |
| | | y: cameraAimPopoverData.y, |
| | | }) |
| | | } catch (error) { |
| | | } |
| | | } |
| | | cameraAimPopoverData.visible = false |
| | | } |
| | | </script> |
| | | |
| | | <style lang='scss' scoped> |
| | | .drone-control-wrapper{ |
| | | // border-bottom: 1px solid #515151; |
| | | |
| | | .drone-control-header{ |
| | | font-size: 14px; |
| | | font-weight: 600; |
| | | padding: 10px 10px 0px; |
| | | } |
| | | |
| | | .drone-control-box { |
| | | display: flex; |
| | | flex-wrap: 1; |
| | | .box { |
| | | width: 50%; |
| | | padding: 5px; |
| | | border: 0.5px solid rgba(255,255,255,0.3); |
| | | |
| | | .row { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | padding: 2px; |
| | | |
| | | + .row{ |
| | | margin-bottom: 6px; |
| | | } |
| | | |
| | | &::v-deep{ |
| | | .ant-btn{ |
| | | font-size: 12px; |
| | | padding: 0px 4px; |
| | | margin-right: 5px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .drone-control{ |
| | | &::v-deep{ |
| | | |
| | | .ant-select-single:not(.ant-select-customize-input) .ant-select-selector{ |
| | | padding: 0 2px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .drone-control-direction{ |
| | | margin-right: 10px; |
| | | |
| | | .ant-btn { |
| | | // padding: 0px 1px; |
| | | margin-right: 0; |
| | | } |
| | | |
| | | .word{ |
| | | width: 12px; |
| | | margin-left: 2px; |
| | | font-size: 12px; |
| | | color: #aaa; |
| | | } |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | <template> |
| | | <a-popover :visible="state.sVisible" |
| | | trigger="click" |
| | | v-bind="$attrs" |
| | | :overlay-class-name="overlayClassName" |
| | | placement="bottom" |
| | | @visibleChange=";" |
| | | v-on="$attrs"> |
| | | <template #content> |
| | | <div class="title-content"> |
| | | </div> |
| | | <slot name="formContent" /> |
| | | <div class="uranus-popconfirm-btns"> |
| | | <a-button size="sm" |
| | | @click="onCancel"> |
| | | {{ cancelText || 'cancel'}} |
| | | </a-button> |
| | | <a-button size="sm" |
| | | :loading="loading" |
| | | type="primary" |
| | | class="confirm-btn" |
| | | @click="onConfirm"> |
| | | {{ okText || 'ok' }} |
| | | </a-button> |
| | | </div> |
| | | </template> |
| | | <template v-if="$slots.default"> |
| | | <slot></slot> |
| | | </template> |
| | | </a-popover> |
| | | </template> |
| | | |
| | | <script lang="ts" setup> |
| | | import { defineProps, defineEmits, reactive, watch, computed } from 'vue' |
| | | |
| | | const props = defineProps<{ |
| | | visible?: boolean, |
| | | loading?: Boolean, |
| | | disabled?: Boolean, |
| | | title?: String, |
| | | okText?: String, |
| | | cancelText?: String, |
| | | width?: Number, |
| | | }>() |
| | | |
| | | const emit = defineEmits(['cancel', 'confirm']) |
| | | |
| | | const state = reactive({ |
| | | sVisible: false, |
| | | loading: false, |
| | | }) |
| | | |
| | | watch(() => props.visible, (val) => { |
| | | state.sVisible = val || false |
| | | }) |
| | | |
| | | const loading = computed(() => { |
| | | return props.loading |
| | | }) |
| | | const okLabel = computed(() => { |
| | | return props.loading ? '' : '确定' |
| | | }) |
| | | |
| | | const overlayClassName = computed(() => { |
| | | const classList = ['drone-control-popconfirm'] |
| | | return classList.join(' ') |
| | | }) |
| | | |
| | | function onConfirm (e: Event) { |
| | | if (props.disabled) { |
| | | return |
| | | } |
| | | emit('confirm', e) |
| | | } |
| | | |
| | | function onCancel (e: Event) { |
| | | state.sVisible = false |
| | | emit('cancel', e) |
| | | } |
| | | |
| | | </script> |
| | | |
| | | <style lang="scss"> |
| | | .drone-control-popconfirm { |
| | | min-width: 300px; |
| | | |
| | | .uranus-popconfirm-btns{ |
| | | display: flex; |
| | | padding: 10px 0px; |
| | | justify-content: flex-end; |
| | | |
| | | .confirm-btn{ |
| | | margin-left: 10px; |
| | | } |
| | | } |
| | | |
| | | .form-content{ |
| | | display: flex; |
| | | flex-direction: column; |
| | | |
| | | > div { |
| | | display: flex; |
| | | margin-bottom: 5px; |
| | | |
| | | .form-label { |
| | | flex: 1 0 60px; |
| | | margin-right: 10px; |
| | | } |
| | | |
| | | > div { |
| | | } |
| | | } |
| | | } |
| | | } |
| | | </style> |
| New file |
| | |
| | | |
| | | 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<UranusMqtt | null>(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() |
| | | }) |
| | | } |
| File was renamed from src/components/g-map/useDockControl.ts |
| | |
| | | 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 |
| | | } |
| | | |
| | | // 远程调试开关 |
| | |
| | | sn: sn, |
| | | cmd: on ? DeviceCmd.DebugModeOpen : DeviceCmd.DebugModeClose |
| | | }, false) |
| | | if (result) { |
| | | setControlPanelVisible(on) |
| | | } |
| | | return result |
| | | } |
| | | |
| | |
| | | } |
| | | } |
| | | |
| | | // 控制面板关闭 |
| | | async function onCloseControlPanel (sn: string) { |
| | | await dockDebugOnOff(sn, false) |
| | | setDockControlPanelVisible(false) |
| | | } |
| | | |
| | | return { |
| | | controlPanelVisible, |
| | | setControlPanelVisible, |
| | | dockControlPanelVisible, |
| | | setDockControlPanelVisible, |
| | | sendDockControlCmd, |
| | | dockDebugOnOff, |
| | | onCloseControlPanel, |
| | | } |
| | | } |
| New file |
| | |
| | | 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 |
| | | } |
| | | } |
| New file |
| | |
| | | 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 |
| | | } |
| | | } |
| New file |
| | |
| | | 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 |
| | | } |
| | | } |
| New file |
| | |
| | | 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<boolean>) { |
| | | const activeCodeKey = ref(null) as Ref<KeyCode | null> |
| | | 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, |
| | | } |
| | | } |
| New file |
| | |
| | | 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<void> |
| | | |
| | | 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<string, { |
| | | pingInterval: any; |
| | | }>(), |
| | | }) |
| | | |
| | | // 监听云控控制权 |
| | | 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, |
| | | } |
| | | } |
| New file |
| | |
| | | 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, |
| | | } |
| | | } |
| | |
| | | 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) { |
| | |
| | | :pagination="paginationProp" :scroll="{ x: '100%', y: 600 }" @change="refreshData"> |
| | | <!-- 执行时间 --> |
| | | <template #duration="{ record }"> |
| | | <div class="flex-row"> |
| | | <div class="flex-row" style="white-space: pre-wrap"> |
| | | <div> |
| | | <div>{{ formatTaskTime(record.begin_time) }}</div> |
| | | <div>{{ formatTaskTime(record.end_time) }}</div> |
| | |
| | | </template> |
| | | <!-- 操作 --> |
| | | <template #action="{ record }"> |
| | | <span class="action-area"> |
| | | <div class="action-area"> |
| | | <a-popconfirm |
| | | v-if="record.status === TaskStatus.Wait" |
| | | title="Are you sure you want to delete flight task?" |
| | |
| | | > |
| | | <a-button type="primary" size="small">Delete</a-button> |
| | | </a-popconfirm> |
| | | </span> |
| | | <a-popconfirm |
| | | v-if="record.status === TaskStatus.Carrying" |
| | | title="Are you sure you want to suspend?" |
| | | ok-text="Yes" |
| | | cancel-text="No" |
| | | @confirm="onSuspendTask(record.job_id)" |
| | | > |
| | | <a-button type="primary" size="small">Suspend</a-button> |
| | | </a-popconfirm> |
| | | <a-popconfirm |
| | | v-if="record.status === TaskStatus.Paused" |
| | | title="Are you sure you want to resume?" |
| | | ok-text="Yes" |
| | | cancel-text="No" |
| | | @confirm="onResumeTask(record.job_id)" |
| | | > |
| | | <a-button type="primary" size="small">Resume</a-button> |
| | | </a-popconfirm> |
| | | </div> |
| | | </template> |
| | | </a-table> |
| | | </div> |
| | |
| | | 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' |
| | |
| | | } |
| | | } |
| | | |
| | | // 挂起任务 |
| | | 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) |
| | |
| | | margin-top: 10px; |
| | | } |
| | | .action-area { |
| | | color: $primary; |
| | | cursor: pointer; |
| | | |
| | | &::v-deep { |
| | | .ant-btn { |
| | | margin-right: 10px; |
| | | margin-bottom: 10px; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .circle-icon { |
| | |
| | | deviceUpgrade: any; // 设备升级 |
| | | deviceLogUploadProgress: any // 设备日志上传 |
| | | flightTaskWs: any // 机场任务消息 |
| | | droneControlWs: any // 飞行指令信息 |
| | | droneControlMqttInfo: any // drc 链路通知 |
| | | }; |
| | | |
| | | const emitter: Emitter<Events> = mitt<Events>() |
| | |
| | | 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() |
| New file |
| | |
| | | |
| | | import { |
| | | IClientOptions, |
| | | } from 'mqtt' |
| | | |
| | | export const OPTIONS: IClientOptions = { |
| | | clean: true, // true: 清除会话, false: 保留会话 |
| | | connectTimeout: 10000, // mqtt 超时时间 |
| | | resubscribe: true, // 断开重连后,再次订阅原订阅 |
| | | reconnectPeriod: 10000, // 重连间隔时间: 5s |
| | | keepalive: 1, // 心跳间隔时间:1s |
| | | } |
| New file |
| | |
| | | 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, |
| | | } |
| | |
| | | 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() |
| | |
| | | fileData.append(key, val.toString()) |
| | | } |
| | | }) |
| | | const timestamp = new Date().getTime() |
| | | uploading = (file.name ?? 'uploding') + timestamp |
| | | notification.open({ |
| | | key: uploading, |
| | | message: `Uploading ${moment().format()}`, |
| | |
| | | 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) |
| | |
| | | style="margin: -5px 0" |
| | | /> |
| | | <template v-else> |
| | | {{ text }} |
| | | <a-tooltip :title="text"> |
| | | {{ text }} |
| | | </a-tooltip> |
| | | </template> |
| | | </div> |
| | | </template> |
| | |
| | | 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[] |
| | |
| | | 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) |
| | |
| | | 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 |
| | | } |
| | |
| | | import { getRoot } from '/@/root' |
| | | import { ERouterName } from '/@/types' |
| | | const root = getRoot() |
| | | const routeName = ref<string>() |
| | | const showLive = ref<boolean>(false) |
| | | const routeName = ref<string>('LiveOthers') |
| | | const showLive = ref<boolean>(root.$route.name === ERouterName.LIVING) |
| | | |
| | | const options = [ |
| | | { key: 0, label: 'Agora Live', path: '/' + ERouterName.LIVESTREAM + '/' + ERouterName.LIVING, routeName: 'LiveAgora' }, |
| | |
| | | ] |
| | | |
| | | const selectLivestream = (route: string) => { |
| | | showLive.value = root.$route.name === ERouterName.LIVING |
| | | routeName.value = route |
| | | } |
| | | |
| | |
| | | <div style="float: left; padding: 0px 5px 8px 8px; width: 88%"> |
| | | <div style="width: 80%; height: 30px; line-height: 30px; font-size: 16px;"> |
| | | <a-tooltip :title="`${dock.gateway.callsign} - ${dock.callsign ?? 'No Drone'}`"> |
| | | <span class="text-hidden" style="max-width: 200px;">{{ dock.gateway.callsign }} - {{ dock.callsign ?? 'No Drone' }}</span> |
| | | <div class="text-hidden" style="max-width: 200px;">{{ dock.gateway.callsign }} - {{ dock.callsign ?? 'No Drone' }}</div> |
| | | </a-tooltip> |
| | | </div> |
| | | <div class="mt5 flex-align-center flex-row flex-justify-between" style="background: #595959;"> |
| | | <div class="flex-align-center flex-row"> |
| | | <span class="ml5 mr5"><RobotOutlined /></span> |
| | | <span class="font-bold text-hidden" style="max-width: 80px;" :style="dockInfo[dock.gateway.sn] && dockInfo[dock.gateway.sn].basic_osd?.mode_code !== EDockModeCode.Disconnected ? 'color: #00ee8b' : 'color: red;'"> |
| | | <div class="font-bold text-hidden" style="max-width: 80px;" :style="dockInfo[dock.gateway.sn] && dockInfo[dock.gateway.sn].basic_osd?.mode_code !== EDockModeCode.Disconnected ? 'color: #00ee8b' : 'color: red;'"> |
| | | {{ dockInfo[dock.gateway.sn] ? EDockModeCode[dockInfo[dock.gateway.sn].basic_osd?.mode_code] : EDockModeCode[EDockModeCode.Disconnected] }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div class="mr5 flex-align-center flex-row" style="width: 85px; margin-right: 0; height: 18px;"> |
| | | <div v-if="hmsInfo[dock.gateway.sn]" class="flex-align-center flex-row"> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="mt5 flex-align-center flex-row flex-justify-between" style="background: #595959;"> |
| | | <div> |
| | | <div class="flex-row"> |
| | | <span class="ml5 mr5"><RocketOutlined /></span> |
| | | <span class="font-bold" :style="deviceInfo[dock.sn] && deviceInfo[dock.sn].mode_code !== EModeCode.Disconnected ? 'color: #00ee8b' : 'color: red;'"> |
| | | <div class="font-bold text-hidden" style="max-width: 80px" :style="deviceInfo[dock.sn] && deviceInfo[dock.sn].mode_code !== EModeCode.Disconnected ? 'color: #00ee8b' : 'color: red;'"> |
| | | {{ deviceInfo[dock.sn] ? EModeCode[deviceInfo[dock.sn].mode_code] : EModeCode[EModeCode.Disconnected] }} |
| | | </span> |
| | | </div> |
| | | </div> |
| | | <div class="mr5 flex-align-center flex-row" style="width: 85px; margin-right: 0; height: 18px;"> |
| | | <div v-if="hmsInfo[dock.sn]" class="flex-align-center flex-row"> |
| | |
| | | </div> |
| | | </div> |
| | | <div class="flex-row flex-justify-center flex-align-center" style="height: 40px;"> |
| | | <div style="height: 20px; background: #595959; width: 94%;" > |
| | | <div class="flex-row" style="height: 20px; background: #595959; width: 94%;" > |
| | | <span class="mr5"><a-image style="margin-left: 2px; margin-top: -2px; height: 20px; width: 20px;" :src="rc" /></span> |
| | | <a-tooltip> |
| | | <template #title>{{ device.gateway.model }} - {{ device.gateway.callsign }} </template> |
| | | <span class="text-hidden" style="max-width: 200px;">{{ device.gateway.model }} - {{ device.gateway.callsign }}</span> |
| | | <div class="text-hidden" style="max-width: 200px;">{{ device.gateway.model }} - {{ device.gateway.callsign }}</div> |
| | | </a-tooltip> |
| | | </div> |
| | | </div> |
| | |
| | | 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' |
| | | |
| | |
| | | const osdVisible = ref({} as OSDVisible) |
| | | const hmsVisible = new Map<string, boolean>() |
| | | 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[] |
| | |
| | | } |
| | | 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) { |
| | |
| | | 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) |
| | | } |
| | |
| | | }) |
| | | break |
| | | } |
| | | case EBizCode.ControlSourceChange: |
| | | case EBizCode.FlyToPointProgress: |
| | | case EBizCode.TakeoffToPointProgress: |
| | | case EBizCode.JoystickInvalidNotify: |
| | | case EBizCode.DrcStatusNotify: |
| | | { |
| | | EventBus.emit('droneControlWs', payload) |
| | | break |
| | | } |
| | | default: |
| | | break |
| | | } |
| New file |
| | |
| | | declare module 'mqtt/dist/mqtt.min' { |
| | | import MQTT from 'mqtt' |
| | | export = MQTT |
| | | } |
| | |
| | | currentSn: '', |
| | | currentType: -1 |
| | | }, |
| | | osdVisible: { |
| | | osdVisible: { // osd 显示设备相关信息 |
| | | sn: '', |
| | | callsign: '', |
| | | model: '', |
| | | visible: false, |
| | | gateway_sn: '', |
| | | is_dock: false, |
| | | payloads: null |
| | | } as OSDVisible, |
| | | waylineInfo: { |
| | | |
| | |
| | | }, |
| | | // 机场指令执行状态信息 |
| | | devicesCmdExecuteInfo: { |
| | | } as DevicesCmdExecuteInfo |
| | | } as DevicesCmdExecuteInfo, |
| | | mqttState: null as any, // mqtt 实例 |
| | | clientId: '', // mqtt 连接 唯一客户端id |
| | | }) |
| | | |
| | | export type RootStateType = ReturnType<typeof initStateFunc> |
| | |
| | | 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 |
| | |
| | | } 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<RootStateType, RootStateType> = { |
| | |
| | | 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[] = [ |
| | |
| | | cmdKey: DeviceCmd.ChargeOpen, |
| | | oppositeCmdKey: DeviceCmd.ChargeClose, |
| | | func: 'chargeStatus', |
| | | loading: false, |
| | | }, |
| | | { |
| | | label: '一键返航', |
| | | status: '--', |
| | | operateText: '返航', |
| | | cmdKey: DeviceCmd.ReturnHome, |
| | | func: 'returnHome', |
| | | loading: false, |
| | | }, |
| | | { |
| | |
| | | percent: number, |
| | | step_key: string, |
| | | step_result: number |
| | | }, |
| | | ext?: { |
| | | rate?: number |
| | | } |
| | | } |
| | | result: number, |
| | |
| | | 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种 |
| | |
| | | export enum DRONE_TYPE { |
| | | M30 = 67, |
| | | M300 = 60, |
| | | Phantom4 = 11, |
| | | Phantom4Pro = 18, |
| | | Phantom4RTK = 59, |
| | | Phantom4Advanced = 27, |
| | | Mavic3EnterpriseAdvanced= 77, |
| | | } |
| | | |
| | |
| | | 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}`, |
| | |
| | | [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', |
| | |
| | | |
| | | // dock |
| | | [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[] |
| | | } |
| | | |
| | | // 固件升级类型 |
| | |
| | | children?: Device[], |
| | | domain: number, |
| | | type: number, |
| | | firmware_progress?: number, // 升级进度 |
| | | firmware_progress?: string, // 升级进度 |
| | | } |
| | | |
| | | export interface DeviceStatus { |
| | |
| | | is_dock: boolean, |
| | | gateway_sn: string, |
| | | gateway_callsign: string, |
| | | payloads: null | PayloadInfo [], |
| | | } |
| | | |
| | | 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, |
| | |
| | | height_limit?: number;// 限高设置 |
| | | distance_limit_status?: DistanceLimitStatus;// 限远开关 |
| | | obstacle_avoidance?: ObstacleAvoidance;// 飞行器避障开关设置 |
| | | cameras?: DeviceOsdCamera[] |
| | | } |
| | | |
| | | export enum NetworkStateTypeEnum { |
| | |
| | | } |
| | | |
| | | 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, |
| | | }, |
| | |
| | | latitude: number, |
| | | longitude: number, |
| | | height: number, |
| | | alternate_land_point: { |
| | | alternate_land_point?: { |
| | | latitude: number, |
| | | longitude: number, |
| | | height: number, |
| | |
| | | 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, |
| | | }, |
| | |
| | | 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<LiveStatus>; // 直播状态 |
| | | } |
| | | |
| | | 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: { |
| | |
| | | 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链路连接状态 |
| | |
| | | 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, |
| | |
| | | export interface DockOsd { |
| | | basic_osd: DockBasicOsd, |
| | | link_osd: DockLinkOsd, |
| | | work_osd: DockWorkOsd |
| | | work_osd: DockWorkOsd |
| | | } |
| | | |
| | | export enum EModeCode { |
| | |
| | | } |
| | | |
| | | // TODO: 设备拓扑管理优化 |
| | | // 设备信息 |
| | | // 设备osd信息 |
| | | export interface DeviceInfoType { |
| | | gateway: GatewayOsd, // 遥控器 |
| | | dock: DockOsd, // 机场 |
| New file |
| | |
| | | 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[]; |
| | | } |
| New file |
| | |
| | | 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 } |
| | | ] |
| | |
| | | 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 { |
| | |
| | | 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<VideoType>; |
| | | } |
| | | |
| | | 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; // 设备端当前状态,是错误码,需要匹配到文案上 |
| | | // } |
| | |
| | | Success = 3, // 完成 |
| | | CanCel = 4, // 取消 |
| | | Fail = 5, // 失败 |
| | | Paused = 6, // 暂停 |
| | | } |
| | | |
| | | export const TaskStatusMap = { |
| | |
| | | [TaskStatus.Success]: 'Task completed', |
| | | [TaskStatus.CanCel]: 'Task canceled', |
| | | [TaskStatus.Fail]: 'Task failed', |
| | | [TaskStatus.Paused]: 'Paused', |
| | | |
| | | } |
| | | |
| | | export const TaskStatusColor = { |
| | |
| | | [TaskStatus.Success]: commonColor.NORMAL, |
| | | [TaskStatus.CanCel]: commonColor.FAIL, |
| | | [TaskStatus.Fail]: commonColor.FAIL, |
| | | [TaskStatus.Paused]: commonColor.BLUE, |
| | | } |
| | | |
| | | // 任务执行 ws 消息状态 |
| | |
| | | [TaskProgressStatus.Failed]: TaskStatus.Fail, |
| | | [TaskProgressStatus.Canceled]: TaskStatus.CanCel, |
| | | [TaskProgressStatus.Timeout]: TaskStatus.Fail, |
| | | [TaskProgressStatus.Paused]: TaskStatus.Wait, |
| | | [TaskProgressStatus.Paused]: TaskStatus.Paused, |
| | | } |
| | | |
| | | // 根据媒体文件上传进度信息,前端自己判断出的状态 |
| | |
| | | "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" |
| | |
| | | dependencies: |
| | | "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=" |
| | |
| | | "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.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" |
| | |
| | | "integrity" "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" |
| | | "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=" |
| | |
| | | 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" |
| | |
| | | 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" |
| | |
| | | "integrity" "sha1-VXBmIEatKeLpFucariYKvf9Pang=" |
| | | "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/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" |
| | |
| | | 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" |
| | |
| | | "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" |
| | |
| | | "entities" "^1.1.1" |
| | | "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==" |
| | |
| | | "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" |
| | |
| | | "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" |
| | |
| | | "integrity" "sha1-B8BQNKbDSfoG4k+jWqdttFgM5N0=" |
| | | "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=" |
| | |
| | | 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" |
| | |
| | | "integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" |
| | | "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=" |
| | |
| | | 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" |
| | |
| | | "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" |
| | |
| | | "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" |
| | |
| | | "integrity" "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" |
| | | "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=" |
| | |
| | | "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" |
| | |
| | | "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" |
| | |
| | | "integrity" "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY=" |
| | | "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=" |
| | |
| | | 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" |
| | |
| | | dependencies: |
| | | "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=" |
| | |
| | | "integrity" "sha1-G/IH9LKPkVg2ZstfvTJ4hzAc1fQ=" |
| | | "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.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" |