├── .gitignore
├── README.md
├── browser.js
├── examples
├── DJIFlightRecord_2015-12-29_[19-05-48].txt
├── browser-example.html
├── example.js
└── output.json
├── index.js
├── lib
├── djibuffer.js
├── index.js
├── keys.js
└── model
│ ├── app-gps.js
│ ├── app-message.js
│ ├── center-battery.js
│ ├── custom.js
│ ├── deform.js
│ ├── details.js
│ ├── gimbal.js
│ ├── home.js
│ ├── osd.js
│ ├── rc-gps.js
│ ├── rc.js
│ ├── recover.js
│ └── smart-battery.js
├── package.json
└── webpack.config.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 |
5 | # Runtime data
6 | pids
7 | *.pid
8 | *.seed
9 |
10 | # Directory for instrumented libs generated by jscoverage/JSCover
11 | lib-cov
12 |
13 | # Coverage directory used by tools like istanbul
14 | coverage
15 |
16 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
17 | .grunt
18 |
19 | # node-waf configuration
20 | .lock-wscript
21 |
22 | # Compiled binary addons (http://nodejs.org/api/addons.html)
23 | build/Release
24 |
25 | # Dependency directory
26 | # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git
27 | node_modules
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # dji-log-parser
2 |
--------------------------------------------------------------------------------
/examples/DJIFlightRecord_2015-12-29_[19-05-48].txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mikeemoo/dji-log-parser/5c58666caaeab827f7edfb37ba147a79a20d462c/examples/DJIFlightRecord_2015-12-29_[19-05-48].txt
--------------------------------------------------------------------------------
/examples/browser-example.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
41 |
42 |
--------------------------------------------------------------------------------
/examples/example.js:
--------------------------------------------------------------------------------
1 | var DJIParser = require("../index");
2 | var fs = require("fs");
3 |
4 | var parser = new DJIParser();
5 | var imageIndex = 1;
6 |
7 | parser.on("OSD", function(obj) {
8 | console.log(obj.getHeight());
9 | });
10 |
11 | parser.on("IMAGE", function(obj) {
12 | fs.writeFileSync("image"+(imageIndex++)+".jpg", obj.buffer, "binary");
13 | });
14 |
15 | parser.parse(fs.readFileSync("DJIFlightRecord_2015-12-29_[19-05-48].txt"));
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | module.exports = require("./lib");
--------------------------------------------------------------------------------
/lib/djibuffer.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var ByteBuffer = require("bytebuffer");
4 | var tmpBuffer = new ByteBuffer(32, true);
5 |
6 | function DJIBuffer(buffer, index, key) {
7 | this.buffer = buffer;
8 | this.index = index;
9 | this.key = key || [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0];
10 | }
11 |
12 | DJIBuffer.prototype.clearCopyAndDecode = function(offset, length) {
13 | tmpBuffer.fill(0, 0, tmpBuffer.length);
14 | this.buffer.copyTo(tmpBuffer, 0, this.index + offset, this.index + offset + length);
15 | for(var i=0; i 6;
66 | // packets start at offset 12
67 | var offset = 12;
68 |
69 | // parse records are located before Details section
70 | while (offset < (detailsOffset || buffer.limit - 4)) {
71 |
72 | if (this.isFrame(buffer, offset)) {
73 | offset = this.extractFrame(buffer, offset, isEncrypted);
74 | continue;
75 | }
76 |
77 | if (this.isImage(buffer, offset)) {
78 | offset = this.extractImage(buffer, offset);
79 | continue;
80 | }
81 | offset++;
82 | }
83 |
84 | // parse Details
85 | if (detailsOffset > 0) {
86 | this.emit('DETAILS', new Details(buffer, detailsOffset));
87 | }
88 | }
89 |
90 | DJIParser.prototype.isFrame = function(buffer, offset) {
91 | var tId = buffer.readUint8(offset++);
92 | var length = buffer.readUint8(offset++);
93 | if (offset + length > buffer.limit - 1) {
94 | return false;
95 | }
96 |
97 | var end = buffer.readUint8(offset + length);
98 | return tId != 0 && end == 0xFF;
99 | }
100 |
101 | DJIParser.prototype.isImage = function(buffer, offset) {
102 | var header = buffer.readUInt32(offset);
103 | return header == 3774863615; // JFIF header 0xFF 0xD8 0xFF 0xE0
104 | }
105 |
106 | DJIParser.prototype.extractFrame = function(buffer, offset, isEncrypted) {
107 | // first byte of a packet is 'type'
108 | var tId = buffer.readUint8(offset++);
109 | var type = types[tId];
110 |
111 | // second byte is packet length
112 | var length = buffer.readUint8(offset++);
113 |
114 | var key;
115 | var dataOffset = offset;
116 | var dataLength = length;
117 |
118 | // Get key if frame is encrypted
119 | if (isEncrypted) {
120 | var byteKey = buffer.readUint8(offset);
121 | key = keys[((tId - 1) * 256) + byteKey];
122 | dataOffset ++;
123 | dataLength -= 2;
124 | }
125 |
126 | var data = null;
127 |
128 | switch (type) {
129 | case "OSD":
130 | data = new OSD(buffer, dataOffset, key);
131 | break;
132 | case "DEFORM":
133 | data = new Deform(buffer, dataOffset, key);
134 | break;
135 | case "SMART_BATTERY":
136 | data = new SmartBattery(buffer, dataOffset, key);
137 | break;
138 | case "GIMBAL":
139 | data = new Gimbal(buffer, dataOffset, key);
140 | break;
141 | case "RC":
142 | data = new RC(buffer, dataOffset, key);
143 | break;
144 | case "CUSTOM":
145 | data = new Custom(buffer, dataOffset, key);
146 | break;
147 | case "RC_GPS":
148 | data = new RCGPS(buffer, dataOffset, key);
149 | break;
150 | case "CENTER_BATTERY":
151 | data = new CenterBattery(buffer, dataOffset, key);
152 | break;
153 | case "HOME":
154 | data = new Home(buffer, dataOffset, key);
155 | break;
156 | case "RECOVER":
157 | data = new Recover(buffer, dataOffset, key);
158 | break;
159 | case "APP_TIP":
160 | case "APP_WARN":
161 | data = new AppMessage(buffer, dataOffset, dataLength, key);
162 | break;
163 | case "APP_GPS":
164 | data = new AppGPS(buffer, dataOffset, key);
165 | break;
166 | }
167 |
168 | if (data !== null) {
169 | this.emit(type, data);
170 | this.lastMessages[type] = data;
171 | }
172 |
173 | return offset + length + 1;
174 | }
175 |
176 | DJIParser.prototype.extractImage = function(buffer, offset) {
177 | for (var endOffset = offset; endOffset < buffer.limit; endOffset++) {
178 | if (buffer.readUint16(endOffset) == 55807) { // End JFIF marker 0xFF 0xD9
179 | this.emit("IMAGE", buffer.copy(offset, endOffset + 2));
180 | break;
181 | }
182 | }
183 | return endOffset + 2;
184 | }
185 |
186 | if (typeof window != "undefined") {
187 | window.DJIParser = DJIParser;
188 | }
189 |
190 | module.exports = DJIParser;
191 |
--------------------------------------------------------------------------------
/lib/model/app-gps.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | function AppGPS(buffer, index, key) {
6 | DJIBuffer.call(this, buffer, index, key);
7 | }
8 |
9 | AppGPS.prototype = Object.create(DJIBuffer.prototype);
10 |
11 | AppGPS.prototype.getLongitude = function() {
12 | return this.readDouble(0, 8);
13 | }
14 |
15 | AppGPS.prototype.getLatitude = function() {
16 | return this.readDouble(8, 8);
17 | }
18 |
19 | AppGPS.prototype.getAccuracy = function() {
20 | return this.readFloat(16, 4);
21 | }
22 |
23 | module.exports = AppGPS;
24 |
--------------------------------------------------------------------------------
/lib/model/app-message.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | function AppMessage(buffer, index, length, key) {
6 | DJIBuffer.call(this, buffer, index, key);
7 | this.length = length;
8 | }
9 |
10 | AppMessage.prototype = Object.create(DJIBuffer.prototype);
11 |
12 | AppMessage.prototype.getMessage = function() {
13 | return this.readString(0, this.length);
14 | }
15 |
16 | module.exports = AppMessage;
--------------------------------------------------------------------------------
/lib/model/center-battery.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var CONN_STATUS = {
6 | 0: "NORMAL",
7 | 1: "INVALID",
8 | 2: "EXCEPTION",
9 | 100: "OTHER"
10 | };
11 |
12 | function CenterBattery(buffer, index, key) {
13 | DJIBuffer.call(this, buffer, index, key);
14 | }
15 |
16 | CenterBattery.prototype = Object.create(DJIBuffer.prototype);
17 |
18 | CenterBattery.prototype.getRelativeCapacity = function() {
19 | return this.readInt(0, 1);
20 | }
21 |
22 | CenterBattery.prototype.getCurrentPV = function() {
23 | return this.readInt(1, 2);
24 | }
25 |
26 | CenterBattery.prototype.getCurrentCapacity = function() {
27 | return this.readInt(3, 2);
28 | }
29 |
30 | CenterBattery.prototype.getFullCapacity = function() {
31 | return this.readInt(5, 2);
32 | }
33 |
34 | CenterBattery.prototype.getLife = function() {
35 | return this.readInt(7, 1);
36 | }
37 |
38 | CenterBattery.prototype.getLoopNum = function() {
39 | return this.readInt(8, 2);
40 | }
41 |
42 | CenterBattery.prototype.getErrorType = function() {
43 | return this.readInt(10, 4);
44 | }
45 |
46 | CenterBattery.prototype.getCurrent = function() {
47 | return this.readInt(14, 2);
48 | }
49 |
50 | CenterBattery.prototype.getPartVoltages = function() {
51 | var voltages = [];
52 | for (var i = 0; i < 6; i++) {
53 | voltages[i] = this.readInt(16 + (i * 2), 2);
54 | }
55 | return voltages;
56 | }
57 |
58 | CenterBattery.prototype.getSerialNo = function() {
59 | return this.readInt(28, 2);
60 | }
61 |
62 | CenterBattery.prototype.getProductDate = function() {
63 | var n2 = this.readInt(30, 2);
64 | return [
65 | ((n2 & 65024) >>> 9) + 1980,
66 | (n2 & 480) >>> 5,
67 | n2 & 31
68 | ];
69 | }
70 |
71 | CenterBattery.prototype.getTemperature = function() {
72 | return this.readInt(32, 2);
73 | }
74 |
75 | CenterBattery.prototype.getConnStatus = function() {
76 | return CONN_STATUS[this.readInt(34, 1)];
77 | }
78 |
79 | CenterBattery.prototype.totalStudyCycle = function() {
80 | return this.readInt(35, 2);
81 | }
82 |
83 | CenterBattery.prototype.lastStudyCycle = function() {
84 | return this.readInt(37, 2);
85 | }
86 |
87 | module.exports = CenterBattery;
--------------------------------------------------------------------------------
/lib/model/custom.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 |
6 | function Custom(buffer, index, key) {
7 | DJIBuffer.call(this, buffer, index, key);
8 | }
9 |
10 | Custom.prototype = Object.create(DJIBuffer.prototype);
11 |
12 | Custom.prototype.getDistance = function() {
13 | return this.readFloat(6,4);
14 | };
15 |
16 | Custom.prototype.getHSpeed = function() {
17 | return this.readFloat(2,4);
18 | };
19 |
20 | Custom.prototype.getDateTime = function() {
21 | return new Date(parseInt(this.readLong(10, 8).toString())).toISOString();
22 | };
23 |
24 | module.exports = Custom;
--------------------------------------------------------------------------------
/lib/model/deform.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var DEFORM_MODE = {
6 | 0: "PACK",
7 | 1: "PROTECT",
8 | 2: "NORMAL",
9 | 3: "OTHER"
10 | };
11 |
12 | var TRIPOD_STATUS = {
13 | 0: "UNKNOWN",
14 | 1: "FOLD_COMPLETE",
15 | 2: "FOLDING",
16 | 3: "STRETCH_COMPLETE",
17 | 4: "STRETCHING",
18 | 5: "STOP_DEFORMATION"
19 | };
20 |
21 | function Deform(buffer, index, key) {
22 | DJIBuffer.call(this, buffer, index, key);
23 | }
24 |
25 | Deform.prototype = Object.create(DJIBuffer.prototype);
26 |
27 | Deform.prototype.getDeformMode = function() {
28 | return DEFORM_MODE[(this.readInt(0, 1) & 48) >>> 4]
29 | }
30 |
31 | Deform.prototype.getDeformStatus = function() {
32 | return TRIPOD_STATUS[(this.readInt(0, 1) & 14) >>> 1];
33 | }
34 |
35 | Deform.prototype.isDeformProtected = function() {
36 | return (this.readInt(0, 1) & 1) != 0;
37 | }
38 |
39 |
40 | module.exports = Deform;
--------------------------------------------------------------------------------
/lib/model/details.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var APP_TYPE = {
6 | 0: "UNKNOWN",
7 | 1: "IOS",
8 | 2: "ANDROID"
9 | };
10 |
11 | function Details(buffer, index) {
12 | DJIBuffer.call(this, buffer, index);
13 | }
14 |
15 | Details.prototype = Object.create(DJIBuffer.prototype);
16 |
17 | Details.prototype.getSubStreet = function() {
18 | return this.buffer.toString("utf8", this.index, this.index+20);
19 | }
20 |
21 | Details.prototype.getStreet = function() {
22 | return this.buffer.toString("utf8", this.index+20, this.index+40);
23 | }
24 |
25 | Details.prototype.getCity = function() {
26 | return this.buffer.toString("utf8", this.index+40, this.index+60);
27 | }
28 |
29 | Details.prototype.getArea = function() {
30 | return this.buffer.toString("utf8", this.index+60, this.index+80);
31 | }
32 |
33 | Details.prototype.isFavorite = function() {
34 | return (this.readInt(80, 1) & 1) != 0;
35 | }
36 |
37 | Details.prototype.isNew = function() {
38 | return (this.readInt(81, 1) & 1) != 0;
39 | }
40 |
41 | Details.prototype.needsUpload = function() {
42 | return (this.readInt(82, 1) & 1) != 0;
43 | }
44 |
45 | Details.prototype.getRecordLineCount = function() {
46 | return this.readInt(83, 4);
47 | }
48 |
49 | Details.prototype.getUpdateTime = function() {
50 | return new Date(parseInt(this.readLong(91, 8).toString())).toISOString();
51 | }
52 |
53 | Details.prototype.getLongitude = function() {
54 | return this.readDouble(99, 8);
55 | }
56 |
57 | Details.prototype.getLatitude = function() {
58 | return this.readDouble(107, 8);
59 | }
60 |
61 | Details.prototype.getTotalDistance = function() {
62 | return this.readFloat(115, 4);
63 | }
64 |
65 | Details.prototype.getTotalTime = function() {
66 | return this.readInt(119, 4);
67 | }
68 |
69 | Details.prototype.getMaxHeight = function() {
70 | return this.readFloat(123, 4);
71 | }
72 |
73 | Details.prototype.getMaxHSpeed = function() {
74 | return this.readFloat(127, 4);
75 | }
76 |
77 | Details.prototype.getMaxVSpeed = function() {
78 | return this.readFloat(131, 4);
79 | }
80 |
81 | Details.prototype.getPhotoNum = function() {
82 | return this.readInt(135, 4);
83 | }
84 |
85 | Details.prototype.getVideoTime = function() {
86 | return this.readInt(139, 4);
87 | }
88 |
89 | Details.prototype.getAircraftSn = function() {
90 | return this.buffer.toString("utf8", this.index+267, this.index+277);
91 | }
92 |
93 | Details.prototype.getAircraftName = function() {
94 | return this.buffer.toString("utf8", this.index+278, this.index+302);
95 | }
96 |
97 | Details.prototype.getActiveTimestamp = function() {
98 | return new Date(parseInt(this.readLong(310, 8).toString())).toISOString();
99 | }
100 |
101 | Details.prototype.getCameraSn = function() {
102 | return this.buffer.toString("utf8", this.index+318, this.index+328);
103 | }
104 |
105 | Details.prototype.getRcSn = function() {
106 | return this.buffer.toString("utf8", this.index+328, this.index+338);
107 | }
108 |
109 | Details.prototype.getBatterySn = function() {
110 | return this.buffer.toString("utf8", this.index+338, this.index+348);
111 | }
112 |
113 | Details.prototype.getAppType = function() {
114 | return APP_TYPE[this.readInt(348, 1)];
115 | }
116 |
117 | Details.prototype.getAppVersion = function() {
118 | return this.readInt(349, 1)+'.'+this.readInt(350, 1)+'.'+this.readInt(351, 1);
119 | }
120 |
121 | module.exports = Details;
122 |
--------------------------------------------------------------------------------
/lib/model/gimbal.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var MODE = {
6 | 0: "YawNoFollow",
7 | 1: "FPV",
8 | 2: "YawFollow",
9 | 100: "OTHER"
10 | };
11 |
12 | function Gimbal(buffer, index, key) {
13 | DJIBuffer.call(this, buffer, index, key);
14 | }
15 |
16 | Gimbal.prototype = Object.create(DJIBuffer.prototype);
17 |
18 | Gimbal.prototype.getPitch = function() {
19 | return this.readShort(0, 2);
20 | }
21 |
22 | Gimbal.prototype.getRoll = function() {
23 | return this.readShort(2, 2);
24 | }
25 |
26 | Gimbal.prototype.getYaw = function() {
27 | return this.readShort(4, 2);
28 | }
29 |
30 | Gimbal.prototype.getRollAdjust = function() {
31 | return this.readShort(7, 1);
32 | }
33 |
34 | Gimbal.prototype.getYawAngle = function() {
35 | return this.readShort(8, 2);
36 | }
37 |
38 | Gimbal.prototype.getJoystickVerDirection = function() {
39 | return this.readInt(8, 1) & 3;
40 | }
41 |
42 | Gimbal.prototype.getJoystickHorDirection = function() {
43 | return (this.readInt(8, 1) >> 2) & 3;
44 | }
45 |
46 | Gimbal.prototype.isAutoCalibration = function() {
47 | return (this.readInt(10, 1) & 8) != 0;
48 | }
49 |
50 | Gimbal.prototype.autoCalibrationResult = function() {
51 | return (this.readInt(10, 1) & 16) != 0;
52 | }
53 |
54 | Gimbal.prototype.isPitchInLimit = function() {
55 | return (this.readInt(10, 1) & 1) != 0;
56 | }
57 |
58 | Gimbal.prototype.isRollInLimit = function() {
59 | return (this.readInt(10, 1) & 2) != 0;
60 | }
61 |
62 | Gimbal.prototype.isYawInLimit = function() {
63 | return (this.readInt(10, 1) & 4) != 0;
64 | }
65 |
66 | Gimbal.prototype.isStuck = function() {
67 | return (this.readInt(10, 1) & 64) != 0;
68 | }
69 |
70 | Gimbal.prototype.getMode = function() {
71 | return MODE[this.readInt(6, 1) >>> 6];
72 | }
73 |
74 | Gimbal.prototype.getSubMode = function() {
75 | return (this.readInt(6, 1) >> 5) & 1;
76 | }
77 |
78 | Gimbal.prototype.getVersion = function() {
79 | return this.readShort(11, 1) & 15;
80 | }
81 |
82 | Gimbal.prototype.isDoubleClick = function() {
83 | return (this.readShort(11, 1) & 32) != 0;
84 | }
85 |
86 | Gimbal.prototype.isTripleClick = function() {
87 | return (this.readShort(11, 1) & 64) != 0;
88 | }
89 |
90 | Gimbal.prototype.isSingleClick = function() {
91 | return (this.readShort(11, 1) & 128) != 0;
92 | }
93 |
94 | module.exports = Gimbal;
--------------------------------------------------------------------------------
/lib/model/home.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var GOHOME_STATUS = {
6 | 0: "STANDBY",
7 | 1: "PREASCENDING",
8 | 2: "ALIGN",
9 | 3: "ASCENDING",
10 | 4: "CRUISE",
11 | 7: "OTHER"
12 | };
13 |
14 | var IOC_MODE = {
15 | 1: "CourseLock",
16 | 2: "HomeLock",
17 | 3: "HotspotSurround",
18 | 100: "OTHER"
19 | }
20 |
21 | var MOTOR_ESCM_STATE = {
22 | 0: "NON_SMART",
23 | 1: "DISCONNECT",
24 | 2: "SIGNAL_ERROR",
25 | 3: "RESISTANCE_ERROR",
26 | 4: "BLOCK",
27 | 5: "NON_BALANCE",
28 | 6: "ESCM_ERROR",
29 | 7: "PROPELLER_OFF",
30 | 8: "MOTOR_IDLE",
31 | 9: "MOTOR_UP",
32 | 10: "MOTOR_OFF",
33 | 11: "NON_CONNECT",
34 | 100: "OTHER"
35 | };
36 |
37 | function Home(buffer, index, key) {
38 | DJIBuffer.call(this, buffer, index, key);
39 | }
40 |
41 | Home.prototype = Object.create(DJIBuffer.prototype);
42 |
43 | Home.prototype.getLongitude = function() {
44 | return this.readDouble(0, 8) * 180 / Math.PI;
45 | }
46 |
47 | Home.prototype.getLatitude = function() {
48 | return this.readDouble(8, 8) * 180 / Math.PI;
49 | }
50 |
51 | Home.prototype.getHeight = function() {
52 | return this.readFloat(16, 4);
53 | }
54 |
55 | Home.prototype.getIOCMode = function() {
56 | return IOC_MODE[(this.readInt(20, 2) & 57344) >>> 13];
57 | }
58 |
59 | Home.prototype.isIOCEnabled = function() {
60 | return ((this.readInt(20, 2) & 4096) >>> 12) != 0;
61 | }
62 |
63 | Home.prototype.isBeginnerMode = function() {
64 | return (this.readInt(20, 2) >> 11 & 1) != 0;
65 | }
66 |
67 | Home.prototype.isCompassCeleing = function() {
68 | return ((this.readInt(20, 2) & 1024) >>> 10) != 0;
69 | }
70 |
71 | Home.prototype.getCompassCeleStatus = function() {
72 | return (this.readInt(20, 2) & 768) >>> 8;
73 | }
74 |
75 | Home.prototype.hasGoHome = function() {
76 | return ((this.readInt(20, 2) & 128) >>> 7) != 0;
77 | }
78 |
79 | Home.prototype.getGoHomeStatus = function() {
80 | return GOHOME_STATUS[(this.readInt(20, 2) & 112) >>> 4];
81 | }
82 |
83 | Home.prototype.isReachLimitHeight = function() {
84 | return ((this.readInt(20, 2) & 32) >>> 5) != 0;
85 | }
86 |
87 | Home.prototype.isReachLimitDistance = function() {
88 | return ((this.readInt(20, 2) & 16) >>> 4) != 0;
89 | }
90 |
91 | Home.prototype.isDynamicHomePointEnabled = function() {
92 | return ((this.readInt(20, 2) & 8) >>> 3) != 0;
93 | }
94 |
95 | Home.prototype.getAircraftHeadDirection = function() {
96 | return (this.readInt(20, 2) & 4) >>> 2;
97 | }
98 |
99 | Home.prototype.getGoHomeMode = function() {
100 | return (this.readInt(20, 2) & 2) >>> 1;
101 | }
102 |
103 | Home.prototype.isHomeRecord = function() {
104 | return (this.readInt(20, 2) & 1) != 0;
105 | }
106 |
107 | Home.prototype.getGoHomeHeight = function() {
108 | return this.readInt(22, 2);
109 | }
110 |
111 | Home.prototype.getCourseLockAngle = function () {
112 | return this.readShort(24, 2);
113 | }
114 |
115 | Home.prototype.getDataRecorderStatus = function() {
116 | return this.readInt(26, 1);
117 | }
118 |
119 | Home.prototype.getDataRecorderRemainCapacity = function() {
120 | return this.readInt(27, 1);
121 | }
122 |
123 | Home.prototype.getDataRecorderRemainTime = function() {
124 | return this.readInt(28, 2);
125 | }
126 |
127 | Home.prototype.getCurDataRecorderFileIndex = function() {
128 | return this.readInt(30, 2);
129 | }
130 |
131 | Home.prototype.isFlycInSimulationMode = function() {
132 | return (this.readInt(32, 1) & 1) != 0;
133 | }
134 |
135 | Home.prototype.isFlycInNavigationMode = function() {
136 | return ((this.readInt(32, 1) & 2) >>> 1) != 0;
137 | }
138 |
139 | Home.prototype.isWingBroken = function() {
140 | return (this.readInt(32, 1) & 4096) != 0;
141 | }
142 |
143 | Home.prototype.getMotorEscmState = function() {
144 | var state = [];
145 | var value = this.readInt(32, 1);
146 | for (var i = 0; i < 8; i++) {
147 | state.push(MOTOR_ESCM_STATE[(value >> (i * 4)) & 15]);
148 | }
149 | }
150 |
151 | Home.prototype.getForceLandingHeight = function() {
152 | return this.readInt(45, 1);
153 | }
154 |
155 | module.exports = Home;
--------------------------------------------------------------------------------
/lib/model/osd.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var DRONE_TYPE = {
6 | 0: "Unknown",
7 | 1: "Inspire",
8 | 2: "P3S",
9 | 3: "P3X",
10 | 4: "P3C",
11 | 5: "OpenFrame",
12 | 6: "ACEONE",
13 | 7: "WKM",
14 | 8: "NAZA",
15 | 9: "A2",
16 | 10: "A3",
17 | 11: "P4",
18 | 13: "Mavic",
19 | 14: "PM820",
20 | 15: "P34K",
21 | 16: "wm220",
22 | 17: "Orange2",
23 | 18: "Pomato",
24 | 20: "N3",
25 | 23: "PM820PRO",
26 | 100: "None",
27 | 255: "NoFlyc",
28 | };
29 |
30 | var FLYC_STATE = {
31 | 0: "MANUAL",
32 | 1: "ATTI",
33 | 2: "ATTI_COURSE_LOCK",
34 | 3: "ATTI_HOVER",
35 | 4: "HOVER",
36 | 5: "GSP_BLAKE",
37 | 6: "GPS_ATTI",
38 | 7: "GPS_COURSE_LOCK",
39 | 8: "GPS_HOME_LOCK",
40 | 9: "GPS_HOT_POINT",
41 | 10: "ASSISTED_TAKEOFF",
42 | 11: "AUTO_TAKEOFF",
43 | 12: "AUTO_LANDING",
44 | 13: "ATTI_LANDING",
45 | 14: "GPS_WAYPOINT",
46 | 15: "GO_HOME",
47 | 16: "CLICK_GO",
48 | 17: "JOYSTICK",
49 | 18: "GPS_ATTI_WRISTBAND",
50 | 19: "CINEMATIC",
51 | 23: "ATTI_LIMITED",
52 | 24: "DRAW",
53 | 25: "GPS_FOLLOW_ME",
54 | 26: "ACTIVE_TRACK",
55 | 27: "TAP_FLY",
56 | 28: "PANO",
57 | 29: "FARMING",
58 | 30: "FPV",
59 | 31: "GPS_SPORT",
60 | 32: "GPS_NOVICE",
61 | 33: "CONFIRM_LANDING",
62 | 35: "TERRAIN_FOLLOW",
63 | 36: "PALM_CONTROL",
64 | 37: "QUICK_SHOT",
65 | 38: "TRIPOD",
66 | 39: "TRACK_SPOTLIGHT",
67 | 41: "MOTORS_JUST_STARTED",
68 | 43: "GPS_GENTLE",
69 | 255: "UNKNOWN"
70 | };
71 |
72 | var GOHOME_STATUS = {
73 | 0: "STANDBY",
74 | 1: "PREASCENDING",
75 | 2: "ALIGN",
76 | 3: "ASCENDING",
77 | 4: "CRUISE",
78 | 5: "BRAKING",
79 | 6: "BYPASSING",
80 | 7: "OTHER"
81 | };
82 |
83 | var BATTERY_TYPE = {
84 | 0: "UNKNOWN",
85 | 1: "NONSMART",
86 | 2: "SMART"
87 | };
88 |
89 | var MOTOR_START_FAILED_CAUSE = {
90 | 0: "None",
91 | 1: "CompassError",
92 | 2: "AssistantProtected",
93 | 3: "DeviceLocked",
94 | 4: "DistanceLimit",
95 | 5: "IMUNeedCalibration",
96 | 6: "IMUSNError",
97 | 7: "IMUWarning",
98 | 8: "CompassCalibrating",
99 | 9: "AttiError",
100 | 10: "NoviceProtected",
101 | 11: "BatteryCellError",
102 | 12: "BatteryCommuniteError",
103 | 13: "SeriouLowVoltage",
104 | 14: "SeriouLowPower",
105 | 15: "LowVoltage",
106 | 16: "TempureVolLow",
107 | 17: "SmartLowToLand",
108 | 18: "BatteryNotReady",
109 | 19: "SimulatorMode",
110 | 20: "PackMode",
111 | 21: "AttitudeAbNormal",
112 | 22: "UnActive",
113 | 23: "FlyForbiddenError",
114 | 24: "BiasError",
115 | 25: "EscError",
116 | 26: "ImuInitError",
117 | 27: "SystemUpgrade",
118 | 28: "SimulatorStarted",
119 | 29: "ImuingError",
120 | 30: "AttiAngleOver",
121 | 31: "GyroscopeError",
122 | 32: "AcceletorError",
123 | 33: "CompassFailed",
124 | 34: "BarometerError",
125 | 35: "BarometerNegative",
126 | 36: "CompassBig",
127 | 37: "GyroscopeBiasBig",
128 | 38: "AcceletorBiasBig",
129 | 39: "CompassNoiseBig",
130 | 40: "BarometerNoiseBig",
131 | 41: "InvalidSn",
132 | 44: "FLASH_OPERATING",
133 | 45: "GPS_DISCONNECT",
134 | 47: "SDCardException",
135 | 61: "IMUNoconnection",
136 | 62: "RCCalibration",
137 | 63: "RCCalibrationException",
138 | 64: "RCCalibrationUnfinished",
139 | 65: "RCCalibrationException2",
140 | 66: "RCCalibrationException3",
141 | 67: "AircraftTypeMismatch",
142 | 68: "FoundUnfinishedModule",
143 | 70: "CYRO_ABNORMAL",
144 | 71: "BARO_ABNORMAL",
145 | 72: "COMPASS_ABNORMAL",
146 | 73: "GPS_ABNORMAL",
147 | 74: "NS_ABNORMAL",
148 | 75: "TOPOLOGY_ABNORMAL",
149 | 76: "RC_NEED_CALI",
150 | 77: "INVALID_FLOAT",
151 | 78: "M600_BAT_TOO_LITTLE",
152 | 79: "M600_BAT_AUTH_ERR",
153 | 80: "M600_BAT_COMM_ERR",
154 | 81: "M600_BAT_DIF_VOLT_LARGE_1",
155 | 82: "M600_BAT_DIF_VOLT_LARGE_2",
156 | 83: "INVALID_VERSION",
157 | 84: "GimbalGyroError",
158 | 85: "GimbalPitchNoData",
159 | 86: "GimbalRollNoData",
160 | 87: "GimbalYawNoData",
161 | 88: "GimbalFirmIsUpdata",
162 | 89: "GimbalDisorder",
163 | 84: "GIMBAL_GYRO_ABNORMAL",
164 | 85: "GIMBAL_ESC_PITCH_NON_DATA",
165 | 86: "GIMBAL_ESC_ROLL_NON_DATA",
166 | 87: "GIMBAL_ESC_YAW_NON_DATA",
167 | 88: "GIMBAL_FIRM_IS_UPDATING",
168 | 89: "GIMBAL_DISORDER",
169 | 90: "GIMBAL_PITCH_SHOCK",
170 | 91: "GIMBAL_ROLL_SHOCK",
171 | 92: "GIMBAL_YAW_SHOCK",
172 | 90: "GimbalPitchShock",
173 | 91: "GimbalRollShock",
174 | 92: "GimbalYawShock",
175 | 93: "IMUcCalibrationFinished",
176 | 101: "BatVersionError",
177 | 102: "RTK_BAD_SIGNAL",
178 | 103: "RTK_DEVIATION_ERROR",
179 | 112: "ESC_CALIBRATING",
180 | 113: "GPS_SIGN_INVALID",
181 | 114: "GIMBAL_IS_CALIBRATING",
182 | 115: "LOCK_BY_APP",
183 | 116: "START_FLY_HEIGHT_ERROR",
184 | 117: "ESC_VERSION_NOT_MATCH",
185 | 118: "IMU_ORI_NOT_MATCH",
186 | 119: "STOP_BY_APP",
187 | 120: "COMPASS_IMU_ORI_NOT_MATCH",
188 | 256: "OTHER"
189 | };
190 |
191 | var FLIGHT_ACTION = {
192 | 0: "NONE",
193 | 1: "WARNING_POWER_GOHOME",
194 | 2: "WARNING_POWER_LANDING",
195 | 3: "SMART_POWER_GOHOME",
196 | 4: "SMART_POWER_LANDING",
197 | 5: "LOW_VOLTAGE_LANDING",
198 | 6: "LOW_VOLTAGE_GOHOME",
199 | 7: "SERIOUS_LOW_VOLTAGE_LANDING",
200 | 8: "RC_ONEKEY_GOHOME",
201 | 9: "RC_ASSISTANT_TAKEOFF",
202 | 10: "RC_AUTO_TAKEOFF",
203 | 11: "RC_AUTO_LANDING",
204 | 12: "APP_AUTO_GOHOME",
205 | 13: "APP_AUTO_LANDING",
206 | 14: "APP_AUTO_TAKEOFF",
207 | 15: "OUTOF_CONTROL_GOHOME",
208 | 16: "API_AUTO_TAKEOFF",
209 | 17: "API_AUTO_LANDING",
210 | 18: "API_AUTO_GOHOME",
211 | 19: "AVOID_GROUND_LANDING",
212 | 20: "AIRPORT_AVOID_LANDING",
213 | 21: "TOO_CLOSE_GOHOME_LANDING",
214 | 22: "TOO_FAR_GOHOME_LANDING",
215 | 23: "APP_WP_MISSION",
216 | 24: "WP_AUTO_TAKEOFF",
217 | 25: "GOHOME_AVOID",
218 | 26: "GOHOME_FINISH",
219 | 27: "VERT_LOW_LIMIT_LANDING",
220 | 28: "BATTERY_FORCE_LANDING",
221 | 29: "MC_PROTECT_GOHOME"
222 | }
223 |
224 | var NON_GPS_CAUSE = {
225 | 0: "ALREADY",
226 | 1: "FORBIN",
227 | 2: "GPSNUM_NONENOUGH",
228 | 3: "GPS_HDOP_LARGE",
229 | 4: "GPS_POSITION_NONMATCH",
230 | 5: "SPEED_ERROR_LARGE",
231 | 6: "YAW_ERROR_LARGE",
232 | 7: "COMPASS_ERROR_LARGE",
233 | 8: "UNKNOWN"
234 | };
235 |
236 | var IMU_INITFAIL_REASON = {
237 | 0: "MONITOR_ERROR",
238 | 1: "COLLECTING_DATA",
239 | 2: "GYRO_DEAD",
240 | 3: "ACCE_DEAD",
241 | 4: "COMPASS_DEAD",
242 | 5: "BAROMETER_DEAD",
243 | 6: "BAROMETER_NEGATIVE",
244 | 7: "COMPASS_MOD_TOO_LARGE",
245 | 8: "GYRO_BIAS_TOO_LARGE",
246 | 9: "ACCE_BIAS_TOO_LARGE",
247 | 10: "COMPASS_NOISE_TOO_LARGE",
248 | 11: "BAROMETER_NOISE_TOO_LARGE",
249 | 12: "WAITING_MC_STATIONARY",
250 | 13: "ACCE_MOVE_TOO_LARGE",
251 | 14: "MC_HEADER_MOVED",
252 | 15: "MC_VIBRATED",
253 | 16: "NONE"
254 | };
255 |
256 | var MOTOR_FAIL_REASON = {
257 | 94: "TAKEOFF_EXCEPTION",
258 | 95: "ESC_STALL_NEAR_GROUND",
259 | 96: "ESC_UNBALANCE_ON_GRD",
260 | 97: "ESC_PART_EMPTY_ON_GRD",
261 | 98: "ENGINE_START_FAILED",
262 | 99: "AUTO_TAKEOFF_LANCH_FAILED",
263 | 100: "ROLL_OVER_ON_GRD",
264 | 128: "OTHER"
265 | }
266 |
267 | var SDK_CONTROL_DEVICE = {
268 | 0: "RC",
269 | 1: "APP",
270 | 2: "ONBOARD_DEVICE",
271 | 3: "CAMERA",
272 | 128: "OTHER"
273 | };
274 |
275 |
276 | function OSD(buffer, index, key) {
277 | DJIBuffer.call(this, buffer, index, key);
278 | }
279 |
280 | OSD.prototype = Object.create(DJIBuffer.prototype);
281 |
282 | OSD.prototype.getLongitude = function() {
283 | return (this.readDouble(0, 8) * 180) / Math.PI;
284 | }
285 |
286 | OSD.prototype.getLatitude = function() {
287 | return (this.readDouble(8, 8) * 180) / Math.PI;
288 | }
289 |
290 | OSD.prototype.getHeight = function() {
291 | return this.readShort(16, 2) / 10;
292 | }
293 |
294 | OSD.prototype.getXSpeed = function() {
295 | return this.readShort(18, 2);
296 | }
297 |
298 | OSD.prototype.getYSpeed = function() {
299 | return this.readShort(20, 2);
300 | }
301 |
302 | OSD.prototype.getZSpeed = function() {
303 | return this.readShort(22, 2);
304 | }
305 |
306 | OSD.prototype.getPitch = function() {
307 | return this.readShort(24, 2);
308 | }
309 |
310 | OSD.prototype.getRoll = function() {
311 | return this.readShort(26, 2);
312 | }
313 |
314 | OSD.prototype.getYaw = function() {
315 | return this.readShort(28, 2);
316 | }
317 |
318 | OSD.prototype.getRcState = function() {
319 | return (this.readShort(30, 1) & 128) == 0;
320 | }
321 |
322 | OSD.prototype.getFlycState = function() {
323 | return FLYC_STATE[this.readShort(30, 1) & -129];
324 | }
325 |
326 | OSD.prototype.getAppCommand = function() {
327 | return this.readShort(31, 1);
328 | }
329 |
330 | OSD.prototype.canIOCWork = function() {
331 | return (this.readInt(32, 4) & 1) == 1;
332 | }
333 |
334 | OSD.prototype.groundOrSky = function() {
335 | return this.readInt(32, 4) >> 1 & 3;
336 | }
337 |
338 | OSD.prototype.isMotorUp = function() {
339 | return (this.readInt(32, 4) >> 3 & 1) == 1
340 | }
341 |
342 | OSD.prototype.isSwaveWork = function() {
343 | return (this.readInt(32, 4) & 16) != 0;
344 | }
345 |
346 | OSD.prototype.getGohomeStatus = function() {
347 | return GOHOME_STATUS[this.readInt(32, 4) >> 5 & 7];
348 | }
349 |
350 | OSD.prototype.isImuPreheated = function() {
351 | return (this.readInt(32, 4) & 4096) != 0;
352 | }
353 |
354 | OSD.prototype.isVisionUsed = function() {
355 | return (this.readInt(32, 4) & 256) != 0;
356 | }
357 |
358 | OSD.prototype.getVoltageWarning = function() {
359 | return (this.readInt(32, 4) & 1536) >>> 9;
360 | }
361 |
362 | OSD.prototype.getModeChannel = function() {
363 | return (this.readInt(32, 4) & 24576) >>> 13;
364 | }
365 |
366 | OSD.prototype.getCompassError = function() {
367 | return (this.readInt(32, 4) & 65536) != 0;
368 | }
369 |
370 | OSD.prototype.getWaveError = function() {
371 | return (this.readInt(32, 4) & 131072) != 0;
372 | }
373 |
374 | OSD.prototype.getGpsLevel = function() {
375 | return this.readInt(32, 4) >>> 18 & 15;
376 | }
377 |
378 | OSD.prototype.getBatteryType = function() {
379 | if (this.getDroneType() == "Unknown" || this.getDroneType() == "None") {
380 | return "SMART";
381 | }
382 | return BATTERY_TYPE[this.readInt(32, 4) >>> 22 & 3];
383 | }
384 |
385 | OSD.prototype.isAcceletorOverRange = function() {
386 | return (this.readInt(32, 4) >>> 24 & 1) != 0;
387 | }
388 |
389 | OSD.prototype.isVibrating = function() {
390 | return (this.readInt(32, 4) >>> 25 & 1) != 0;
391 | }
392 |
393 | OSD.prototype.isBarometerDeadInAir = function() {
394 | return (this.readInt(32, 4) >>> 26 & 1) != 0;
395 | }
396 |
397 | OSD.prototype.isMotorBlocked = function() {
398 | return (this.readInt(32, 4) >>> 27 & 1) != 0;
399 | }
400 |
401 | OSD.prototype.isNotEnoughForce = function() {
402 | return (this.readInt(32, 4) >>> 28 & 1) != 0;
403 | }
404 |
405 | OSD.prototype.isPropellerCatapult = function() {
406 | return (this.readInt(32, 4) >>> 29 & 1) != 0;
407 | }
408 |
409 | OSD.prototype.isGoHomeHeightModified = function() {
410 | return (this.readInt(32, 4) >>> 30 & 1) != 0;
411 | }
412 |
413 | OSD.prototype.isOutOfLimit = function() {
414 | return (this.readInt(32, 4) >>> 31 & 1) != 0;
415 | }
416 |
417 | OSD.prototype.getGpsNum = function() {
418 | return this.readShort(36, 1);
419 | }
420 |
421 | OSD.prototype.getFlightAction = function() {
422 | return FLIGHT_ACTION[this.readShort(37, 1)];
423 | }
424 |
425 | OSD.prototype.getMotorFailedCause = function() {
426 | var s2 = this.readShort(38, 1);
427 | if (s2 >> 7 == 0) {
428 | return "NONE";
429 | }
430 | return MOTOR_START_FAILED_CAUSE[this.readShort(38, 1) & 127];
431 | }
432 |
433 | OSD.prototype.getNonGpsCause = function() {
434 | return NON_GPS_CAUSE[this.readInt(39, 1) & 15];
435 | }
436 |
437 | OSD.prototype.getWaypointLimitMode = function() {
438 | return this.readInt(39, 1) & 16 == 16;
439 | }
440 |
441 | OSD.prototype.getBattery = function() {
442 | return this.readInt(40, 1);
443 | }
444 |
445 | OSD.prototype.getSwaveHeight = function() {
446 | return this.readShort(41, 1);
447 | }
448 |
449 | OSD.prototype.getFlyTime = function() {
450 | return this.readInt(42, 2) / 10;
451 | }
452 |
453 | OSD.prototype.getMotorRevolution = function() {
454 | return this.readShort(44, 1);
455 | }
456 |
457 | OSD.prototype.getFlycVersion = function() {
458 | return this.readInt(47, 1);
459 | }
460 |
461 | OSD.prototype.getDroneType = function() {
462 | return DRONE_TYPE[this.readInt(48, 1)];
463 | }
464 |
465 | OSD.prototype.getIMUinitFailReason = function() {
466 | return IMU_INITFAIL_REASON[this.readInt(49, 1)];
467 | }
468 |
469 | OSD.prototype.isImuInitError = function() {
470 | var reason = this.getIMUinitFailReason();
471 | return reason != "None" && reason != "ColletingData" && reason != "MonitorError";
472 | }
473 |
474 | OSD.prototype.getMotorFailReason = function() {
475 | return MOTOR_FAIL_REASON[this.readInt(50, 1)];
476 | }
477 |
478 | OSD.prototype.getSDKCtrlDevice = function() {
479 | return SDK_CONTROL_DEVICE[this.readInt(52, 1)];
480 | }
481 |
482 | module.exports = OSD;
--------------------------------------------------------------------------------
/lib/model/rc-gps.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | function RCGPS(buffer, index, key) {
6 | DJIBuffer.call(this, buffer, index, key);
7 | }
8 |
9 | RCGPS.prototype = Object.create(DJIBuffer.prototype);
10 |
11 | RCGPS.prototype.getLatitude = function() {
12 | return this.readInt(7, 4);
13 | }
14 |
15 | RCGPS.prototype.getLongitude = function() {
16 | return this.readInt(11, 4);
17 | }
18 |
19 | RCGPS.prototype.getXSpeed = function() {
20 | return this.readInt(15, 4) / 1000;
21 | }
22 |
23 | RCGPS.prototype.getYSpeed = function() {
24 | return this.readInt(19, 4) / 1000;
25 | }
26 |
27 | RCGPS.prototype.getGpsNum = function() {
28 | return this.readShort(23, 1);
29 | }
30 |
31 | RCGPS.prototype.getGpsStatus = function() {
32 | return this.readShort(28, 2) == 1;
33 | }
34 |
35 | module.exports = RCGPS;
--------------------------------------------------------------------------------
/lib/model/rc.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | function RC(buffer, index, key) {
6 | DJIBuffer.call(this, buffer, index, key);
7 | }
8 |
9 | RC.prototype = Object.create(DJIBuffer.prototype);
10 |
11 | RC.prototype.getAileron = function() {
12 | return this.readInt(0, 2);
13 | }
14 |
15 | RC.prototype.getElevator = function() {
16 | return this.readInt(2, 2);
17 | }
18 |
19 | RC.prototype.getThrottle = function() {
20 | return this.readInt(4, 2);
21 | }
22 |
23 | RC.prototype.getRudder = function() {
24 | return this.readInt(6, 2);
25 | }
26 |
27 | RC.prototype.getGyroValue = function() {
28 | return this.readInt(8, 2);
29 | }
30 |
31 | RC.prototype.getFootStool = function() {
32 | return (this.readInt(11, 1) >> 6 & 4) == 3;
33 | }
34 |
35 | RC.prototype.getMode = function() {
36 | return this.readInt(11, 1) >> 4 & 3;
37 | }
38 |
39 | RC.prototype.getGoHome = function() {
40 | return this.readInt(11, 1) >> 3 & 1;
41 | }
42 |
43 | RC.prototype.getCoronaChange = function() {
44 | return (this.readInt(10, 1) >> 7 & 1) == 1;
45 | }
46 |
47 | RC.prototype.getChangeDirection = function() {
48 | return this.readInt(10, 1) >> 6 & 1;
49 | }
50 |
51 | RC.prototype.getOffset = function() {
52 | return this.readInt(10, 1) >> 1 & 31;
53 | }
54 |
55 | RC.prototype.getIsPushCorona = function() {
56 | return this.readInt(10, 1) & 1;
57 | }
58 |
59 | RC.prototype.getRecordStatus = function() {
60 | return (this.readInt(12, 1) >> 7 & 1) == 1;
61 | }
62 |
63 | RC.prototype.getShutterStatus = function() {
64 | return (this.readInt(12, 1) >> 6 & 1) == 1;
65 | }
66 |
67 | RC.prototype.getPlayback = function() {
68 | return this.readInt(12, 1) >> 5 & 1;
69 | }
70 |
71 | RC.prototype.getCustom2 = function() {
72 | return this.readInt(12, 1) >> 3 & 1;
73 | }
74 |
75 | RC.prototype.getCustom1 = function() {
76 | return this.readInt(12, 1) >> 4 & 1;
77 | }
78 |
79 | RC.prototype.isGoHomeButtonPressed = function() {
80 | return ((this.readInt(11, 1) >> 3) & 1) != 0;
81 | }
82 |
83 | RC.prototype.getFootStool = function() {
84 | return ((this.readInt(11, 1) >> 6) & 3) == 3;
85 | }
86 |
87 | RC.prototype.getMode = function() {
88 | return (this.readInt(11, 1) >> 4) & 3;
89 | }
90 |
91 | RC.prototype.getBandWidth = function() {
92 | return this.readInt(13, 1);
93 | }
94 |
95 | module.exports = RC;
--------------------------------------------------------------------------------
/lib/model/recover.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | function Recover(buffer, index, key) {
6 | DJIBuffer.call(this, buffer, index, key);
7 | }
8 |
9 | var DRONE_TYPE = {
10 | 0: "Unknown",
11 | 1: "Inspire",
12 | 2: "P3S",
13 | 3: "P3X",
14 | 4: "P3C",
15 | 5: "OpenFrame",
16 | 7: "P4",
17 | 13: "Mavic",
18 | 100: "None"
19 | };
20 |
21 | var APP_TYPE = {
22 | 0: "UNKNOWN",
23 | 1: "IOS",
24 | 2: "ANDROID"
25 | };
26 |
27 | Recover.prototype = Object.create(DJIBuffer.prototype);
28 |
29 | Recover.prototype.getDroneType = function() {
30 | return DRONE_TYPE[this.readInt(0, 1)];
31 | }
32 |
33 | Recover.prototype.getAppType = function() {
34 | return APP_TYPE[this.readInt(1, 1)];
35 | }
36 |
37 | Recover.prototype.getAppVersion = function() {
38 | return this.readInt(2, 1)+'.'+this.readInt(3, 1)+'.'+this.readInt(4, 1);
39 | }
40 |
41 | Recover.prototype.getAircraftSn = function() {
42 | return this.readString(5, 10);
43 | }
44 |
45 | Recover.prototype.getAircraftName = function() {
46 | return this.readString(15, 24);
47 | }
48 |
49 | Recover.prototype.getActiveTimestamp = function() {
50 | return new Date(parseInt(this.readLong(47, 8).toString())).toISOString();
51 | }
52 |
53 | Recover.prototype.getCameraSn = function() {
54 | return this.readString(55, 10);
55 | }
56 |
57 | Recover.prototype.getRcSn = function() {
58 | return this.readString(65, 10);
59 | }
60 |
61 | Recover.prototype.getBatterySn = function() {
62 | return this.readString(75, 85);
63 | }
64 |
65 | module.exports = Recover;
66 |
--------------------------------------------------------------------------------
/lib/model/smart-battery.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | var DJIBuffer = require("../djibuffer");
4 |
5 | var DJI_BATTERY_STATUS = {
6 | 0: "UserBatteryReqGoHome",
7 | 1: "UserBatteryReqLand",
8 | 4: "SmartBatteryReqGoHome",
9 | 8: "SmartBatteryReqLand",
10 | 16: "MainVoltageLowGoHOme",
11 | 32: "MainVoltageLowLand",
12 | 64: "BatteryCellError",
13 | 128: "BatteryCommunicateError",
14 | 256: "VoltageLowNeedLand",
15 | 512: "BatteryTempVoltageLow",
16 | 1024: "BatteryNotReady",
17 | 2048: "BatteryFirstChargeNotFull",
18 | 69905: "OTHER"
19 | };
20 |
21 | function SmartBattery(buffer, index, key) {
22 | DJIBuffer.call(this, buffer, index, key);
23 | }
24 |
25 | SmartBattery.prototype = Object.create(DJIBuffer.prototype);
26 |
27 | SmartBattery.prototype.getUsefulTime = function() {
28 | return this.readInt(0, 2);
29 | }
30 |
31 | SmartBattery.prototype.getGoHomeTime = function() {
32 | return this.readInt(2, 2);
33 | }
34 |
35 | SmartBattery.prototype.getLandTime = function() {
36 | return this.readInt(4, 2);
37 | }
38 |
39 | SmartBattery.prototype.getGoHomeBattery = function() {
40 | return this.readInt(6, 2);
41 | }
42 |
43 | SmartBattery.prototype.getLandBattery = function() {
44 | return this.readInt(8, 2);
45 | }
46 |
47 | SmartBattery.prototype.getSafeFlyRadius = function() {
48 | return this.readFloat(10, 4);
49 | }
50 |
51 | SmartBattery.prototype.getVolumeConsume = function() {
52 | return this.readFloat(14, 4);
53 | }
54 |
55 | SmartBattery.prototype.getStatus = function() {
56 | return DJI_BATTERY_STATUS[this.readInt(18, 4)];
57 | }
58 |
59 | SmartBattery.prototype.getGoHomeStatus = function() {
60 | return this.readInt(22, 1);
61 | }
62 |
63 | SmartBattery.prototype.getGoHomeCountDown = function() {
64 | return this.readInt(23, 1);
65 | }
66 |
67 | SmartBattery.prototype.getVoltage = function() {
68 | return this.readInt(24, 2);
69 | }
70 |
71 | //SmartBattery.prototype.getBattery
72 |
73 | SmartBattery.prototype.getLowWarning = function() {
74 | return this.readInt(27, 1) & 127;
75 | }
76 |
77 | SmartBattery.prototype.getLowWarningGoHome = function() {
78 | return (this.readInt(27, 1) & 128) != 0;
79 | }
80 |
81 | SmartBattery.prototype.getSeriousLowWarning = function() {
82 | return this.readInt(28, 1) & 127;
83 | }
84 |
85 | SmartBattery.prototype.getSeriousLowWarningLanding = function() {
86 | return (this.readInt(28, 1) & 128) != 0;
87 | }
88 |
89 | SmartBattery.prototype.getVoltagePercent = function() {
90 | return this.readInt(29, 1);
91 | }
92 |
93 | module.exports = SmartBattery;
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dji-log-parser",
3 | "version": "0.0.4",
4 | "description": "",
5 | "author": "",
6 | "license": "MIT",
7 | "dependencies": {
8 | "bytebuffer": "^5.0.0",
9 | "long": "^3.0.1"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "https://github.com/mikeemoo/dji-log-parser.git"
14 | },
15 | "scripts": {
16 | "build": "webpack --config webpack.config.js"
17 | },
18 | "devDependencies": {
19 | "uglifyjs-webpack-plugin": "^1.0.0-beta.3",
20 | "webpack": "^3.7.1"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var UglifyJSPlugin = require('uglifyjs-webpack-plugin');
2 |
3 | module.exports = {
4 | entry: __dirname + "/lib",
5 | output: {
6 | path: __dirname,
7 | filename: "browser.js"
8 | },
9 | plugins: [
10 | new UglifyJSPlugin()
11 | ]
12 | };
--------------------------------------------------------------------------------