config-editor-base 2.9.3 → 2.9.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -22309,7 +22309,8 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22309
22309
  _proto.onMerge = function onMerge() {
22310
22310
  var _this$state5 = this.state,
22311
22311
  combinedConfig = _this$state5.combinedConfig,
22312
- mergedConfigValid = _this$state5.mergedConfigValid;
22312
+ mergedConfigValid = _this$state5.mergedConfigValid,
22313
+ enableControlSignal = _this$state5.enableControlSignal;
22313
22314
  var formData = this.props.formData;
22314
22315
  if (mergedConfigValid !== true) {
22315
22316
  this.props.showAlert("warning", "Cannot merge - the combined configuration is invalid. Check console for details.");
@@ -22327,10 +22328,19 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22327
22328
  });
22328
22329
  this.props.setConfigContent(freshMergedConfig);
22329
22330
  this.props.setUpdatedFormData(freshMergedConfig);
22330
- this.props.showAlert("success", "Merged OBD transmit list with Configuration File");
22331
+ if (!enableControlSignal) {
22332
+ this.props.showAlert("warning", "Merged OBD transmit list with Configuration File. Important: If your CANedge transmits data while the vehicle ignition is off it can drain the vehicle battery. Use a control signal to start/stop transmission or ensure the device powers off with the ignition (e.g. by changing the installation setup or manually disconnecting the device).");
22333
+ } else {
22334
+ this.props.showAlert("success", "Merged OBD transmit list with Configuration File");
22335
+ }
22331
22336
  };
22332
22337
  _proto.onDownload = function onDownload() {
22333
- var generatedConfig = this.state.generatedConfig;
22338
+ var _this$state6 = this.state,
22339
+ generatedConfig = _this$state6.generatedConfig,
22340
+ enableControlSignal = _this$state6.enableControlSignal;
22341
+ if (!enableControlSignal) {
22342
+ this.props.showAlert("warning", "Important: If your CANedge transmits data while the vehicle ignition is off it can drain the vehicle battery. Use a control signal to start/stop transmission or ensure the device powers off with the ignition (e.g. by changing the installation setup or manually disconnecting the device).");
22343
+ }
22334
22344
  var dataStr = JSON.stringify(generatedConfig, null, 2);
22335
22345
  var dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
22336
22346
  var exportFileDefaultName = 'obd-transmit-list.json';
@@ -22341,23 +22351,23 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22341
22351
  };
22342
22352
  _proto.render = function render() {
22343
22353
  var _this9 = this;
22344
- var _this$state6 = this.state,
22345
- toolMode = _this$state6.toolMode,
22346
- channel = _this$state6.channel,
22347
- bitRate = _this$state6.bitRate,
22348
- canId = _this$state6.canId,
22349
- obdMode = _this$state6.obdMode,
22350
- spacing = _this$state6.spacing,
22351
- searchQuery = _this$state6.searchQuery,
22352
- supportedPids = _this$state6.supportedPids,
22353
- generatedConfig = _this$state6.generatedConfig,
22354
- mergedConfigValid = _this$state6.mergedConfigValid,
22355
- csvFileName = _this$state6.csvFileName,
22356
- mixedWarning = _this$state6.mixedWarning,
22357
- showPreview = _this$state6.showPreview,
22358
- enableControlSignal = _this$state6.enableControlSignal,
22359
- enableOBDFilter = _this$state6.enableOBDFilter,
22360
- combinedConfig = _this$state6.combinedConfig;
22354
+ var _this$state7 = this.state,
22355
+ toolMode = _this$state7.toolMode,
22356
+ channel = _this$state7.channel,
22357
+ bitRate = _this$state7.bitRate,
22358
+ canId = _this$state7.canId,
22359
+ obdMode = _this$state7.obdMode,
22360
+ spacing = _this$state7.spacing,
22361
+ searchQuery = _this$state7.searchQuery,
22362
+ supportedPids = _this$state7.supportedPids,
22363
+ generatedConfig = _this$state7.generatedConfig,
22364
+ mergedConfigValid = _this$state7.mergedConfigValid,
22365
+ csvFileName = _this$state7.csvFileName,
22366
+ mixedWarning = _this$state7.mixedWarning,
22367
+ showPreview = _this$state7.showPreview,
22368
+ enableControlSignal = _this$state7.enableControlSignal,
22369
+ enableOBDFilter = _this$state7.enableOBDFilter,
22370
+ combinedConfig = _this$state7.combinedConfig;
22361
22371
  var _this$props = this.props,
22362
22372
  formData = _this$props.formData,
22363
22373
  editorConfigFiles = _this$props.editorConfigFiles;
@@ -23120,6 +23130,392 @@ function evaluateFilters(frames, configData, detectedDeviceType) {
23120
23130
  };
23121
23131
  }
23122
23132
 
23133
+ var can_internal$1 = {
23134
+ filter: {
23135
+ id: [
23136
+ {
23137
+ name: "Heartbeat",
23138
+ state: 0,
23139
+ type: 0,
23140
+ id_format: 0,
23141
+ method: 0,
23142
+ f1: "2",
23143
+ f2: "2",
23144
+ prescaler_type: 0
23145
+ },
23146
+ {
23147
+ name: "TimeCalendar",
23148
+ state: 0,
23149
+ type: 0,
23150
+ id_format: 0,
23151
+ method: 0,
23152
+ f1: "3",
23153
+ f2: "3",
23154
+ prescaler_type: 0
23155
+ },
23156
+ {
23157
+ name: "TimeExternal",
23158
+ state: 0,
23159
+ type: 0,
23160
+ id_format: 0,
23161
+ method: 0,
23162
+ f1: "5",
23163
+ f2: "5",
23164
+ prescaler_type: 0
23165
+ }
23166
+ ]
23167
+ }
23168
+ };
23169
+ var can_1$2 = {
23170
+ filter: {
23171
+ remote_frames: 0,
23172
+ id: [
23173
+ {
23174
+ name: "AllStandardID",
23175
+ state: 1,
23176
+ type: 0,
23177
+ id_format: 0,
23178
+ method: 0,
23179
+ f1: "0",
23180
+ f2: "7FF",
23181
+ prescaler_type: 0
23182
+ },
23183
+ {
23184
+ name: "AllExtendedID",
23185
+ state: 1,
23186
+ type: 0,
23187
+ id_format: 1,
23188
+ method: 0,
23189
+ f1: "0",
23190
+ f2: "1FFFFFFF",
23191
+ prescaler_type: 0
23192
+ }
23193
+ ]
23194
+ }
23195
+ };
23196
+ var can_2$1 = {
23197
+ filter: {
23198
+ remote_frames: 0,
23199
+ id: [
23200
+ {
23201
+ name: "AllStandardID",
23202
+ state: 1,
23203
+ type: 0,
23204
+ id_format: 0,
23205
+ method: 0,
23206
+ f1: "0",
23207
+ f2: "7FF",
23208
+ prescaler_type: 0
23209
+ },
23210
+ {
23211
+ name: "AllExtendedID",
23212
+ state: 1,
23213
+ type: 0,
23214
+ id_format: 1,
23215
+ method: 0,
23216
+ f1: "0",
23217
+ f2: "1FFFFFFF",
23218
+ prescaler_type: 0
23219
+ }
23220
+ ]
23221
+ }
23222
+ };
23223
+ var canedgeDefaultFilters = {
23224
+ can_internal: can_internal$1,
23225
+ can_1: can_1$2,
23226
+ can_2: can_2$1
23227
+ };
23228
+
23229
+ var can_internal$2 = {
23230
+ filter: {
23231
+ id: [
23232
+ {
23233
+ name: "Heartbeat",
23234
+ state: 0,
23235
+ type: 0,
23236
+ id_format: 0,
23237
+ method: 0,
23238
+ f1: "2",
23239
+ f2: "2",
23240
+ prescaler_type: 0
23241
+ },
23242
+ {
23243
+ name: "TimeCalendar",
23244
+ state: 0,
23245
+ type: 0,
23246
+ id_format: 0,
23247
+ method: 0,
23248
+ f1: "3",
23249
+ f2: "3",
23250
+ prescaler_type: 0
23251
+ },
23252
+ {
23253
+ name: "TimeExternal",
23254
+ state: 0,
23255
+ type: 0,
23256
+ id_format: 0,
23257
+ method: 0,
23258
+ f1: "5",
23259
+ f2: "5",
23260
+ prescaler_type: 0
23261
+ },
23262
+ {
23263
+ name: "GnssStatus",
23264
+ state: 1,
23265
+ type: 0,
23266
+ id_format: 0,
23267
+ method: 0,
23268
+ f1: "65",
23269
+ f2: "65",
23270
+ prescaler_type: 0
23271
+ },
23272
+ {
23273
+ name: "GnssTime",
23274
+ state: 1,
23275
+ type: 0,
23276
+ id_format: 0,
23277
+ method: 0,
23278
+ f1: "66",
23279
+ f2: "66",
23280
+ prescaler_type: 0
23281
+ },
23282
+ {
23283
+ name: "GnsssPosition",
23284
+ state: 1,
23285
+ type: 0,
23286
+ id_format: 0,
23287
+ method: 0,
23288
+ f1: "67",
23289
+ f2: "67",
23290
+ prescaler_type: 0
23291
+ },
23292
+ {
23293
+ name: "GnssAltitude",
23294
+ state: 1,
23295
+ type: 0,
23296
+ id_format: 0,
23297
+ method: 0,
23298
+ f1: "68",
23299
+ f2: "68",
23300
+ prescaler_type: 0
23301
+ },
23302
+ {
23303
+ name: "GnssAttitude",
23304
+ state: 1,
23305
+ type: 0,
23306
+ id_format: 0,
23307
+ method: 0,
23308
+ f1: "69",
23309
+ f2: "69",
23310
+ prescaler_type: 0
23311
+ },
23312
+ {
23313
+ name: "GnssDistance",
23314
+ state: 1,
23315
+ type: 0,
23316
+ id_format: 0,
23317
+ method: 0,
23318
+ f1: "6A",
23319
+ f2: "6A",
23320
+ prescaler_type: 0
23321
+ },
23322
+ {
23323
+ name: "GnssSpeed",
23324
+ state: 1,
23325
+ type: 0,
23326
+ id_format: 0,
23327
+ method: 0,
23328
+ f1: "6B",
23329
+ f2: "6B",
23330
+ prescaler_type: 0
23331
+ },
23332
+ {
23333
+ name: "GnssGeofence",
23334
+ state: 1,
23335
+ type: 0,
23336
+ id_format: 0,
23337
+ method: 0,
23338
+ f1: "6C",
23339
+ f2: "6C",
23340
+ prescaler_type: 0
23341
+ },
23342
+ {
23343
+ name: "ImuAlign",
23344
+ state: 1,
23345
+ type: 0,
23346
+ id_format: 0,
23347
+ method: 0,
23348
+ f1: "6E",
23349
+ f2: "6E",
23350
+ prescaler_type: 0
23351
+ },
23352
+ {
23353
+ name: "ImuAcc",
23354
+ state: 1,
23355
+ type: 0,
23356
+ id_format: 0,
23357
+ method: 0,
23358
+ f1: "6F",
23359
+ f2: "6F",
23360
+ prescaler_type: 0
23361
+ }
23362
+ ]
23363
+ }
23364
+ };
23365
+ var can_1$3 = {
23366
+ filter: {
23367
+ remote_frames: 0,
23368
+ id: [
23369
+ {
23370
+ name: "AllStandardID",
23371
+ state: 1,
23372
+ type: 0,
23373
+ id_format: 0,
23374
+ method: 0,
23375
+ f1: "0",
23376
+ f2: "7FF",
23377
+ prescaler_type: 0
23378
+ },
23379
+ {
23380
+ name: "AllExtendedID",
23381
+ state: 1,
23382
+ type: 0,
23383
+ id_format: 1,
23384
+ method: 0,
23385
+ f1: "0",
23386
+ f2: "1FFFFFFF",
23387
+ prescaler_type: 0
23388
+ }
23389
+ ]
23390
+ }
23391
+ };
23392
+ var can_2$2 = {
23393
+ filter: {
23394
+ remote_frames: 0,
23395
+ id: [
23396
+ {
23397
+ name: "AllStandardID",
23398
+ state: 1,
23399
+ type: 0,
23400
+ id_format: 0,
23401
+ method: 0,
23402
+ f1: "0",
23403
+ f2: "7FF",
23404
+ prescaler_type: 0
23405
+ },
23406
+ {
23407
+ name: "AllExtendedID",
23408
+ state: 1,
23409
+ type: 0,
23410
+ id_format: 1,
23411
+ method: 0,
23412
+ f1: "0",
23413
+ f2: "1FFFFFFF",
23414
+ prescaler_type: 0
23415
+ }
23416
+ ]
23417
+ }
23418
+ };
23419
+ var canedgeDefaultFiltersGps = {
23420
+ can_internal: can_internal$2,
23421
+ can_1: can_1$3,
23422
+ can_2: can_2$2
23423
+ };
23424
+
23425
+ var phy = {
23426
+ can_s1: {
23427
+ filter: [
23428
+ {
23429
+ name: "AllStandardID",
23430
+ state: 1,
23431
+ id_format: 0,
23432
+ frame_format: 2,
23433
+ f1: "7FF",
23434
+ f2: "0",
23435
+ prescaler_type: 0
23436
+ },
23437
+ {
23438
+ name: "AllExtendedID",
23439
+ state: 1,
23440
+ id_format: 1,
23441
+ frame_format: 2,
23442
+ f1: "1FFFFFFF",
23443
+ f2: "0",
23444
+ prescaler_type: 0
23445
+ }
23446
+ ]
23447
+ },
23448
+ can_s2: {
23449
+ filter: [
23450
+ {
23451
+ name: "AllStandardID",
23452
+ state: 1,
23453
+ id_format: 0,
23454
+ frame_format: 2,
23455
+ f1: "7FF",
23456
+ f2: "0",
23457
+ prescaler_type: 0
23458
+ },
23459
+ {
23460
+ name: "AllExtendedID",
23461
+ state: 1,
23462
+ id_format: 1,
23463
+ frame_format: 2,
23464
+ f1: "1FFFFFFF",
23465
+ f2: "0",
23466
+ prescaler_type: 0
23467
+ }
23468
+ ]
23469
+ },
23470
+ can_s3: {
23471
+ filter: [
23472
+ {
23473
+ name: "AllStandardID",
23474
+ state: 1,
23475
+ id_format: 0,
23476
+ frame_format: 2,
23477
+ f1: "7FF",
23478
+ f2: "0",
23479
+ prescaler_type: 0
23480
+ },
23481
+ {
23482
+ name: "AllExtendedID",
23483
+ state: 1,
23484
+ id_format: 1,
23485
+ frame_format: 2,
23486
+ f1: "1FFFFFFF",
23487
+ f2: "0",
23488
+ prescaler_type: 0
23489
+ }
23490
+ ]
23491
+ },
23492
+ can_s4: {
23493
+ filter: [
23494
+ {
23495
+ name: "AllStandardID",
23496
+ state: 1,
23497
+ id_format: 0,
23498
+ frame_format: 2,
23499
+ f1: "7FF",
23500
+ f2: "0",
23501
+ prescaler_type: 0
23502
+ },
23503
+ {
23504
+ name: "AllExtendedID",
23505
+ state: 1,
23506
+ id_format: 1,
23507
+ frame_format: 2,
23508
+ f1: "1FFFFFFF",
23509
+ f2: "0",
23510
+ prescaler_type: 0
23511
+ }
23512
+ ]
23513
+ }
23514
+ };
23515
+ var canmodRouterDefaultFilters = {
23516
+ phy: phy
23517
+ };
23518
+
23123
23519
  var _excluded = ["name"],
23124
23520
  _excluded2 = ["name"];
23125
23521
  var merge$2 = require("deepmerge");
@@ -23140,8 +23536,10 @@ var MAX_11BIT_FILTERS_CANEDGE = 128;
23140
23536
  var MAX_29BIT_FILTERS_CANEDGE = 64;
23141
23537
  var MAX_FILTERS_CANMOD_ROUTER = 32;
23142
23538
  var CANEDGE_CHANNELS = ["CAN1", "CAN2", "CAN9"];
23143
- var MIN_FIRMWARE_CANEDGE = "01.09";
23144
- var MIN_FIRMWARE_CANMOD_ROUTER = "01.02";
23539
+ var SUPPORTED_FIRMWARE_CANEDGE = ["01.08", "01.09"];
23540
+ var SUPPORTED_FIRMWARE_CANMOD_ROUTER = ["01.02"];
23541
+ var MIN_FIRMWARE_CANEDGE = SUPPORTED_FIRMWARE_CANEDGE[0];
23542
+ var MIN_FIRMWARE_CANMOD_ROUTER = SUPPORTED_FIRMWARE_CANMOD_ROUTER[0];
23145
23543
  var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23146
23544
  function FilterBuilderTool(props) {
23147
23545
  var _this;
@@ -23159,6 +23557,7 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23159
23557
  _this.testMergedFile = _this.testMergedFile.bind(_this);
23160
23558
  _this.onMerge = _this.onMerge.bind(_this);
23161
23559
  _this.onDownload = _this.onDownload.bind(_this);
23560
+ _this.onReset = _this.onReset.bind(_this);
23162
23561
  _this.onSubmit = _this.onSubmit.bind(_this);
23163
23562
  _this.onValidationError = _this.onValidationError.bind(_this);
23164
23563
  _this.state = {
@@ -23248,9 +23647,9 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23248
23647
  var version = this.getConfigVersion();
23249
23648
  if (!version) return false;
23250
23649
  if (this.props.deviceType === "CANmod") {
23251
- return version >= MIN_FIRMWARE_CANMOD_ROUTER;
23650
+ return SUPPORTED_FIRMWARE_CANMOD_ROUTER.includes(version);
23252
23651
  }
23253
- return version >= MIN_FIRMWARE_CANEDGE;
23652
+ return SUPPORTED_FIRMWARE_CANEDGE.includes(version);
23254
23653
  };
23255
23654
  _proto.calculateFrameWeight = function calculateFrameWeight(dataLength) {
23256
23655
  var baseWeight = 4;
@@ -23978,16 +24377,29 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23978
24377
  var isPdu1 = (pgn & 0xFF00) < 0xF000;
23979
24378
  var mask = isPdu1 ? "3FF0000" : "3FFFF00";
23980
24379
  var filterId = isPdu1 ? ((pgn & 0x3FF00) << 8).toString(16).toUpperCase() : (pgn << 8).toString(16).toUpperCase();
23981
- var filter = {
23982
- name: (_entry4.messageName || "PGN " + pgn.toString(16).toUpperCase()).substring(0, 16),
23983
- state: 1,
23984
- type: filterTypeValue,
23985
- id_format: 1,
23986
- method: 1,
23987
- f1: filterId,
23988
- f2: mask,
23989
- prescaler_type: prescaler_type
23990
- };
24380
+ var filter = void 0;
24381
+ if (isCanmodRouter) {
24382
+ filter = {
24383
+ name: (_entry4.messageName || "PGN " + pgn.toString(16).toUpperCase()).substring(0, 16),
24384
+ state: 1,
24385
+ id_format: 1,
24386
+ frame_format: 2,
24387
+ f1: filterId,
24388
+ f2: mask,
24389
+ prescaler_type: prescaler_type
24390
+ };
24391
+ } else {
24392
+ filter = {
24393
+ name: (_entry4.messageName || "PGN " + pgn.toString(16).toUpperCase()).substring(0, 16),
24394
+ state: 1,
24395
+ type: filterTypeValue,
24396
+ id_format: 1,
24397
+ method: 1,
24398
+ f1: filterId,
24399
+ f2: mask,
24400
+ prescaler_type: prescaler_type
24401
+ };
24402
+ }
23991
24403
  if (prescaler_value !== undefined) {
23992
24404
  filter.prescaler_value = prescaler_value;
23993
24405
  }
@@ -24094,10 +24506,14 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24094
24506
  });
24095
24507
  var validate = ajv.compile(schemaContent);
24096
24508
  var valid = validate(mergedConfigTemp);
24509
+ if (!valid && validate.errors) {
24510
+ console.log("AJV validation errors:", validate.errors);
24511
+ }
24097
24512
  _this11.setState({
24098
24513
  mergedConfigValid: valid
24099
24514
  });
24100
24515
  } catch (e) {
24516
+ console.log("AJV compilation/validation exception:", e);
24101
24517
  _this11.setState({
24102
24518
  mergedConfigValid: false
24103
24519
  });
@@ -24295,6 +24711,33 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24295
24711
  linkElement.setAttribute('download', exportFileDefaultName);
24296
24712
  linkElement.click();
24297
24713
  };
24714
+ _proto.onReset = function onReset() {
24715
+ var _this$props = this.props,
24716
+ formData = _this$props.formData,
24717
+ deviceType = _this$props.deviceType;
24718
+ if (!formData || Object.keys(formData).length === 0) {
24719
+ this.props.showAlert("warning", "No configuration file loaded");
24720
+ return;
24721
+ }
24722
+ var defaultFilters;
24723
+ var isCanmodRouter = this.isCanmodRouter();
24724
+ if (deviceType === "CANmod" && isCanmodRouter) {
24725
+ defaultFilters = canmodRouterDefaultFilters;
24726
+ } else if (deviceType && deviceType.includes("GNSS")) {
24727
+ defaultFilters = canedgeDefaultFiltersGps;
24728
+ } else {
24729
+ defaultFilters = canedgeDefaultFilters;
24730
+ }
24731
+ var overwriteMerge = function overwriteMerge(destinationArray, sourceArray, options) {
24732
+ return sourceArray;
24733
+ };
24734
+ var resetConfig = merge$2(formData, defaultFilters, {
24735
+ arrayMerge: overwriteMerge
24736
+ });
24737
+ this.props.setConfigContent(resetConfig);
24738
+ this.props.setUpdatedFormData(resetConfig);
24739
+ this.props.showAlert("success", "CAN channel filters reset to defaults (record everything)");
24740
+ };
24298
24741
  _proto.renderBarChart = function renderBarChart(percentage, maxPercentage) {
24299
24742
  var maxWidth = 25;
24300
24743
  var barWidth = Math.max(1, percentage / maxPercentage * maxWidth);
@@ -24371,9 +24814,25 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24371
24814
  clickable: true
24372
24815
  }, /*#__PURE__*/React.createElement("button", {
24373
24816
  className: "btn btn-primary"
24374
- }, "Load DBC(s)")))), /*#__PURE__*/React.createElement("p", {
24817
+ }, "Load DBC(s)"))), function () {
24818
+ var isFirmwareSupported = _this12.isFirmwareVersionSupported();
24819
+ var isCanmod = _this12.props.deviceType === "CANmod";
24820
+ var isCanmodRouter = isCanmod && _this12.isCanmodRouter();
24821
+ var isDeviceSupported = !isCanmod || isCanmodRouter;
24822
+ var hasConfig = _this12.props.formData && Object.keys(_this12.props.formData).length > 0;
24823
+ return /*#__PURE__*/React.createElement("button", {
24824
+ className: "btn",
24825
+ onClick: _this12.onReset,
24826
+ disabled: !hasConfig || !isFirmwareSupported || !isDeviceSupported,
24827
+ style: {
24828
+ backgroundColor: "#fff",
24829
+ border: "1px solid #ccc",
24830
+ color: "#333"
24831
+ }
24832
+ }, "Reset filters");
24833
+ }()), /*#__PURE__*/React.createElement("span", {
24375
24834
  className: "field-description field-description-shift"
24376
- }, this.props.deviceType === "CANmod" ? "Load a CSV log file output from the MF4 converter 'mdf2csv' which reflects a realistic log session with the default filters applied. The MF4 should be recorded with a CANedge with one or two CANmod.router(s) on CAN2. The CSV should be created by first demuxing the MF4 via the 'mdf2mdf' converter using the argument '--muxtp-can2=010#11:12:13:14'. If you are analyzing a second router, use --muxtp-can2=012#15:16:17:18. Recommended CSV file size is 1-10 MB. Optionally load DBC file(s) to add further details or enable filter selection based on DBC messages. DBC files must have a CAN channel prefix (e.g. can11-abc.dbc)." : "Load a CSV log file output from the MF4 converter 'mdf2csv' which reflects a realistic log session with the default filters applied. Recommended CSV file size is 1-10 MB. Optionally load DBC file(s) to add further details or enable filter selection based on DBC messages. DBC files must have a CAN channel prefix (e.g. can1-abc.dbc)."), (csvFileName || dbcFileNames.length > 0) && /*#__PURE__*/React.createElement("div", {
24835
+ }, this.props.deviceType === "CANmod" ? "Load CSV: Load a log file recorded with CANedge + CANmod.router(s), demuxed via 'mdf2mdf' and converted to CSV via 'mdf2csv'. Load DBC(s): Add DBC files with channel prefix (e.g. can11-abc.dbc). Reset filters: Reset all CAN channel filters to defaults (record everything)." : "Load CSV: Load a CSV from 'mdf2csv' reflecting a realistic log session. Load DBC(s): Add DBC files with channel prefix (e.g. can1-abc.dbc). Reset filters: Reset all CAN channel filters to defaults (record everything)."), (csvFileName || dbcFileNames.length > 0) && /*#__PURE__*/React.createElement("div", {
24377
24836
  style: {
24378
24837
  fontSize: "11px",
24379
24838
  color: "#666",
@@ -24857,7 +25316,8 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24857
25316
  style: {
24858
25317
  opacity: _this12.props.deviceType === "CANmod" ? 0.5 : 1,
24859
25318
  pointerEvents: _this12.props.deviceType === "CANmod" ? "none" : "auto"
24860
- }
25319
+ },
25320
+ title: _this12.props.deviceType === "CANmod" ? "CANmod only supports acceptance filters" : ""
24861
25321
  }, /*#__PURE__*/React.createElement(SimpleDropdown, {
24862
25322
  name: "Type",
24863
25323
  options: [{
@@ -24875,13 +25335,7 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24875
25335
  return _this12.generateFilterConfig();
24876
25336
  });
24877
25337
  }
24878
- }), _this12.props.deviceType === "CANmod" && /*#__PURE__*/React.createElement("span", {
24879
- className: "field-description",
24880
- style: {
24881
- fontSize: "11px",
24882
- color: "#999"
24883
- }
24884
- }, "CANmod only supports acceptance filters")), _this12.state.filterType === "acceptance" && /*#__PURE__*/React.createElement("div", {
25338
+ })), _this12.state.filterType === "acceptance" && /*#__PURE__*/React.createElement("div", {
24885
25339
  className: "col-xs-6"
24886
25340
  }, /*#__PURE__*/React.createElement(SimpleDropdown, {
24887
25341
  name: "Prescaler",
@@ -24931,13 +25385,16 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24931
25385
  }), /*#__PURE__*/React.createElement("span", {
24932
25386
  className: "field-description field-description-shift"
24933
25387
  }, _this12.state.prescalerType === "count" && "Accept every Nth message (1-256)", _this12.state.prescalerType === "time" && "Minimum time between messages (1-4194304 ms)", _this12.state.prescalerType === "data" && "Hex mask for data change detection")), /*#__PURE__*/React.createElement("div", {
25388
+ className: "form-group pl0 field-string",
25389
+ style: {
25390
+ marginBottom: "10px"
25391
+ }
25392
+ }, /*#__PURE__*/React.createElement("div", {
24934
25393
  style: {
24935
25394
  display: "flex",
24936
25395
  alignItems: "center",
24937
- marginBottom: "15px",
24938
25396
  gap: "10px"
24939
- },
24940
- title: "The new filters can either replace existing filters on the affected channel(s) or be appended at the top/bottom of the existing filters."
25397
+ }
24941
25398
  }, /*#__PURE__*/React.createElement("label", {
24942
25399
  style: {
24943
25400
  display: "flex",
@@ -25022,7 +25479,9 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
25022
25479
  position: "relative",
25023
25480
  top: "1px"
25024
25481
  }
25025
- }, "Append (bottom)"))), /*#__PURE__*/React.createElement("div", {
25482
+ }, "Append (bottom)"))), /*#__PURE__*/React.createElement("span", {
25483
+ className: "field-description field-description-shift"
25484
+ }, "The new filters can either replace existing filters on the affected channel(s) or be appended at the top/bottom of the existing filters. If you e.g. wish to prescale 5 specific IDs and then log everything else as-is, you can append the 5 ID filters at the top of the default filters.")), /*#__PURE__*/React.createElement("div", {
25026
25485
  style: {
25027
25486
  fontSize: "12px",
25028
25487
  color: "#666",
@@ -25064,13 +25523,29 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
25064
25523
  className: "btn btn-default",
25065
25524
  onClick: _this12.onDownload,
25066
25525
  disabled: Object.keys(_this12.state.generatedFilterConfig).length === 0
25067
- }, "Download JSON")), _this12.props.formData && Object.keys(_this12.props.formData).length > 0 && isDeviceSupported && !isFirmwareSupported && /*#__PURE__*/React.createElement("div", {
25068
- style: {
25069
- fontSize: "12px",
25070
- color: "#666",
25071
- marginTop: "8px"
25526
+ }, "Download JSON")), function () {
25527
+ var mergeDisabled = !_this12.props.formData || Object.keys(_this12.props.formData).length === 0 || _this12.state.mergedConfigValid !== true || !isFirmwareSupported || !isDeviceSupported;
25528
+ if (!mergeDisabled) return null;
25529
+ var reason = "";
25530
+ if (!_this12.props.formData || Object.keys(_this12.props.formData).length === 0) {
25531
+ reason = "No configuration file loaded";
25532
+ } else if (!isDeviceSupported) {
25533
+ reason = "Only CANmod.router is supported for CANmod devices";
25534
+ } else if (!isFirmwareSupported) {
25535
+ reason = "Merging requires firmware " + minFirmware + ".XX+ - please update your device";
25536
+ } else if (_this12.state.mergedConfigValid === "Unknown") {
25537
+ reason = "No filters selected";
25538
+ } else if (_this12.state.mergedConfigValid === false) {
25539
+ reason = "Generated filter configuration is invalid";
25072
25540
  }
25073
- }, "Merging requires firmware ", minFirmware, ".XX+ - please update your device"));
25541
+ return reason ? /*#__PURE__*/React.createElement("div", {
25542
+ style: {
25543
+ fontSize: "12px",
25544
+ color: "#d9534f",
25545
+ marginTop: "8px"
25546
+ }
25547
+ }, reason) : null;
25548
+ }());
25074
25549
  }(), Object.keys(_this12.state.generatedFilterConfig).length > 0 && /*#__PURE__*/React.createElement("div", {
25075
25550
  style: {
25076
25551
  marginTop: "10px"