mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-25 17:25:16 +03:00
Bringing in changes from the trunk
This commit is contained in:
commit
4c22f6e8c0
20 changed files with 396 additions and 123 deletions
55
.github/stale.yml
vendored
55
.github/stale.yml
vendored
|
@ -1,55 +0,0 @@
|
||||||
# Configuration for probot-stale - https://github.com/probot/stale
|
|
||||||
|
|
||||||
# Number of days of inactivity before an Issue or Pull Request becomes stale
|
|
||||||
daysUntilStale: 30
|
|
||||||
|
|
||||||
# Number of days of inactivity before a stale Issue or Pull Request is closed.
|
|
||||||
# Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
|
|
||||||
daysUntilClose: 7
|
|
||||||
|
|
||||||
# Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
|
|
||||||
exemptLabels:
|
|
||||||
- BUG
|
|
||||||
- Feature Request
|
|
||||||
- Pinned
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a project (defaults to false)
|
|
||||||
exemptProjects: false
|
|
||||||
|
|
||||||
# Set to true to ignore issues in a milestone (defaults to false)
|
|
||||||
exemptMilestones: true
|
|
||||||
|
|
||||||
# Label to use when marking as stale
|
|
||||||
staleLabel: Inactive
|
|
||||||
|
|
||||||
# Comment to post when marking as stale. Set to `false` to disable
|
|
||||||
markComment: >
|
|
||||||
This issue / pull request has been automatically marked as stale because it
|
|
||||||
has not had recent activity. It will be closed if no further activity occurs
|
|
||||||
within a week.
|
|
||||||
|
|
||||||
# Comment to post when removing the stale label.
|
|
||||||
# unmarkComment: >
|
|
||||||
# Your comment here.
|
|
||||||
|
|
||||||
# Comment to post when closing a stale Issue or Pull Request.
|
|
||||||
closeComment: >
|
|
||||||
Automatically closing as inactive.
|
|
||||||
|
|
||||||
# Limit the number of actions per hour, from 1-30. Default is 30
|
|
||||||
limitPerRun: 30
|
|
||||||
|
|
||||||
# Limit to only `issues` or `pulls`
|
|
||||||
# only: issues
|
|
||||||
|
|
||||||
# Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
|
|
||||||
# pulls:
|
|
||||||
# daysUntilStale: 30
|
|
||||||
# markComment: >
|
|
||||||
# This pull request has been automatically marked as stale because it has not had
|
|
||||||
# recent activity. It will be closed if no further activity occurs. Thank you
|
|
||||||
# for your contributions.
|
|
||||||
|
|
||||||
# issues:
|
|
||||||
# exemptLabels:
|
|
||||||
# - confirmed
|
|
31
.github/workflows/stale.yaml
vendored
Normal file
31
.github/workflows/stale.yaml
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
name: 'Close stale issues'
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: "30 4 * * *"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
stale:
|
||||||
|
name: 'Check and close stale issues'
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/stale@v3
|
||||||
|
with:
|
||||||
|
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
operations-per-run: 30
|
||||||
|
days-before-stale: 30
|
||||||
|
days-before-close: 7
|
||||||
|
stale-issue-message: >
|
||||||
|
This issue has been automatically marked as stale because it
|
||||||
|
has not had recent activity. It will be closed if no further activity occurs
|
||||||
|
within a week.
|
||||||
|
close-issue-message: 'Issue closed automatically as inactive.'
|
||||||
|
exempt-issue-labels: 'BUG,Feature Request,Pinned,Has Milestone'
|
||||||
|
stale-issue-label: 'Inactive'
|
||||||
|
stale-pr-message: >
|
||||||
|
This pull request has been automatically marked as stale because it
|
||||||
|
has not had recent activity. It will be closed if no further activity occurs
|
||||||
|
within a week.
|
||||||
|
close-pr-message: 'Pull request closed automatically as inactive.'
|
||||||
|
exempt-pr-labels: 'Pinned,Has Milestone'
|
||||||
|
stale-pr-label: 'Inactive'
|
|
@ -5657,6 +5657,10 @@
|
||||||
"message": "Saved",
|
"message": "Saved",
|
||||||
"description": "Saved action button in the VTX tab"
|
"description": "Saved action button in the VTX tab"
|
||||||
},
|
},
|
||||||
|
"vtxSmartAudioUnlocked": {
|
||||||
|
"message": "{{version}} unlocked",
|
||||||
|
"description": "Indicates if SA device is unlocked"
|
||||||
|
},
|
||||||
|
|
||||||
"mainHelpArmed": {
|
"mainHelpArmed": {
|
||||||
"message": "Motor Arming"
|
"message": "Motor Arming"
|
||||||
|
|
|
@ -31,6 +31,24 @@ class EscDshotDirectionComponent
|
||||||
static get HIGHLIGHTED_BUTTON_CLASS() { return "highlighted"; }
|
static get HIGHLIGHTED_BUTTON_CLASS() { return "highlighted"; }
|
||||||
static get RED_TEXT_CLASS() { return "red-text"; }
|
static get RED_TEXT_CLASS() { return "red-text"; }
|
||||||
|
|
||||||
|
static get _BUTTON_PUSH_DOWN_EVENT_TYPE()
|
||||||
|
{
|
||||||
|
if (GUI.isCordova()) {
|
||||||
|
return "touchstart";
|
||||||
|
} else {
|
||||||
|
return "mousedown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get _BUTTON_RELEASE_EVENT_TYPE()
|
||||||
|
{
|
||||||
|
if (GUI.isCordova()) {
|
||||||
|
return "touchend";
|
||||||
|
} else {
|
||||||
|
return "mouseup mouseout";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_readDom()
|
_readDom()
|
||||||
{
|
{
|
||||||
this._domAgreeSafetyCheckBox = $("#escDshotDirectionDialog-safetyCheckbox");
|
this._domAgreeSafetyCheckBox = $("#escDshotDirectionDialog-safetyCheckbox");
|
||||||
|
@ -117,8 +135,7 @@ class EscDshotDirectionComponent
|
||||||
|
|
||||||
_deactivateNormalReverseButtons()
|
_deactivateNormalReverseButtons()
|
||||||
{
|
{
|
||||||
if (null !== this._activationButtonTimeoutId)
|
if (null !== this._activationButtonTimeoutId) {
|
||||||
{
|
|
||||||
clearTimeout(this._activationButtonTimeoutId);
|
clearTimeout(this._activationButtonTimeoutId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +145,7 @@ class EscDshotDirectionComponent
|
||||||
|
|
||||||
_subscribeDirectionSpinButton(button, direction, buttonText)
|
_subscribeDirectionSpinButton(button, direction, buttonText)
|
||||||
{
|
{
|
||||||
button.on("mousedown touchstart", () => {
|
button.on(EscDshotDirectionComponent._BUTTON_PUSH_DOWN_EVENT_TYPE, () => {
|
||||||
this._sendCurrentEscSpinDirection(direction);
|
this._sendCurrentEscSpinDirection(direction);
|
||||||
this._motorIsSpinning = true;
|
this._motorIsSpinning = true;
|
||||||
button.text(this._releaseToStopText);
|
button.text(this._releaseToStopText);
|
||||||
|
@ -138,7 +155,7 @@ class EscDshotDirectionComponent
|
||||||
this._domSecondHint.addClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
this._domSecondHint.addClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
});
|
});
|
||||||
|
|
||||||
button.on("mouseup mouseout touchend", () => {
|
button.on(EscDshotDirectionComponent._BUTTON_RELEASE_EVENT_TYPE, () => {
|
||||||
if (this._motorIsSpinning) {
|
if (this._motorIsSpinning) {
|
||||||
button.text(buttonText);
|
button.text(buttonText);
|
||||||
this._motorIsSpinning = false;
|
this._motorIsSpinning = false;
|
||||||
|
@ -175,7 +192,7 @@ class EscDshotDirectionComponent
|
||||||
this._domMotorButtonsBlock.append(button);
|
this._domMotorButtonsBlock.append(button);
|
||||||
this._motorButtons[motorIndex] = button;
|
this._motorButtons[motorIndex] = button;
|
||||||
|
|
||||||
button.on("mousedown touchstart", () => {
|
button.on(EscDshotDirectionComponent._BUTTON_PUSH_DOWN_EVENT_TYPE, () => {
|
||||||
this._domSecondActionDiv.toggle(true);
|
this._domSecondActionDiv.toggle(true);
|
||||||
this._motorIsSpinning = true;
|
this._motorIsSpinning = true;
|
||||||
this._domActionHint.html(this._releaseButtonToStopText);
|
this._domActionHint.html(this._releaseButtonToStopText);
|
||||||
|
@ -185,7 +202,7 @@ class EscDshotDirectionComponent
|
||||||
this._motorDriver.spinMotor(this._selectedMotor);
|
this._motorDriver.spinMotor(this._selectedMotor);
|
||||||
});
|
});
|
||||||
|
|
||||||
button.on("mouseup mouseout touchend", () => {
|
button.on(EscDshotDirectionComponent._BUTTON_RELEASE_EVENT_TYPE, () => {
|
||||||
if (this._motorIsSpinning) {
|
if (this._motorIsSpinning) {
|
||||||
this._domActionHint.html(this._topHintText);
|
this._domActionHint.html(this._topHintText);
|
||||||
this._domActionHint.removeClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
this._domActionHint.removeClass(EscDshotDirectionComponent.RED_TEXT_CLASS);
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.escDshotDirection-Component .regular-button{
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-webkit-tap-highlight-color: transparent;
|
||||||
|
outline-style: none;
|
||||||
|
}
|
||||||
|
|
||||||
.escDshotDirection-ComponentHeader {
|
.escDshotDirection-ComponentHeader {
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
@ -100,12 +106,14 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
#escDshotDirectionDialog-NormalDialog .regular-button.pushed:hover {
|
@media (hover: hover) {
|
||||||
background-color: #993333;
|
#escDshotDirectionDialog-NormalDialog .regular-button.pushed:hover {
|
||||||
}
|
background-color: #993333;
|
||||||
|
}
|
||||||
|
|
||||||
#escDshotDirectionDialog-NormalDialog .regular-button:hover {
|
#escDshotDirectionDialog-NormalDialog .regular-button:hover {
|
||||||
background-color: #993333;
|
background-color: #993333;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#escDshotDirectionDialog-MainContent .regular-button.highlighted {
|
#escDshotDirectionDialog-MainContent .regular-button.highlighted {
|
||||||
|
|
|
@ -1514,7 +1514,8 @@ dialog .dialog_toolbar .btn a.disabled {
|
||||||
@media all and (max-width: 575px) {
|
@media all and (max-width: 575px) {
|
||||||
dialog {
|
dialog {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
width: calc(100% - 2em);
|
width: calc(100% - 2em) !important;
|
||||||
|
height: auto !important;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
top: 56px;
|
top: 56px;
|
||||||
border-radius: unset;
|
border-radius: unset;
|
||||||
|
|
|
@ -23,10 +23,10 @@
|
||||||
margin-bottom: 0px;
|
margin-bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-motors #dialogMotorOutputReorder {
|
.tab-motors dialog {
|
||||||
width: 400px;
|
width: 400px;
|
||||||
height: 440px
|
height: 440px;
|
||||||
;}
|
}
|
||||||
|
|
||||||
.tab-motors #dialogMotorOutputReorderContentWrapper {
|
.tab-motors #dialogMotorOutputReorderContentWrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -47,11 +47,6 @@
|
||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-motors #escDshotDirectionDialog {
|
|
||||||
width: 400px;
|
|
||||||
height: 440px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-motors #escDshotDirectionDialog-ContentWrapper {
|
.tab-motors #escDshotDirectionDialog-ContentWrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-flow: column;
|
flex-flow: column;
|
||||||
|
@ -471,27 +466,4 @@
|
||||||
.tab-motors .motor_testing .telemetry li {
|
.tab-motors .motor_testing .telemetry li {
|
||||||
font-size: 6px;
|
font-size: 6px;
|
||||||
}
|
}
|
||||||
.tab-motors #dialogMotorOutputReorder {
|
|
||||||
position: fixed;
|
|
||||||
width: calc(100% - 2em);
|
|
||||||
bottom: 0;
|
|
||||||
top: 56px;
|
|
||||||
border-radius: unset;
|
|
||||||
border: none;
|
|
||||||
overflow: auto;
|
|
||||||
margin: 0;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-motors #escDshotDirectionDialog- {
|
|
||||||
position: fixed;
|
|
||||||
width: calc(100% - 2em);
|
|
||||||
bottom: 0;
|
|
||||||
top: 56px;
|
|
||||||
border-radius: unset;
|
|
||||||
border: none;
|
|
||||||
overflow: auto;
|
|
||||||
margin: 0;
|
|
||||||
height: auto;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,7 @@ const FC = {
|
||||||
VTXTABLE_BAND: null,
|
VTXTABLE_BAND: null,
|
||||||
VTXTABLE_POWERLEVEL: null,
|
VTXTABLE_POWERLEVEL: null,
|
||||||
VTX_CONFIG: null,
|
VTX_CONFIG: null,
|
||||||
|
VTX_DEVICE_STATUS: null,
|
||||||
|
|
||||||
resetState () {
|
resetState () {
|
||||||
// Using `Object.assign` instead of reassigning to
|
// Using `Object.assign` instead of reassigning to
|
||||||
|
@ -621,6 +622,7 @@ const FC = {
|
||||||
gyro_notch2_cutoff: 100,
|
gyro_notch2_cutoff: 100,
|
||||||
gyro_notch2_hz: 200,
|
gyro_notch2_hz: 200,
|
||||||
gyro_rpm_notch_harmonics: 3,
|
gyro_rpm_notch_harmonics: 3,
|
||||||
|
gyro_rpm_notch_min_hz: 100,
|
||||||
dterm_lowpass_hz: 100,
|
dterm_lowpass_hz: 100,
|
||||||
dterm_lowpass_dyn_min_hz: 150,
|
dterm_lowpass_dyn_min_hz: 150,
|
||||||
dterm_lowpass_dyn_max_hz: 250,
|
dterm_lowpass_dyn_max_hz: 250,
|
||||||
|
@ -635,6 +637,8 @@ const FC = {
|
||||||
dyn_notch_width_percent: 8,
|
dyn_notch_width_percent: 8,
|
||||||
dyn_notch_q_rpm: 250, // default with rpm filtering
|
dyn_notch_q_rpm: 250, // default with rpm filtering
|
||||||
dyn_notch_width_percent_rpm: 0,
|
dyn_notch_width_percent_rpm: 0,
|
||||||
|
dyn_notch_min_hz: 150,
|
||||||
|
dyn_notch_max_hz: 600,
|
||||||
};
|
};
|
||||||
|
|
||||||
this.DEFAULT_PIDS = [
|
this.DEFAULT_PIDS = [
|
||||||
|
@ -642,6 +646,8 @@ const FC = {
|
||||||
46, 90, 38, 22, 95,
|
46, 90, 38, 22, 95,
|
||||||
30, 90, 0, 0, 90,
|
30, 90, 0, 0, 90,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
this.VTX_DEVICE_STATUS = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
getSerialRxTypes: () => {
|
getSerialRxTypes: () => {
|
||||||
|
|
|
@ -113,6 +113,21 @@ GuiControl.prototype.interval_add = function (name, code, interval, first) {
|
||||||
return data;
|
return data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// name = string
|
||||||
|
// code = function reference (code to be executed)
|
||||||
|
// interval = time interval in miliseconds
|
||||||
|
// first = true/false if code should be ran initially before next timer interval hits
|
||||||
|
// condition = function reference with true/false result, a condition to be checked before every interval code execution
|
||||||
|
GuiControl.prototype.interval_add_condition = function (name, code, interval, first, condition) {
|
||||||
|
this.interval_add(name, () => {
|
||||||
|
if (condition()) {
|
||||||
|
code();
|
||||||
|
} else {
|
||||||
|
this.interval_remove(name);
|
||||||
|
}
|
||||||
|
}, interval, first);
|
||||||
|
}
|
||||||
|
|
||||||
// name = string
|
// name = string
|
||||||
GuiControl.prototype.interval_remove = function (name) {
|
GuiControl.prototype.interval_remove = function (name) {
|
||||||
for (let i = 0; i < this.interval_array.length; i++) {
|
for (let i = 0; i < this.interval_array.length; i++) {
|
||||||
|
|
|
@ -182,4 +182,5 @@ const MSPCodes = {
|
||||||
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
|
MSP2_MOTOR_OUTPUT_REORDERING: 0x3001,
|
||||||
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
|
MSP2_SET_MOTOR_OUTPUT_REORDERING: 0x3002,
|
||||||
MSP2_SEND_DSHOT_COMMAND: 0x3003,
|
MSP2_SEND_DSHOT_COMMAND: 0x3003,
|
||||||
|
MSP2_GET_VTX_DEVICE_STATUS: 0x3004,
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,12 +5,7 @@
|
||||||
const ledDirectionLetters = ['n', 'e', 's', 'w', 'u', 'd']; // in LSB bit order
|
const ledDirectionLetters = ['n', 'e', 's', 'w', 'u', 'd']; // in LSB bit order
|
||||||
const ledFunctionLetters = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l']; // in LSB bit order
|
const ledFunctionLetters = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b', 'l']; // in LSB bit order
|
||||||
const ledBaseFunctionLetters = ['c', 'f', 'a', 'l', 's', 'g', 'r']; // in LSB bit
|
const ledBaseFunctionLetters = ['c', 'f', 'a', 'l', 's', 'g', 'r']; // in LSB bit
|
||||||
let ledOverlayLetters;
|
let ledOverlayLetters = ['t', 'o', 'b', 'v', 'i', 'w']; // in LSB bit
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
|
||||||
ledOverlayLetters = ['t', 'o', 'b', 'n', 'i', 'w']; // in LSB bit
|
|
||||||
} else {
|
|
||||||
ledOverlayLetters = ['t', 'o', 'b', 'v', 'i', 'w']; // in LSB bit
|
|
||||||
}
|
|
||||||
|
|
||||||
function MspHelper() {
|
function MspHelper() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
@ -144,6 +139,17 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
FC.MOTOR_OUTPUT_ORDER[i] = data.readU8();
|
FC.MOTOR_OUTPUT_ORDER[i] = data.readU8();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case MSPCodes.MSP2_GET_VTX_DEVICE_STATUS:
|
||||||
|
FC.VTX_DEVICE_STATUS = null;
|
||||||
|
const dataLength = data.byteLength;
|
||||||
|
if (dataLength > 0) {
|
||||||
|
const vtxDeviceStatusData = new Uint8Array(dataLength);
|
||||||
|
for (let i = 0; i < dataLength; i++) {
|
||||||
|
vtxDeviceStatusData[i] = data.readU8();
|
||||||
|
}
|
||||||
|
FC.VTX_DEVICE_STATUS = vtxDeviceStatusFactory.createVtxDeviceStatus(vtxDeviceStatusData);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSPCodes.MSP_MOTOR_TELEMETRY:
|
case MSPCodes.MSP_MOTOR_TELEMETRY:
|
||||||
const telemMotorCount = data.readU8();
|
const telemMotorCount = data.readU8();
|
||||||
for (let i = 0; i < telemMotorCount; i++) {
|
for (let i = 0; i < telemMotorCount; i++) {
|
||||||
|
@ -1191,6 +1197,9 @@ MspHelper.prototype.process_data = function(dataHandler) {
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
|
if (semver.gte(FC.CONFIG.apiVersion, "1.20.0")) {
|
||||||
ledCount = data.byteLength / 4;
|
ledCount = data.byteLength / 4;
|
||||||
}
|
}
|
||||||
|
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
||||||
|
ledOverlayLetters = ['t', 'o', 'b', 'n', 'i', 'w']; // in LSB bit
|
||||||
|
}
|
||||||
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_41)) {
|
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_41)) {
|
||||||
// According to betaflight/src/main/msp/msp.c
|
// According to betaflight/src/main/msp/msp.c
|
||||||
// API 1.41 - add indicator for advanced profile support and the current profile selection
|
// API 1.41 - add indicator for advanced profile support and the current profile selection
|
||||||
|
@ -2574,9 +2583,13 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
|
||||||
|
|
||||||
buffer.push(ledIndex);
|
buffer.push(ledIndex);
|
||||||
|
|
||||||
|
if (semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_36)) {
|
||||||
|
ledOverlayLetters = ['t', 'o', 'b', 'n', 'i', 'w']; // in LSB bit
|
||||||
|
}
|
||||||
|
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, "1.20.0")) {
|
if (semver.lt(FC.CONFIG.apiVersion, "1.20.0")) {
|
||||||
let directionMask = 0;
|
let directionMask = 0;
|
||||||
for (const directionLetterIndex of led.directions) {
|
for (let directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
|
||||||
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
directionMask = bit_set(directionMask, bitIndex);
|
directionMask = bit_set(directionMask, bitIndex);
|
||||||
|
@ -2585,7 +2598,7 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
|
||||||
buffer.push16(directionMask);
|
buffer.push16(directionMask);
|
||||||
|
|
||||||
let functionMask = 0;
|
let functionMask = 0;
|
||||||
for (const functionLetterIndex of led.functions) {
|
for (let functionLetterIndex = 0; functionLetterIndex < led.functions.length; functionLetterIndex++) {
|
||||||
const bitIndex = ledFunctionLetters.indexOf(led.functions[functionLetterIndex]);
|
const bitIndex = ledFunctionLetters.indexOf(led.functions[functionLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
functionMask = bit_set(functionMask, bitIndex);
|
functionMask = bit_set(functionMask, bitIndex);
|
||||||
|
@ -2602,7 +2615,7 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
|
||||||
mask |= (led.y << 0);
|
mask |= (led.y << 0);
|
||||||
mask |= (led.x << 4);
|
mask |= (led.x << 4);
|
||||||
|
|
||||||
for (const functionLetterIndex of led.functions) {
|
for (let functionLetterIndex = 0; functionLetterIndex < led.functions.length; functionLetterIndex++) {
|
||||||
const fnIndex = ledBaseFunctionLetters.indexOf(led.functions[functionLetterIndex]);
|
const fnIndex = ledBaseFunctionLetters.indexOf(led.functions[functionLetterIndex]);
|
||||||
if (fnIndex >= 0) {
|
if (fnIndex >= 0) {
|
||||||
mask |= (fnIndex << 8);
|
mask |= (fnIndex << 8);
|
||||||
|
@ -2610,7 +2623,7 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const overlayLetterIndex of led.functions) {
|
for (let overlayLetterIndex = 0; overlayLetterIndex < led.functions.length; overlayLetterIndex++) {
|
||||||
const bitIndex = ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
|
const bitIndex = ledOverlayLetters.indexOf(led.functions[overlayLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
mask |= bit_set(mask, bitIndex + 12);
|
mask |= bit_set(mask, bitIndex + 12);
|
||||||
|
@ -2619,7 +2632,7 @@ MspHelper.prototype.sendLedStripConfig = function(onCompleteCallback) {
|
||||||
|
|
||||||
mask |= (led.color << 18);
|
mask |= (led.color << 18);
|
||||||
|
|
||||||
for (const directionLetterIndex of led.directions) {
|
for (let directionLetterIndex = 0; directionLetterIndex < led.directions.length; directionLetterIndex++) {
|
||||||
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
const bitIndex = ledDirectionLetters.indexOf(led.directions[directionLetterIndex]);
|
||||||
if (bitIndex >= 0) {
|
if (bitIndex >= 0) {
|
||||||
mask |= bit_set(mask, bitIndex + 22);
|
mask |= bit_set(mask, bitIndex + 22);
|
||||||
|
|
|
@ -242,8 +242,10 @@ const serial = {
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.connectionId = false;
|
self.connectionId = false;
|
||||||
|
CONFIGURATOR.virtualMode = false;
|
||||||
|
self.connectionType = false;
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -9,6 +9,7 @@ TABS.led_strip = {
|
||||||
TABS.led_strip.initialize = function (callback, scrollPosition) {
|
TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
let selectedColorIndex = null;
|
let selectedColorIndex = null;
|
||||||
let selectedModeColor = null;
|
let selectedModeColor = null;
|
||||||
|
const functionTag = '.function-';
|
||||||
|
|
||||||
if (semver.lt(FC.CONFIG.apiVersion, "1.20.0")) {
|
if (semver.lt(FC.CONFIG.apiVersion, "1.20.0")) {
|
||||||
TABS.led_strip.functions = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b'];
|
TABS.led_strip.functions = ['i', 'w', 'f', 'a', 't', 'r', 'c', 'g', 's', 'b'];
|
||||||
|
@ -68,8 +69,6 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
|
|
||||||
i18n.localizePage();
|
i18n.localizePage();
|
||||||
|
|
||||||
const functionTag = '.function-';
|
|
||||||
|
|
||||||
// Build Grid
|
// Build Grid
|
||||||
const theHTML = [];
|
const theHTML = [];
|
||||||
let theHTMLlength = 0;
|
let theHTMLlength = 0;
|
||||||
|
@ -316,6 +315,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
$('.mainGrid').selectable({
|
$('.mainGrid').selectable({
|
||||||
filter: ' > div',
|
filter: ' > div',
|
||||||
stop: function() {
|
stop: function() {
|
||||||
|
const functionsInSelection = [];
|
||||||
const directionsInSelection = [];
|
const directionsInSelection = [];
|
||||||
|
|
||||||
clearModeColorSelection();
|
clearModeColorSelection();
|
||||||
|
@ -566,7 +566,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
$(this).find('.wire').html(ledIndex);
|
$(this).find('.wire').html(ledIndex);
|
||||||
|
|
||||||
for (let modeIndex = 0; modeIndex < led.functions.length; modeIndex++) {
|
for (let modeIndex = 0; modeIndex < led.functions.length; modeIndex++) {
|
||||||
$(this).addClass(`function-'${led.functions[modeIndex]}`);
|
$(this).addClass(`function-${led.functions[modeIndex]}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let directionIndex = 0; directionIndex < led.directions.length; directionIndex++) {
|
for (let directionIndex = 0; directionIndex < led.directions.length; directionIndex++) {
|
||||||
|
@ -1052,7 +1052,7 @@ TABS.led_strip.initialize = function (callback, scrollPosition) {
|
||||||
const className = 'color-' + colorIndex;
|
const className = 'color-' + colorIndex;
|
||||||
if ($(this).is('.' + className)) {
|
if ($(this).is('.' + className)) {
|
||||||
$(this).find('.overlay-color').addClass(className);
|
$(this).find('.overlay-color').addClass(className);
|
||||||
$(this).find('.overlay-color').css('background-color', HsvToColor(FC.LED_COLORS[colorIndex]))
|
$(this).find('.overlay-color').css('background-color', HsvToColor(FC.LED_COLORS[colorIndex]));
|
||||||
} else {
|
} else {
|
||||||
if ($(this).find('.overlay-color').is('.' + className))
|
if ($(this).find('.overlay-color').is('.' + className))
|
||||||
$(this).find('.overlay-color').removeClass(className);
|
$(this).find('.overlay-color').removeClass(className);
|
||||||
|
|
|
@ -12,6 +12,39 @@ TABS.vtx = {
|
||||||
analyticsChanges: {},
|
analyticsChanges: {},
|
||||||
updating: true,
|
updating: true,
|
||||||
env: new djv(),
|
env: new djv(),
|
||||||
|
get _DEVICE_STATUS_UPDATE_INTERVAL_NAME() {
|
||||||
|
return "vtx_device_status_request";
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TABS.vtx.isVtxDeviceStatusNotReady = function()
|
||||||
|
{
|
||||||
|
const isReady = (null !== FC.VTX_DEVICE_STATUS) && (FC.VTX_DEVICE_STATUS.deviceIsReady);
|
||||||
|
return !isReady;
|
||||||
|
};
|
||||||
|
|
||||||
|
TABS.vtx.updateVtxDeviceStatus = function()
|
||||||
|
{
|
||||||
|
MSP.send_message(MSPCodes.MSP2_GET_VTX_DEVICE_STATUS, false, false, vtxDeviceStatusReceived);
|
||||||
|
|
||||||
|
function vtxDeviceStatusReceived()
|
||||||
|
{
|
||||||
|
$("#vtx_type_description").text(TABS.vtx.getVtxTypeString());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
TABS.vtx.getVtxTypeString = function()
|
||||||
|
{
|
||||||
|
let result = i18n.getMessage(`vtxType_${FC.VTX_CONFIG.vtx_type}`);
|
||||||
|
|
||||||
|
const isSmartAudio = VtxDeviceTypes.VTXDEV_SMARTAUDIO === FC.VTX_CONFIG.vtx_type;
|
||||||
|
const isVtxDeviceStatusReceived = null !== FC.VTX_DEVICE_STATUS;
|
||||||
|
|
||||||
|
if (isSmartAudio && isVtxDeviceStatusReceived) {
|
||||||
|
result += ` ${FC.VTX_DEVICE_STATUS.smartAudioVersion}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
};
|
};
|
||||||
|
|
||||||
TABS.vtx.initialize = function (callback) {
|
TABS.vtx.initialize = function (callback) {
|
||||||
|
@ -55,7 +88,19 @@ TABS.vtx.initialize = function (callback) {
|
||||||
vtx_config();
|
vtx_config();
|
||||||
|
|
||||||
function vtx_config() {
|
function vtx_config() {
|
||||||
MSP.send_message(MSPCodes.MSP_VTX_CONFIG, false, false, vtxtable_bands);
|
MSP.send_message(MSPCodes.MSP_VTX_CONFIG, false, false, vtxConfigReceived);
|
||||||
|
}
|
||||||
|
|
||||||
|
function vtxConfigReceived() {
|
||||||
|
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_44)) {
|
||||||
|
GUI.interval_add_condition(self._DEVICE_STATUS_UPDATE_INTERVAL_NAME,
|
||||||
|
TABS.vtx.updateVtxDeviceStatus,
|
||||||
|
1000, false,
|
||||||
|
TABS.vtx.isVtxDeviceStatusNotReady
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
vtxtable_bands();
|
||||||
}
|
}
|
||||||
|
|
||||||
function vtxtable_bands() {
|
function vtxtable_bands() {
|
||||||
|
@ -196,11 +241,11 @@ TABS.vtx.initialize = function (callback) {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Supported?
|
// Supported?
|
||||||
const vtxSupported = FC.VTX_CONFIG.vtx_type !== 0 && FC.VTX_CONFIG.vtx_type !== 255;
|
const vtxSupported = FC.VTX_CONFIG.vtx_type !== VtxDeviceTypes.VTXDEV_UNSUPPORTED && FC.VTX_CONFIG.vtx_type !== VtxDeviceTypes.VTXDEV_UNKNOWN;
|
||||||
const vtxTableNotConfigured = vtxSupported && FC.VTX_CONFIG.vtx_table_available &&
|
const vtxTableNotConfigured = vtxSupported && FC.VTX_CONFIG.vtx_table_available &&
|
||||||
(FC.VTX_CONFIG.vtx_table_bands === 0 || FC.VTX_CONFIG.vtx_table_channels === 0 || FC.VTX_CONFIG.vtx_table_powerlevels === 0);
|
(FC.VTX_CONFIG.vtx_table_bands === 0 || FC.VTX_CONFIG.vtx_table_channels === 0 || FC.VTX_CONFIG.vtx_table_powerlevels === 0);
|
||||||
|
|
||||||
TABS.vtx.vtxTableFactoryBandsSupported = FC.VTX_CONFIG.vtx_type === 3;
|
TABS.vtx.vtxTableFactoryBandsSupported = FC.VTX_CONFIG.vtx_type === VtxDeviceTypes.VTXDEV_SMARTAUDIO;
|
||||||
|
|
||||||
$(".vtx_supported").toggle(vtxSupported);
|
$(".vtx_supported").toggle(vtxSupported);
|
||||||
$(".vtx_not_supported").toggle(!vtxSupported);
|
$(".vtx_not_supported").toggle(!vtxSupported);
|
||||||
|
@ -234,7 +279,7 @@ TABS.vtx.initialize = function (callback) {
|
||||||
const noMessage = i18n.getMessage("no");
|
const noMessage = i18n.getMessage("no");
|
||||||
|
|
||||||
$("#vtx_device_ready_description").text(FC.VTX_CONFIG.vtx_device_ready ? yesMessage : noMessage);
|
$("#vtx_device_ready_description").text(FC.VTX_CONFIG.vtx_device_ready ? yesMessage : noMessage);
|
||||||
$("#vtx_type_description").text(i18n.getMessage(`vtxType_${FC.VTX_CONFIG.vtx_type}`));
|
$("#vtx_type_description").text(self.getVtxTypeString());
|
||||||
$("#vtx_channel_description").text(FC.VTX_CONFIG.vtx_channel);
|
$("#vtx_channel_description").text(FC.VTX_CONFIG.vtx_channel);
|
||||||
$("#vtx_frequency_description").text(FC.VTX_CONFIG.vtx_frequency);
|
$("#vtx_frequency_description").text(FC.VTX_CONFIG.vtx_frequency);
|
||||||
$("#vtx_pit_mode_description").text(FC.VTX_CONFIG.vtx_pit_mode ? yesMessage : noMessage);
|
$("#vtx_pit_mode_description").text(FC.VTX_CONFIG.vtx_pit_mode ? yesMessage : noMessage);
|
||||||
|
@ -513,23 +558,23 @@ TABS.vtx.initialize = function (callback) {
|
||||||
|
|
||||||
switch (vtxType) {
|
switch (vtxType) {
|
||||||
|
|
||||||
case 0: // Unsupported
|
case VtxDeviceTypes.VTXDEV_UNSUPPORTED:
|
||||||
powerMinMax = {};
|
powerMinMax = {};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1: // RTC6705
|
case VtxDeviceTypes.VTXDEV_RTC6705:
|
||||||
powerMinMax = {min: 1, max: 3};
|
powerMinMax = {min: 1, max: 3};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 3: // SmartAudio
|
case VtxDeviceTypes.VTXDEV_SMARTAUDIO:
|
||||||
powerMinMax = {min: 1, max: 4};
|
powerMinMax = {min: 1, max: 4};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4: // Tramp
|
case VtxDeviceTypes.VTXDEV_TRAMP:
|
||||||
powerMinMax = {min: 1, max: 5};
|
powerMinMax = {min: 1, max: 5};
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 255: // Unknown
|
case VtxDeviceTypes.VTXDEV_UNKNOWN:
|
||||||
default:
|
default:
|
||||||
powerMinMax = {min: 0, max: 7};
|
powerMinMax = {min: 0, max: 7};
|
||||||
}
|
}
|
||||||
|
@ -969,6 +1014,8 @@ TABS.vtx.cleanup = function (callback) {
|
||||||
this.VTXTABLE_BAND_LIST = [];
|
this.VTXTABLE_BAND_LIST = [];
|
||||||
this.VTXTABLE_POWERLEVEL_LIST = [];
|
this.VTXTABLE_POWERLEVEL_LIST = [];
|
||||||
|
|
||||||
|
GUI.interval_remove(this._DEVICE_STATUS_UPDATE_INTERVAL_NAME);
|
||||||
|
|
||||||
if (callback) {
|
if (callback) {
|
||||||
callback();
|
callback();
|
||||||
}
|
}
|
||||||
|
|
19
src/js/utils/VtxDeviceStatus/Rtc6705DeviceStatus.js
Normal file
19
src/js/utils/VtxDeviceStatus/Rtc6705DeviceStatus.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class VtxDeviceStatusRtc6705 extends VtxDeviceStatus {
|
||||||
|
constructor(dataView)
|
||||||
|
{
|
||||||
|
super(dataView);
|
||||||
|
|
||||||
|
dataView.readU8(); // custom device status size
|
||||||
|
|
||||||
|
// Read other Tramp VTX device parameters here
|
||||||
|
}
|
||||||
|
|
||||||
|
static get staticDeviceStatusType()
|
||||||
|
{
|
||||||
|
return VtxDeviceTypes.VTXDEV_RTC6705;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtxDeviceStatusFactory.registerVtxDeviceStatusClass(VtxDeviceStatusRtc6705);
|
49
src/js/utils/VtxDeviceStatus/SmartAudioDeviceStatus.js
Normal file
49
src/js/utils/VtxDeviceStatus/SmartAudioDeviceStatus.js
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class VtxDeviceStatusSmartAudio extends VtxDeviceStatus {
|
||||||
|
constructor(dataView)
|
||||||
|
{
|
||||||
|
super(dataView);
|
||||||
|
|
||||||
|
dataView.readU8(); // custom device status size
|
||||||
|
|
||||||
|
this._version = dataView.readU8();
|
||||||
|
this._mode = dataView.readU8();
|
||||||
|
this._orfreq = dataView.readU16();
|
||||||
|
this._willBootIntoPitMode = Boolean(dataView.readU8());
|
||||||
|
}
|
||||||
|
|
||||||
|
get smartAudioVersion()
|
||||||
|
{
|
||||||
|
const sa = this._version * 100 + this._mode;
|
||||||
|
let result = "";
|
||||||
|
|
||||||
|
switch (this._version) {
|
||||||
|
case 1:
|
||||||
|
result = "1.0";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
result = "2.0";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
result = "2.1";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// unknown SA version
|
||||||
|
result = i18n.getMessage("vtxType_255");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (16 == this._mode) {
|
||||||
|
result = i18n.getMessage("vtxSmartAudioUnlocked", {"version": result});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get staticDeviceStatusType()
|
||||||
|
{
|
||||||
|
return VtxDeviceTypes.VTXDEV_SMARTAUDIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtxDeviceStatusFactory.registerVtxDeviceStatusClass(VtxDeviceStatusSmartAudio);
|
19
src/js/utils/VtxDeviceStatus/TrampDeviceStatus.js
Normal file
19
src/js/utils/VtxDeviceStatus/TrampDeviceStatus.js
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
class VtxDeviceStatusTramp extends VtxDeviceStatus {
|
||||||
|
constructor(dataView)
|
||||||
|
{
|
||||||
|
super(dataView);
|
||||||
|
|
||||||
|
dataView.readU8(); // custom device status size
|
||||||
|
|
||||||
|
// Read other Tramp VTX device parameters here
|
||||||
|
}
|
||||||
|
|
||||||
|
static get staticDeviceStatusType()
|
||||||
|
{
|
||||||
|
return VtxDeviceTypes.VTXDEV_TRAMP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vtxDeviceStatusFactory.registerVtxDeviceStatusClass(VtxDeviceStatusTramp);
|
79
src/js/utils/VtxDeviceStatus/VtxDeviceStatus.js
Normal file
79
src/js/utils/VtxDeviceStatus/VtxDeviceStatus.js
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const VtxDeviceTypes = {
|
||||||
|
VTXDEV_UNSUPPORTED: 0, // reserved for MSP
|
||||||
|
VTXDEV_RTC6705: 1,
|
||||||
|
// 2 reserved
|
||||||
|
VTXDEV_SMARTAUDIO: 3,
|
||||||
|
VTXDEV_TRAMP: 4,
|
||||||
|
VTXDEV_UNKNOWN: 0xFF,
|
||||||
|
};
|
||||||
|
|
||||||
|
class VtxDeviceStatus
|
||||||
|
{
|
||||||
|
constructor(dataView)
|
||||||
|
{
|
||||||
|
this._deviceIsReady = dataView.readU8();
|
||||||
|
const bandAndChannelAvailable = Boolean(dataView.readU8());
|
||||||
|
this._band = dataView.readU8();
|
||||||
|
this._channel = dataView.readU8();
|
||||||
|
|
||||||
|
if (!bandAndChannelAvailable) {
|
||||||
|
this._band = undefined;
|
||||||
|
this._channel = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const powerIndexAvailable = Boolean(dataView.readU8());
|
||||||
|
this._powerIndex = dataView.readU8();
|
||||||
|
|
||||||
|
if (!powerIndexAvailable) {
|
||||||
|
this._powerIndex = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const frequencyAvailable = Boolean(dataView.readU8());
|
||||||
|
this._frequency = dataView.readU16();
|
||||||
|
|
||||||
|
if (!frequencyAvailable) {
|
||||||
|
this._frequency = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vtxStatusAvailable = Boolean(dataView.readU8());
|
||||||
|
this._vtxStatus = dataView.readU32(); // pitmode and/or locked
|
||||||
|
|
||||||
|
if (!vtxStatusAvailable) {
|
||||||
|
this._vtxStatus = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._readPowerLevels(dataView);
|
||||||
|
}
|
||||||
|
|
||||||
|
_readPowerLevels(dataView)
|
||||||
|
{
|
||||||
|
this._levels = [];
|
||||||
|
this._powers = [];
|
||||||
|
const powerLevelCount = dataView.readU8();
|
||||||
|
|
||||||
|
for (let i = 0; i < powerLevelCount; i++)
|
||||||
|
{
|
||||||
|
this._levels.push(dataView.readU16());
|
||||||
|
this._powers.push(dataView.readU16());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
get deviceIsReady()
|
||||||
|
{
|
||||||
|
return this._deviceIsReady;
|
||||||
|
}
|
||||||
|
|
||||||
|
// overload this function in subclasses
|
||||||
|
static get staticDeviceStatusType()
|
||||||
|
{
|
||||||
|
return VtxDeviceTypes.VTXDEV_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
get deviceStatusType()
|
||||||
|
{
|
||||||
|
// returns result of overloaded static function "staticDeviceStatusType"
|
||||||
|
return this.constructor.staticDeviceStatusType;
|
||||||
|
}
|
||||||
|
}
|
40
src/js/utils/VtxDeviceStatus/VtxDeviceStatusFactory.js
Normal file
40
src/js/utils/VtxDeviceStatus/VtxDeviceStatusFactory.js
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
const vtxDeviceStatusFactory = {
|
||||||
|
_vtxDeviceStatusClasses: [],
|
||||||
|
|
||||||
|
// call this to register a new vtx type like SmartAudio, Tramp or Rtc6705
|
||||||
|
registerVtxDeviceStatusClass: function(vtxDeviceStatusClass)
|
||||||
|
{
|
||||||
|
this._vtxDeviceStatusClasses.push(vtxDeviceStatusClass);
|
||||||
|
},
|
||||||
|
|
||||||
|
createVtxDeviceStatus: function(byteArray)
|
||||||
|
{
|
||||||
|
const dataView = new DataView(byteArray.buffer);
|
||||||
|
|
||||||
|
const vtxTypeIndex = dataView.readU8();
|
||||||
|
const vtxDeviceStatusClass = this._getDeviceStatusClass(vtxTypeIndex);
|
||||||
|
|
||||||
|
return new vtxDeviceStatusClass(dataView);
|
||||||
|
},
|
||||||
|
|
||||||
|
_readVtxType: function(dataView)
|
||||||
|
{
|
||||||
|
return dataView.readU8();
|
||||||
|
},
|
||||||
|
|
||||||
|
_getDeviceStatusClass: function(vtxTypeIndex)
|
||||||
|
{
|
||||||
|
let result = this._vtxDeviceStatusClasses.find(
|
||||||
|
(vtxClass) => {
|
||||||
|
return vtxClass.staticDeviceStatusType === vtxTypeIndex;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (typeof result === 'undefined') {
|
||||||
|
result = VtxDeviceStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
};
|
|
@ -74,6 +74,11 @@
|
||||||
<script type="text/javascript" src="./js/utils/css.js"></script>
|
<script type="text/javascript" src="./js/utils/css.js"></script>
|
||||||
<script type="text/javascript" src="./js/utils/window_watchers.js"></script>
|
<script type="text/javascript" src="./js/utils/window_watchers.js"></script>
|
||||||
<script type="text/javascript" src="./js/utils/CommonUtils.js"></script>
|
<script type="text/javascript" src="./js/utils/CommonUtils.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/VtxDeviceStatus/VtxDeviceStatusFactory.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/VtxDeviceStatus/VtxDeviceStatus.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/VtxDeviceStatus/TrampDeviceStatus.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/VtxDeviceStatus/SmartAudioDeviceStatus.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/utils/VtxDeviceStatus/Rtc6705DeviceStatus.js"></script>
|
||||||
<script type="text/javascript" src="./js/injected_methods.js"></script>
|
<script type="text/javascript" src="./js/injected_methods.js"></script>
|
||||||
<script type="text/javascript" src="./js/ConfigStorage.js"></script>
|
<script type="text/javascript" src="./js/ConfigStorage.js"></script>
|
||||||
<script type="text/javascript" src="./js/data_storage.js"></script>
|
<script type="text/javascript" src="./js/data_storage.js"></script>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue