Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
932c1f7
Add option to disable 3D acceleration in settings
Lemontree-Softworks Dec 3, 2025
9bcf765
Update SITL binaries for 9.0.0-RC3
sensei-hacker Dec 7, 2025
c288607
Merge pull request #2464 from sensei-hacker/sitl-update-9.0.0-RC3
sensei-hacker Dec 7, 2025
d1c3720
Optimize logic conditions loading with configured mask
sensei-hacker Dec 8, 2025
e717a1f
Merge pull request #2465 from sensei-hacker/feature/logic-conditions-…
sensei-hacker Dec 8, 2025
66b6d82
Progressive settings loading for faster tab rendering
sensei-hacker Dec 8, 2025
a1c2145
Add null check for customElementItems array
sensei-hacker Dec 8, 2025
ec6cc6b
Pass settings promise to callback for optional await
sensei-hacker Dec 8, 2025
5bb233e
Make optimized logic condition loading compatible with earler 9.0-RX*…
sensei-hacker Dec 9, 2025
8b05f65
Merge pull request #2467 from sensei-hacker/remove-version-check-logi…
sensei-hacker Dec 9, 2025
159806a
Fix OSD tab race conditions with async data loading
sensei-hacker Dec 9, 2025
2df96a9
Make optimized logic condition loading compatible with earler 9.0-RX*…
sensei-hacker Dec 9, 2025
0773404
Fix transpiler CSE mutation bug: invalidate cache on variable mutation
sensei-hacker Dec 9, 2025
b2ad7c4
Add PID operand support for transpiler compile/decompile
sensei-hacker Dec 10, 2025
9f372e2
Fix decompiler handling of value computations vs boolean conditions
sensei-hacker Dec 10, 2025
3f56e3a
Tree-based decompiler with improved sticky syntax
sensei-hacker Dec 10, 2025
7e122eb
Improve decompiler readability: expression hoisting and var declarations
sensei-hacker Dec 10, 2025
5d8e3c1
Add flight.mode.* API for checking active flight modes
sensei-hacker Dec 10, 2025
d60a99a
Fix round-trip compilation for decompiled JavaScript code
sensei-hacker Dec 10, 2025
faa8bbf
Fix round-trip compilation for var latch = sticky() syntax
sensei-hacker Dec 10, 2025
90b0552
Fix round-trip compilation issues in transpiler
sensei-hacker Dec 10, 2025
77c7715
Fix duplicate variable declarations in decompiler round-trip
sensei-hacker Dec 11, 2025
1e1f7d8
Decompiler: Use explicit comparisons instead of truthy syntax
sensei-hacker Dec 11, 2025
229b74d
Extract extractValue() and extractIdentifier() to shared module
sensei-hacker Dec 11, 2025
1934ad9
Remove dead code from decompiler.js
sensei-hacker Dec 11, 2025
f1ec9b0
Remove more dead code from transpiler
sensei-hacker Dec 11, 2025
e146d22
added ru l10n
funkill Dec 11, 2025
33d5c11
added ru item
funkill Dec 11, 2025
ae7c040
Add examples for PID, flight modes, and updated sticky syntax
sensei-hacker Dec 11, 2025
e21559b
Merge pull request #2471 from funkill/russian-translation
sensei-hacker Dec 11, 2025
e087ffb
Refactor operand validation to declarative lookup table
sensei-hacker Dec 11, 2025
5deae4b
Refactor handleNot to use structural pattern matching
sensei-hacker Dec 11, 2025
3064d16
Normalize >= and <= with constants to save 1 LC per comparison
sensei-hacker Dec 11, 2025
e9566d4
Refactor condition_decompiler to use lookup tables
sensei-hacker Dec 11, 2025
05220a9
Track latch variables structurally instead of regex pattern matching
sensei-hacker Dec 11, 2025
e082e30
Track imports and inline declarations structurally in decompiler
sensei-hacker Dec 11, 2025
28436b9
Refactor action_decompiler hoisting from string-parsing to structural
sensei-hacker Dec 11, 2025
1de6a2b
Fix potential infinite recursion in extractValue parenthesized handling
sensei-hacker Dec 11, 2025
e5f9f1d
Fix duplicate hoisted variable names across assignments
sensei-hacker Dec 11, 2025
842efff
Output standalone conditions as external references
sensei-hacker Dec 11, 2025
63fa726
Fix gap markers to insert blank lines in decompiled output
sensei-hacker Dec 11, 2025
495dac6
Preserve visual gaps in round-trip: blank lines create disabled LCs
sensei-hacker Dec 11, 2025
14d2da8
Merge pull request #2470 from sensei-hacker/decompiler-pid
sensei-hacker Dec 11, 2025
5b9f4af
Add examples coverage test suite (24 tests)
sensei-hacker Dec 11, 2025
490be04
Fix CLI copy button - enable clipboard support detection
sensei-hacker Dec 12, 2025
47eae3e
Fix override architecture: centralize mapping, add 9 missing operations
sensei-hacker Dec 12, 2025
2c5520b
Fix headingTarget unit: degrees (0-359), not centidegrees
sensei-hacker Dec 12, 2025
fca0372
Fix decompiler to use correct operand per INAV firmware
sensei-hacker Dec 12, 2025
9d28839
Merge pull request #2472 from sensei-hacker/transpiler-simplification…
sensei-hacker Dec 12, 2025
a70f2e2
Merge pull request #2466 from sensei-hacker/feature/progressive-setti…
sensei-hacker Dec 12, 2025
790071b
Merge pull request #2454 from Scavanger/config-3d-acceleration
sensei-hacker Dec 13, 2025
a17053d
Apply suggestions from code review
sensei-hacker Dec 13, 2025
1f8332b
Fix motor number positioning in Mixer tab
sensei-hacker Dec 13, 2025
d01cf13
Fix handling of extra.parenthesized in extractValue
sensei-hacker Dec 13, 2025
af3f959
Merge pull request #2473 from sensei-hacker/fix-cli-clipboard
sensei-hacker Dec 13, 2025
5cb4ce9
Fix decompiler: OR precedence and missing override actions
sensei-hacker Dec 13, 2025
cdb3ab7
Fix decompiler: APPROX_EQUAL outputs approxEqual() function
sensei-hacker Dec 13, 2025
637b4d2
Fix decompiler: edge/delay output arrow function format
sensei-hacker Dec 13, 2025
539e518
Fix activator relationship preservation in decompiler (#9)
sensei-hacker Dec 13, 2025
3cc2dae
Fix NOT() bypassing hoisted vars with activators (#3)
sensei-hacker Dec 13, 2025
7c50084
Fix missing Edge/Delay patterns with no children (#10)
sensei-hacker Dec 13, 2025
7f13a47
Fix sticky variable scope bug (#5)
sensei-hacker Dec 13, 2025
8a077e1
Simplify activator hoisting: emit all vars at top in LC index order
sensei-hacker Dec 13, 2025
50af276
Fix transpiler: handle pre-declared sticky variables
sensei-hacker Dec 13, 2025
b0b7eea
Transpiler: Add !(a && b) → NAND, !(a || b) → NOR pattern recognition
sensei-hacker Dec 13, 2025
61390b7
Transpiler: Add ternary support, caching, and improve pattern recogni…
sensei-hacker Dec 13, 2025
0488cac
Decompiler: Fix redundant activator wrapping in hoisted variables
sensei-hacker Dec 13, 2025
b5faa31
Transpiler: Hoist duplicated root LCs and fix const variable resolution
sensei-hacker Dec 13, 2025
e51fb9d
Transpiler: Fix const variable duplication in round-trip compilation
sensei-hacker Dec 13, 2025
2eb6cc9
Transpiler: Add scoped hoisting and optimize decompiler output
sensei-hacker Dec 14, 2025
3ec4e79
Examples: Add let/const variables and ternary operator examples
sensei-hacker Dec 14, 2025
f0d9210
Merge upstream/maintenance-9.x into transpiler-additional-overrides
sensei-hacker Dec 14, 2025
8179fbe
Tests: Move jetrell test to regression tests, clean up debug files
sensei-hacker Dec 14, 2025
0645fdf
Transpiler: Always import all INAV objects, remove usedFeatures tracking
sensei-hacker Dec 14, 2025
ffc2cdd
i18n: Localize JavaScript Programming tab
sensei-hacker Dec 14, 2025
612b86c
i18n: Add Ukrainian, Japanese, and Chinese translations for JavaScrip…
sensei-hacker Dec 14, 2025
acce07d
transpiler: add line feeds to import for readability
sensei-hacker Dec 14, 2025
751eb04
error handle
error414 Dec 14, 2025
696f9ed
Fix receiver MSP control page nouislider migration
sensei-hacker Dec 15, 2025
5267c82
receiver_msp.js: remove debug logging
sensei-hacker Dec 15, 2025
d08e49c
Add Chrome DevTools Protocol remote debugging support
sensei-hacker Dec 18, 2025
95ca8ea
Update js/main/main.js
sensei-hacker Dec 18, 2025
96dca3c
Update js/main/main.js
sensei-hacker Dec 18, 2025
c8c819d
Merge pull request #2483 from sensei-hacker/add-remote-debugging-support
sensei-hacker Dec 18, 2025
c55d203
Fix async settings loading race condition in Configuration and Receiv…
sensei-hacker Dec 18, 2025
9e614a4
Apply Qodo bot suggestions: error handling and trigger optimization
sensei-hacker Dec 18, 2025
9986d94
Merge pull request #2474 from sensei-hacker/transpiler-additional-ove…
sensei-hacker Dec 19, 2025
e87f05f
Merge pull request #2475 from sensei-hacker/fix-mixer-motor-number-po…
sensei-hacker Dec 19, 2025
a8344d4
Merge pull request #2480 from sensei-hacker/fix-receiver-msp-nouislider
sensei-hacker Dec 19, 2025
eb65162
Merge pull request #2485 from sensei-hacker/fix-async-settings-triggers
sensei-hacker Dec 19, 2025
3dc3f8c
Merge pull request #2476 from error414/fix-serial-port--open
sensei-hacker Dec 19, 2025
a1be10b
Merge pull request #2487 from sensei-hacker/flight-axis-override-impl…
sensei-hacker Dec 19, 2025
2b7a2f9
Fix blackbox save to file functionality
sensei-hacker Dec 20, 2025
8bd229e
Fix auto-select target functionality in firmware flasher
sensei-hacker Dec 20, 2025
927f8ef
Refactor transpiler to use fully namespaced inav.* syntax
sensei-hacker Dec 21, 2025
44cae10
Fix RC channel boolean properties with inav. namespace
sensei-hacker Dec 21, 2025
5ae49fc
Add test runner for all 22 examples
sensei-hacker Dec 21, 2025
1efed60
Tests: Update test suite for namespaced syntax
sensei-hacker Dec 21, 2025
9effe21
Decompiler: Add inav. prefix to gvar, rc, and pid operands
sensei-hacker Dec 21, 2025
6aca22b
Add helper functions to inav.helpers namespace and validate usage
sensei-hacker Dec 21, 2025
cbb70ab
Simplify helper function namespace validation in expression_generator.js
sensei-hacker Dec 21, 2025
a3b9a9d
Refactor: Inline helper function namespace checking
sensei-hacker Dec 21, 2025
4e7743f
Refactor: Consistent namespace-based routing in property access checker
sensei-hacker Dec 21, 2025
30f27fc
Add comprehensive namespace validation tests
sensei-hacker Dec 21, 2025
74d75f1
Fix: Flight axis override backward compatibility
sensei-hacker Dec 21, 2025
508dc2d
Fix error handling to use .catch() for promise rejection
sensei-hacker Dec 21, 2025
0cf3278
Adding recent Ukrainian translations for INAV 9 RC
smsnvc Dec 21, 2025
5a87c1f
Adding recent Ukrainian translations for INAV 9 RC
smsnvc Dec 21, 2025
5ade699
Merge pull request #2488 from sensei-hacker/fix-dialog-undefined-main…
sensei-hacker Dec 21, 2025
768478f
Improve forEach check with duck typing for future-proofing
sensei-hacker Dec 21, 2025
a8b3790
Merge pull request #2489 from sensei-hacker/fix-auto-select-target-fo…
sensei-hacker Dec 21, 2025
c67df60
Merge branch 'maintenance-9.x' into Add-missing-Ukrainian-translation…
smsnvc Dec 21, 2025
c85b75a
Merge pull request #2491 from smsnvc/Add-missing-Ukrainian-translatio…
sensei-hacker Dec 21, 2025
da60941
Fix serial connection reliability issues
sensei-hacker Dec 23, 2025
9e45a79
Fix serial port handle leak causing "Cannot lock port" errors
sensei-hacker Dec 23, 2025
19af8c4
Merge pull request #2490 from sensei-hacker/fix-monaco-autocomplete-r…
sensei-hacker Dec 23, 2025
6cce81e
Merge pull request #2494 from sensei-hacker/fix-serial-connection-rel…
sensei-hacker Dec 23, 2025
212917f
Fix logic conditions loading to handle MSP errors
sensei-hacker Dec 23, 2025
5bf903c
Merge pull request #2495 from sensei-hacker/fix-logic-conditions-load…
sensei-hacker Dec 23, 2025
34d2696
Fix SITL binary path resolution for dev and packaged modes
sensei-hacker Dec 24, 2025
ac5180b
Merge pull request #2496 from sensei-hacker/fix-sitl-path-resolution
sensei-hacker Dec 24, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
128 changes: 128 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# INAV Configurator - Developer Guide

> **Maintainers:** Update this file when making architectural changes or adding major features.

## Overview

INAV Configurator is a cross-platform Electron desktop application for configuring INAV flight controllers. It supports multirotors, fixed-wing aircraft, rovers, and boats.

**Tech Stack:** Electron + Vite + jQuery + i18next

## Quick Start

```bash
yarn install # Install dependencies
yarn start # Run in development mode (hot reload)
yarn make # Build distributable packages
```

## Directory Structure

```
inav-configurator/
├── js/ # Main application source
│ ├── configurator_main.js # Renderer entry point (initializes UI)
│ ├── fc.js # Flight controller state model
│ ├── gui.js # Tab switching & UI management
│ ├── msp.js # MSP protocol encoder/decoder
│ ├── serial_backend.js # Connection orchestration
│ ├── main/ # Electron main process
│ │ ├── main.js # Main process entry
│ │ └── preload.js # IPC bridge (renderer↔main)
│ ├── connection/ # Connection layer (factory pattern)
│ │ ├── connectionSerial.js # Serial port
│ │ ├── connectionTcp.js # TCP/IP (SITL)
│ │ └── connectionBle.js # Bluetooth LE
│ ├── msp/ # MSP protocol helpers
│ │ ├── MSPCodes.js # Command codes
│ │ └── MSPHelper.js # Serialization (largest file)
│ └── transpiler/ # Logic conditions compiler
├── src/css/ # Stylesheets
│ └── tabs/ # Per-tab styles
├── locale/ # i18n translations (en, ja, uk, zh_CN)
├── resources/ # 3D models, OSD fonts, SITL binaries
├── index.html # Single-page app entry
├── forge.config.js # Electron Forge build config
└── vite.*.config.js # Vite build configs
```

## Architecture

### Data Flow

```
User → GUI Tab → MSP.send_message() → Serial Queue → Connection → Flight Controller
User ← GUI Update ← FC state object ← MSP.decode() ← Serial Data ←──────┘
```

### Key Subsystems

1. **Connection Layer** (`js/connection/`): Factory pattern abstracts serial, TCP, UDP, BLE
2. **MSP Protocol** (`js/msp/`): Binary protocol for FC communication (V1/V2 variants)
3. **FC State** (`js/fc.js`): Central state object (CONFIG, PID, SENSOR_DATA, GPS_DATA, etc.)
4. **Tab System** (`js/gui.js`): Tabs load dynamically; separate tabs for connected vs disconnected states

### MSP Request Pattern

```javascript
MSP.send_message(MSPCodes.MSP_SOME_CODE, payload, false, () => {
// FC state already updated, refresh UI here
updateUIFromState(FC.SOME_DATA);
});
```

## Adding a New Tab

1. Create tab JS file with `initialize()` and `cleanup()` functions
2. Register in `TABS` object
3. Add CSS in `src/css/tabs/`
4. Add HTML link in `index.html` (mode-connected or mode-disconnected list)
5. Add translation keys to `locale/en/messages.json`

## Adding New MSP Commands

1. Add command code to `js/msp/MSPCodes.js`
2. Add serialize/deserialize logic to `js/msp/MSPHelper.js`
3. Add state property to `js/fc.js`
4. Use in relevant tab

## Build Targets

| Platform | Command | Output |
|----------|---------|--------|
| Windows | `yarn make --platform win32` | MSI installer |
| macOS | `yarn make --platform darwin` | DMG |
| Linux | `yarn make --platform linux` | DEB, RPM |

## Key Files by Importance

| File | Purpose |
|------|---------|
| `js/msp/MSPHelper.js` | All MSP serialization (159KB - largest file) |
| `js/fc.js` | Flight controller state model |
| `js/serial_backend.js` | Connection management |
| `js/gui.js` | Tab switching, UI state |
| `js/configurator_main.js` | Application initialization |


## Code Patterns

- **jQuery** for DOM manipulation
- **Callbacks** for async (some Promises)
- **i18next** via `data-i18n` attributes: `<span data-i18n="key"></span>`
- **ES6 modules** throughout (`import`/`export`)

## Debugging

```bash
NODE_ENV=development yarn start # Dev mode
# Press Ctrl+Shift+I for DevTools
```

## Resources

- [INAV Firmware](https://github.com/iNavFlight/inav)
- [INAV Wiki](https://github.com/iNavFlight/inav/wiki)
- [INAV Discord](https://discord.gg/peg2hhbYwN)
- [Electron Docs](https://www.electronjs.org/docs)
33 changes: 33 additions & 0 deletions forge.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,39 @@ export default {
executableName: "inav-configurator",
asar: false,
icon: 'images/inav',
extraResource: [
'resources/public/sitl'
],
afterCopy: [
(buildPath, electronVersion, platform, arch, callback) => {
// Remove SITL binaries for other platforms/architectures to reduce package size
const sitlPath = path.join(buildPath, 'resources', 'sitl');
if (platform === 'win32') {
fs.rmSync(path.join(sitlPath, 'linux'), { recursive: true, force: true });
fs.rmSync(path.join(sitlPath, 'macos'), { recursive: true, force: true });
} else if (platform === 'darwin') {
fs.rmSync(path.join(sitlPath, 'linux'), { recursive: true, force: true });
fs.rmSync(path.join(sitlPath, 'windows'), { recursive: true, force: true });
} else if (platform === 'linux') {
fs.rmSync(path.join(sitlPath, 'macos'), { recursive: true, force: true });
fs.rmSync(path.join(sitlPath, 'windows'), { recursive: true, force: true });
// Remove wrong architecture
if (arch === 'x64') {
fs.rmSync(path.join(sitlPath, 'linux', 'arm64'), { recursive: true, force: true });
} else if (arch === 'arm64') {
// Move arm64 binary to linux root and remove x64
const arm64Binary = path.join(sitlPath, 'linux', 'arm64', 'inav_SITL');
const destBinary = path.join(sitlPath, 'linux', 'inav_SITL');
if (fs.existsSync(arm64Binary)) {
fs.rmSync(destBinary, { force: true });
fs.renameSync(arm64Binary, destBinary);
fs.rmSync(path.join(sitlPath, 'linux', 'arm64'), { recursive: true, force: true });
}
}
}
callback();
}
],
},
rebuildConfig: {},
plugins: [
Expand Down
9 changes: 9 additions & 0 deletions js/configurator_main.js
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,15 @@ $(function() {
var check = $(this).is(':checked');
store.set('update_notify', check);
});

if (store.get('disable_3d_acceleration', false)) {
$('div.disable_3d_acceleration input').prop('checked', true);
}

$('div.disable_3d_acceleration input').on('change', function () {
var check = $(this).is(':checked');
store.set('disable_3d_acceleration', check);
});

$('div.statistics input').on('change', function () {
var check = $(this).is(':checked');
Expand Down
31 changes: 27 additions & 4 deletions js/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,19 @@ import child_process from './child_process';

const __dirname = path.dirname(fileURLToPath(import.meta.url));

/**
* Returns the base path for SITL binaries.
* - In packaged mode: uses Electron's resourcesPath (where extraResource files are placed)
* - In dev mode: uses the source location in resources/public/sitl
*/
function getSitlBasePath() {
if (app.isPackaged) {
return path.join(process.resourcesPath, 'sitl');
} else {
return path.join(app.getAppPath(), 'resources', 'public', 'sitl');
}
}

const usbBootloaderIds = [
{ vendorId: 1155, productId: 57105},
{ vendorId: 11836, productId: 57105}
Expand All @@ -31,11 +44,21 @@ let selectBluetoothCallback = null;

const store = new Store();

// Workaround for some Linux systems: https://github.com/electron/electron/issues/32760
if (process.platform === 'linux') {
// Workaround for some Linux systems: https://github.com/electron/electron/issues/32760
if (store.get('disable_3d_acceleration', false)) {
app.disableHardwareAcceleration();
}

// Enable remote debugging in development mode
// This allows chrome://inspect and Playwright CDP connections
if (!app.isPackaged) { // Development mode (not packaged)
const port = process.env.CDP_PORT ?? '9222';
app.commandLine.appendSwitch('remote-debugging-port', port);
console.log(`[cdp] Remote debugging enabled on port ${port}`);
console.log(` Chrome DevTools: chrome://inspect`);
console.log(` CDP Endpoint: http://localhost:${port}`);
}

// In Electron the bluetooth device chooser didn't exist, so we have to build our own
function createDeviceChooser() {
bluetoothDeviceChooser = new BrowserWindow({
Expand Down Expand Up @@ -340,7 +363,7 @@ app.whenReady().then(() => {

ipcMain.handle('chmod', (_event, pathName, mode) => {
return new Promise(resolve => {
chmod(path.join(__dirname, 'sitl', pathName), mode, error => {
chmod(path.join(getSitlBasePath(), pathName), mode, error => {
if (error) {
resolve(error.message)
} else {
Expand All @@ -363,7 +386,7 @@ app.whenReady().then(() => {
});

ipcMain.on('startChildProcess', (_event, command, args, opts) => {
child_process.start(path.join(__dirname, 'sitl', command), args, opts, mainWindow);
child_process.start(path.join(getSitlBasePath(), command), args, opts, mainWindow);
});

ipcMain.on('killChildProcess', (_event) => {
Expand Down
59 changes: 55 additions & 4 deletions js/main/serial.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,49 @@ const serial = {
_serialport: null,
_id: 1,

connect: function(path, options, window) {
connect: async function(path, options, window) {
// Clean up any existing serial port to prevent handle leaks
if (this._serialport) {
try {
const oldPort = this._serialport;
this._serialport = null;
oldPort.removeAllListeners();
if (oldPort.isOpen) {
await new Promise(resolveClose => {
oldPort.close(() => resolveClose());
});
}
oldPort.destroy();
// Small delay to ensure OS releases the file handle
await new Promise(r => setTimeout(r, 100));
} catch (e) {
console.log('Cleanup error (ignored):', e.message);
}
}

return new Promise(resolve => {
try {
var openPortResolved = false;
this._serialport = new SerialPortStream({binding, path: path, baudRate: options.bitrate, autoOpen: true});
this._serialport.on('error', error => {
console.log('Serial port error:', error.message);
if (!window.isDestroyed()) {
window.webContents.send('serialError', error);
window.webContents.send('serialError', error);
}

// Clean up the serial port to prevent handle leaks
// This prevents "Resource temporarily unavailable Cannot lock port" errors
if (this._serialport) {
const failedPort = this._serialport;
this._serialport = null;
failedPort.removeAllListeners();
failedPort.destroy();
}

if(!openPortResolved) {
openPortResolved = true;
// Fixed: Report error correctly so connection handling works properly
resolve({error: true, msg: error.message || 'Serial port error'});
}
});

Expand All @@ -30,7 +66,12 @@ const serial = {
window.webContents.send('serialData', buffer);
}
});
resolve({error: false, id: this._id++});

this._serialport.on('open', () => {
openPortResolved = true;
resolve({error: false, id: this._id++});
});

} catch (err) {
resolve ({error: true, errorMsg: err});
}
Expand All @@ -39,14 +80,24 @@ const serial = {
close: function() {
return new Promise(resolve => {
if (this._serialport && this._serialport.isOpen) {
this._serialport.close(error => {
const port = this._serialport;
this._serialport = null;
port.close(error => {
if (error) {
resolve({error: true, msg: error})
} else {
resolve({error: false})
}
});
} else if (this._serialport) {
// Port exists but isn't open - destroy it to clean up
try {
this._serialport.destroy();
} catch (e) {
// Ignore cleanup errors
}
this._serialport = null;
resolve({error: false});
} else {
resolve({error: false})
}
Expand Down
3 changes: 2 additions & 1 deletion js/msp/MSPCodes.js
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,8 @@ var MSPCodes = {
MSP2_INAV_SAFEHOME: 0x2038,
MSP2_INAV_SET_SAFEHOME: 0x2039,

MSP2_INAV_LOGIC_CONDITIONS_SINGLE: 0x203B,
MSP2_INAV_LOGIC_CONDITIONS_SINGLE: 0x203B,
MSP2_INAV_LOGIC_CONDITIONS_CONFIGURED: 0x203C,

MSP2_INAV_LED_STRIP_CONFIG_EX: 0x2048,
MSP2_INAV_SET_LED_STRIP_CONFIG_EX: 0x2049,
Expand Down
Loading
Loading