1
0
Fork 0
mirror of https://github.com/betaflight/betaflight-configurator.git synced 2025-07-21 23:35:22 +03:00

Fixed dimension reporting.

This commit is contained in:
mikeller 2018-08-02 22:02:19 +12:00
parent 8d5d81f9cf
commit a72c436e8e
12 changed files with 251 additions and 151 deletions

View file

@ -1,9 +1,32 @@
'use strict';
var Analytics = function (serviceName, trackingId, operatingSystem) {
this.eventBuilder = analytics.EventBuilder;
this.service = analytics.getService(serviceName);
this.tracker = this.service.getTracker(trackingId);
var Analytics = function (trackingId, userId, appName, appVersion, buildType, optOut, debugMode) {
this._trackingId = trackingId;
this.setOptOut(optOut);
this._analytics = analytics;
this._analytics.initialize(this._trackingId, {
storage: 'none',
clientId: userId,
debug: !!debugMode
});
// Make it work for the Chrome App:
this._analytics.set('forceSSL', true);
this._analytics.set('transport', 'xhr');
// Make it work for NW.js:
this._analytics.set('checkProtocolTask', null);
this._analytics.set('appName', appName);
this._analytics.set('appVersion', debugMode ? appVersion + '-debug' : appVersion);
this.EVENT_CATEGORIES = {
APPLICATION: 'Application',
FLIGHT_CONTROLLER: 'FlightController',
};
this.DATA = {
BOARD_TYPE: 'boardType',
@ -14,51 +37,71 @@ var Analytics = function (serviceName, trackingId, operatingSystem) {
};
this.DIMENSIONS = {
OS: 1,
BUILD_TYPE: 1,
BOARD_TYPE: 2,
FIRMWARE_TYPE: 3,
FIRMWARE_VERSION: 4,
API_VERSION: 5,
};
this.APPLICATION_EVENT = this.eventBuilder.builder()
.category('Application')
.dimension(this.DIMENSIONS.OS, operatingSystem);
this.setDimension(this.DIMENSIONS.BUILD_TYPE, buildType);
this.resetFlightControllerData();
};
Analytics.prototype.setTrackingPermitted = function (permitted) {
this.service.getConfig().addCallback(function(config) {
config.setTrackingPermitted(permitted);
});
Analytics.prototype.setDimension = function (dimension, value) {
var dimensionName = 'dimension' + dimension;
this._analytics.custom(dimensionName, value);
}
Analytics.prototype.send = function (event) {
this.tracker.send(event);
Analytics.prototype.sendEvent = function (category, action, options) {
options = options || {};
options.eventLabel = options.eventLabel || this.flightControllerData[this.DATA.MCU_ID];
this._analytics.event(category, action, options);
}
Analytics.prototype.sendChangeEvents = function (category, changeList) {
for (var actionName in changeList) {
if (changeList.hasOwnProperty(actionName)) {
var actionValue = changeList[actionName];
if (actionValue !== undefined) {
this.sendEvent(category, actionName, { eventLabel: actionValue });
}
}
}
}
Analytics.prototype.sendAppView = function (viewName) {
this.tracker.sendAppView(viewName);
this._analytics.screenview(viewName);
}
Analytics.prototype.rebuildFlightControllerEvent = function () {
this.FLIGHT_CONTROLLER_EVENT = this.eventBuilder.builder()
.category('FlightController')
.dimension(this.DIMENSIONS.BOARD_TYPE, this.flightControllerData[this.DATA.BOARD_TYPE])
.dimension(this.DIMENSIONS.FIRMWARE_TYPE, this.flightControllerData[this.DATA.FIRMWARE_TYPE])
.dimension(this.DIMENSIONS.FIRMWARE_VERSION, this.flightControllerData[this.DATA.FIRMWARE_VERSION])
.dimension(this.DIMENSIONS.API_VERSION, this.flightControllerData[this.DATA.API_VERSION]);
Analytics.prototype.sendTiming = function (category, timing, value) {
this._analytics.timing(category, timing, value);
}
Analytics.prototype.sendException = function (message) {
this._analytics.exception(message);
}
Analytics.prototype.setOptOut = function (optOut) {
window['ga-disable-' + this._trackingId] = !!optOut;
}
Analytics.prototype._rebuildFlightControllerEvent = function () {
this.setDimension(this.DIMENSIONS.BOARD_TYPE, this.flightControllerData[this.DATA.BOARD_TYPE]);
this.setDimension(this.DIMENSIONS.FIRMWARE_TYPE, this.flightControllerData[this.DATA.FIRMWARE_TYPE]);
this.setDimension(this.DIMENSIONS.FIRMWARE_VERSION, this.flightControllerData[this.DATA.FIRMWARE_VERSION]);
this.setDimension(this.DIMENSIONS.API_VERSION, this.flightControllerData[this.DATA.API_VERSION]);
}
Analytics.prototype.setFlightControllerData = function (property, value) {
this.flightControllerData[property] = value;
this.rebuildFlightControllerEvent();
this._rebuildFlightControllerEvent();
}
Analytics.prototype.resetFlightControllerData = function () {
this.flightControllerData = {};
this.rebuildFlightControllerEvent();
this._rebuildFlightControllerEvent();
}

View file

@ -99,11 +99,16 @@ var Features = function (config) {
self._features = features;
self._featureMask = 0;
self._analyticsChanges = {};
};
Features.prototype.getMask = function () {
var self = this;
analytics.sendChangeEvents(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self._analyticsChanges);
self._analyticsChanges = {};
return self._featureMask;
};
@ -127,6 +132,8 @@ Features.prototype.isEnabled = function (featureName) {
Features.prototype.generateElements = function (featuresElements) {
var self = this;
self._featureChanges = {};
var listElements = [];
for (var i = 0; i < self._features.length; i++) {
@ -191,29 +198,48 @@ Features.prototype.generateElements = function (featuresElements) {
}
};
Features.prototype.findFeatureByBit = function (bit) {
var self = this;
for (var i = 0; i < self._features.length; i++) {
if (self._features[i].bit == bit) {
return self._features[i];
}
}
}
Features.prototype.updateData = function (featureElement) {
var self = this;
if (featureElement.attr('type') === 'checkbox') {
var bit = featureElement.data('bit');
var featureValue;
if (featureElement.is(':checked')) {
self._featureMask = bit_set(self._featureMask, bit);
featureValue = 'On';
} else {
self._featureMask = bit_clear(self._featureMask, bit);
featureValue = 'Off';
}
self._analyticsChanges['Feature' + self.findFeatureByBit(bit).name] = featureValue;
} else if (featureElement.prop('localName') === 'select') {
var controlElements = featureElement.children();
var selectedBit = featureElement.val();
if (selectedBit !== -1) {
var featureName;
for (var i = 0; i < controlElements.length; i++) {
var bit = controlElements[i].value;
if (selectedBit === bit) {
self._featureMask = bit_set(self._featureMask, bit);
featureName = self.findFeatureByBit(bit).name;
} else {
self._featureMask = bit_clear(self._featureMask, bit);
}
}
if (featureName) {
self._analyticsChanges['Feature' + featureName] = 'On';
}
}
}
};

View file

@ -4,8 +4,8 @@ var analytics;
openNewWindowsInExternalBrowser();
//Asynchronous configuration to be done.
//When finish the startProcess() function must be called
// Asynchronous configuration to be done.
// When finish the startProcess() function must be called
$(document).ready(function () {
i18n.init(function() {
setupAnalytics();
@ -14,8 +14,7 @@ $(document).ready(function () {
});
function setupAnalytics() {
analytics = new Analytics('com.betaflight.configurator', 'UA-123002063-1', GUI.operating_system);
chrome.storage.local.get('userId', function (result) {
chrome.storage.local.get(['userId', 'analyticsOptOut'], function (result) {
var userId;
if (result.userId) {
userId = result.userId;
@ -23,17 +22,25 @@ function setupAnalytics() {
var uid = new ShortUniqueId();
userId = uid.randomUUID(13);
chrome.storage.local.set({'userId': userId});
chrome.storage.local.set({ 'userId': userId });
}
analytics.tracker.set('userId', userId);
var optOut = !!result.analyticsOptOut
analytics.tracker.set('sessionControl', 'start');
analytics.send(analytics.APPLICATION_EVENT.action('AppStart'))
var debugMode = process.versions['nw-flavor'] === 'sdk';
analytics = new Analytics('UA-123002063-1', userId, 'Betaflight Configurator', getManifestVersion(), GUI.operating_system, optOut, debugMode);
function logException(exception) {
analytics.sendException(exception.stack);
}
process.on('uncaughtException', logException);
analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppStart', { sessionControl: 'start' });
function sendCloseEvent() {
analytics.send(analytics.APPLICATION_EVENT.action('AppClose'))
analytics.tracker.set('sessionControl', 'end');
analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'AppClose', { sessionControl: 'end' })
}
try {
@ -303,13 +310,13 @@ function startProcess() {
chrome.storage.local.set({'analyticsOptOut': checked});
if (checked) {
analytics.send(analytics.APPLICATION_EVENT.action('OptOut'));
analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptOut');
}
analytics.setTrackingPermitted(!checked);
analytics.setOptOut(checked);
if (!checked) {
analytics.send(analytics.APPLICATION_EVENT.action('OptIn'));
analytics.sendEvent(analytics.EVENT_CATEGORIES.APPLICATION, 'OptIn');
}
}).change();
});

View file

@ -1,7 +1,7 @@
'use strict';
var mspHelper;
var analyticsTimer;
var connectionTimestamp;
function initializeSerialBackend() {
@ -126,11 +126,12 @@ function initializeSerialBackend() {
function finishClose(finishedCallback) {
var wasConnected = CONFIGURATOR.connectionValid;
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Disconnected'));
if (analyticsTimer) {
analyticsTimer.send();
analyticsTimer = undefined;
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Disconnected');
if (connectionTimestamp) {
var connectedTime = Date.now() - connectionTimestamp;
analytics.sendTiming(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Connected', connectedTime);
connectedTime = undefined;
}
analytics.resetFlightControllerData();
@ -241,8 +242,8 @@ function onOpen(openInfo) {
var uniqueDeviceIdentifier = CONFIG.uid[0].toString(16) + CONFIG.uid[1].toString(16) + CONFIG.uid[2].toString(16);
analytics.setFlightControllerData(analytics.DATA.MCU_ID, objectHash.sha1(uniqueDeviceIdentifier));
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('Connected'));
analyticsTimer = analytics.tracker.startTiming('FlightController', 'Connected');
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'Connected');
connectionTimestamp = Date.now();
GUI.log(i18n.getMessage('uniqueDeviceIdReceived', [uniqueDeviceIdentifier]));
if (semver.gte(CONFIG.apiVersion, "1.20.0")) {
@ -260,7 +261,7 @@ function onOpen(openInfo) {
});
});
} else {
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused'));
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'ConnectionRefused');
var dialog = $('.dialogConnectWarning')[0];
@ -276,7 +277,7 @@ function onOpen(openInfo) {
}
});
} else {
analytics.send(analytics.FLIGHT_CONTROLLER_EVENT.action('ConnectionRefused'));
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'ConnectionRefused');
var dialog = $('.dialogConnectWarning')[0];
@ -292,7 +293,7 @@ function onOpen(openInfo) {
}
});
} else {
analytics.send(analytics.APPLICATION_EVENT.action('SerialPortFailed'));
analytics.sendEvent(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, 'SerialPortFailed');
console.log('Failed to open serial port');
GUI.log(i18n.getMessage('serialPortOpenFail'));

View file

@ -2,7 +2,8 @@
TABS.configuration = {
DSHOT_PROTOCOL_MIN_VALUE: 5,
SHOW_OLD_BATTERY_CONFIG: false
SHOW_OLD_BATTERY_CONFIG: false,
analyticsChanges: {},
};
TABS.configuration.initialize = function (callback, scrollPosition) {
@ -195,6 +196,10 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
load_config();
function process_html() {
var self = this;
self.analyticsChanges = {};
var mixer_list_e = $('select.mixerList');
for (var selectIndex = 0; selectIndex < mixerList.length; selectIndex++) {
mixerList.forEach(function (mixerEntry, mixerIndex) {
@ -225,7 +230,15 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
reverseMotorSwitch_e.prop('checked', MIXER_CONFIG.reverseMotorDir != 0).change();
mixer_list_e.change(function () {
MIXER_CONFIG.mixer = parseInt($(this).val());
var mixerValue = parseInt($(this).val());
var newValue;
if (mixerValue !== MIXER_CONFIG.mixer) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['Mixer'] = newValue;
MIXER_CONFIG.mixer = mixerValue;
refreshMixerPreview();
});
@ -371,8 +384,16 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
esc_protocol_e.val(PID_ADVANCED_CONFIG.fast_pwm_protocol + 1);
esc_protocol_e.change(function () {
var escProtocolValue = parseInt($(this).val()) - 1;
var newValue;
if (escProtocolValue !== PID_ADVANCED_CONFIG.fast_pwm_protocol) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['EscProtocol'] = newValue;
//hide not used setting for DSHOT protocol
if ($(this).val() - 1 >= self.DSHOT_PROTOCOL_MIN_VALUE) {
if (escProtocolValue >= self.DSHOT_PROTOCOL_MIN_VALUE) {
$('div.minthrottle').hide();
$('div.maxthrottle').hide();
$('div.mincommand').hide();
@ -621,7 +642,15 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
}
serialRX_e.change(function () {
RX_CONFIG.serialrx_provider = parseInt($(this).val());
var serialRxValue = parseInt($(this).val());
var newValue;
if (serialRxValue !== RX_CONFIG.serialrx_provider) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['SerialRx'] = newValue;
RX_CONFIG.serialrx_provider = serialRxValue;
});
// select current serial RX type
@ -989,6 +1018,9 @@ TABS.configuration.initialize = function (callback, scrollPosition) {
RX_CONFIG.fpvCamAngleDegrees = parseInt($('input[name="fpvCamAngleDegrees"]').val());
}
analytics.sendChangeEvents(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges);
self.analyticsChanges = {};
function save_serial_config() {
var next_callback = save_feature_config;
MSP.send_message(MSPCodes.MSP_SET_CF_SERIAL_CONFIG, mspHelper.crunch(MSPCodes.MSP_SET_CF_SERIAL_CONFIG), false, next_callback);

View file

@ -1,6 +1,8 @@
'use strict';
TABS.ports = {};
TABS.ports = {
analyticsChanges: {},
};
TABS.ports.initialize = function (callback, scrollPosition) {
var self = this;
@ -117,6 +119,9 @@ TABS.ports.initialize = function (callback, scrollPosition) {
}
function update_ui() {
self.analyticsChanges = {};
self.foo.bar = 1;
if (semver.lt(CONFIG.apiVersion, "1.6.0")) {
@ -240,6 +245,19 @@ TABS.ports.initialize = function (callback, scrollPosition) {
if (serialPort.functions.indexOf(functionName) >= 0) {
select_e.val(functionName);
}
if (column === 'telemetry') {
var initialValue = functionName;
select_e.change(function () {
var telemetryValue = $(this).val();
var newValue;
if (telemetryValue !== initialValue) {
newValue = $(this).find('option:selected').text();
}
self.analyticsChanges['Telemetry'] = newValue;
});
}
}
}
}
@ -249,6 +267,7 @@ TABS.ports.initialize = function (callback, scrollPosition) {
}
function on_tab_loaded_handler() {
var self = this;
i18n.localizePage();
@ -265,6 +284,9 @@ TABS.ports.initialize = function (callback, scrollPosition) {
}
function on_save_handler() {
analytics.sendChangeEvents(analytics.EVENT_CATEGORIES.FLIGHT_CONTROLLER, self.analyticsChanges);
self.analyticsChanges = {};
// update configuration based on current ui state
SERIAL_CONFIG.ports = [];