Make saving the configuration more robust (#594)
* feat: Make saving the configuration more robust * parse backup user config before return * fix some bug * Add write-userconfig.js and invalid-config.bin * throw exception if failed user config parsing * Merge branch 'master' into feat-467-make-save-more-robust * hide keymaps and macros if agent in restore mode * fix Device name settings
This commit is contained in:
committed by
László Monda
parent
00c5b69129
commit
13ec617d58
190
package-lock.json
generated
190
package-lock.json
generated
@@ -67,9 +67,9 @@
|
||||
}
|
||||
},
|
||||
"@types/fs-extra": {
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-4.0.5.tgz",
|
||||
"integrity": "sha512-tIG0GpHum5IFb8Qze/cSv0w/0gNzHB+MUDftTQaxenx46z50g51/MPkNLssLz9+uZLzCDd35bT9qtWOTXZ21Gw==",
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.1.tgz",
|
||||
"integrity": "sha512-h3wnflb+jMTipvbbZnClgA2BexrT4w0GcfoCz5qyxd0IRsbqhLSyesM6mqZTAnhbVmhyTm5tuxfRu9R+8l+lGw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/node": "8.0.53"
|
||||
@@ -571,6 +571,12 @@
|
||||
"integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
|
||||
"dev": true
|
||||
},
|
||||
"bindings": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
|
||||
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==",
|
||||
"dev": true
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
|
||||
@@ -1130,6 +1136,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz",
|
||||
"integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=",
|
||||
"dev": true
|
||||
},
|
||||
"chromium-pickle-js": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
|
||||
@@ -2788,6 +2800,15 @@
|
||||
"strip-dirs": "2.1.0"
|
||||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mimic-response": "1.0.0"
|
||||
}
|
||||
},
|
||||
"decompress-tar": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
|
||||
@@ -3479,13 +3500,26 @@
|
||||
"requires": {
|
||||
"debug": "3.1.0",
|
||||
"env-paths": "1.0.0",
|
||||
"fs-extra": "4.0.2",
|
||||
"fs-extra": "4.0.3",
|
||||
"minimist": "1.2.0",
|
||||
"nugget": "2.0.1",
|
||||
"path-exists": "3.0.0",
|
||||
"rc": "1.2.1",
|
||||
"semver": "5.4.1",
|
||||
"sumchecker": "2.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"fs-extra": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11",
|
||||
"jsonfile": "4.0.0",
|
||||
"universalify": "0.1.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"find-up": {
|
||||
@@ -4266,6 +4300,12 @@
|
||||
"fill-range": "2.2.3"
|
||||
}
|
||||
},
|
||||
"expand-template": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz",
|
||||
"integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ==",
|
||||
"dev": true
|
||||
},
|
||||
"exports-loader": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/exports-loader/-/exports-loader-0.6.3.tgz",
|
||||
@@ -4533,25 +4573,14 @@
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.2.tgz",
|
||||
"integrity": "sha1-+RcExT0bRh+JNFKwwwfZmXZHq2s=",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
|
||||
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11",
|
||||
"jsonfile": "4.0.0",
|
||||
"universalify": "0.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"jsonfile": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fs-extra-p": {
|
||||
@@ -5819,6 +5848,12 @@
|
||||
"ini": "1.3.4"
|
||||
}
|
||||
},
|
||||
"github-from-package": {
|
||||
"version": "0.0.0",
|
||||
"resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
|
||||
"integrity": "sha1-l/tdlr/eiXMxPyDoKI75oWf6ZM4=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "6.0.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
|
||||
@@ -6950,7 +6985,7 @@
|
||||
"dedent": "0.7.0",
|
||||
"execa": "0.8.0",
|
||||
"find-up": "2.1.0",
|
||||
"fs-extra": "4.0.2",
|
||||
"fs-extra": "4.0.3",
|
||||
"get-port": "3.2.0",
|
||||
"glob": "7.1.2",
|
||||
"glob-parent": "3.1.0",
|
||||
@@ -7101,6 +7136,17 @@
|
||||
"locate-path": "2.0.0"
|
||||
}
|
||||
},
|
||||
"fs-extra": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
|
||||
"integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"graceful-fs": "4.1.11",
|
||||
"jsonfile": "4.0.0",
|
||||
"universalify": "0.1.1"
|
||||
}
|
||||
},
|
||||
"git-raw-commits": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-1.3.4.tgz",
|
||||
@@ -7825,6 +7871,12 @@
|
||||
"integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=",
|
||||
"dev": true
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
|
||||
"integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=",
|
||||
"dev": true
|
||||
},
|
||||
"minimalistic-assert": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
|
||||
@@ -7925,8 +7977,7 @@
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
|
||||
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY=",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
"dev": true
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.3.0",
|
||||
@@ -7989,6 +8040,17 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node-hid": {
|
||||
"version": "0.5.7",
|
||||
"resolved": "https://registry.npmjs.org/node-hid/-/node-hid-0.5.7.tgz",
|
||||
"integrity": "sha512-dwwpOetL2+MGYgivbO22ML+45ieCGbueWv1rYxRgBoEc2QMp6UF6ZucEkYts1IA3YPWJNkmpGh6dqQ85n19szw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bindings": "1.3.0",
|
||||
"nan": "2.7.0",
|
||||
"prebuild-install": "2.5.1"
|
||||
}
|
||||
},
|
||||
"node-libs-browser": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz",
|
||||
@@ -8089,6 +8151,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
|
||||
"integrity": "sha1-lKKxYzxPExdVMAfYlm/Q6EG2pMI=",
|
||||
"dev": true
|
||||
},
|
||||
"nopt": {
|
||||
"version": "3.0.6",
|
||||
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
|
||||
@@ -8971,6 +9039,29 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz",
|
||||
"integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"detect-libc": "1.0.3",
|
||||
"expand-template": "1.1.0",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-abi": "2.3.0",
|
||||
"noop-logger": "0.1.1",
|
||||
"npmlog": "4.1.2",
|
||||
"os-homedir": "1.0.2",
|
||||
"pump": "2.0.1",
|
||||
"rc": "1.2.1",
|
||||
"simple-get": "2.7.0",
|
||||
"tar-fs": "1.16.0",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"which-pm-runs": "1.0.0"
|
||||
}
|
||||
},
|
||||
"prepend-http": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
|
||||
@@ -9061,6 +9152,16 @@
|
||||
"randombytes": "2.0.5"
|
||||
}
|
||||
},
|
||||
"pump": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
@@ -9646,6 +9747,23 @@
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
|
||||
"dev": true
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
|
||||
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
|
||||
"dev": true
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
|
||||
"integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"decompress-response": "3.3.0",
|
||||
"once": "1.4.0",
|
||||
"simple-concat": "1.0.0"
|
||||
}
|
||||
},
|
||||
"single-line-log": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
|
||||
@@ -10526,6 +10644,30 @@
|
||||
"inherits": "2.0.3"
|
||||
}
|
||||
},
|
||||
"tar-fs": {
|
||||
"version": "1.16.0",
|
||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.0.tgz",
|
||||
"integrity": "sha512-I9rb6v7mjWLtOfCau9eH5L7sLJyU2BnxtEZRQ5Mt+eRKmf1F0ohXmT/Jc3fr52kDvjJ/HV5MH3soQfPL5bQ0Yg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"pump": "1.0.3",
|
||||
"tar-stream": "1.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz",
|
||||
@@ -11435,6 +11577,12 @@
|
||||
"integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
|
||||
"dev": true
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=",
|
||||
"dev": true
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/electron-devtools-installer": "2.0.2",
|
||||
"@types/electron-settings": "3.0.0",
|
||||
"@types/fs-extra": "4.0.5",
|
||||
"@types/fs-extra": "5.0.1",
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/jsonfile": "4.0.1",
|
||||
"@types/node": "8.0.53",
|
||||
@@ -47,10 +47,11 @@
|
||||
"electron-updater": "2.21.4",
|
||||
"exports-loader": "0.6.3",
|
||||
"file-loader": "0.10.0",
|
||||
"fs-extra": "4.0.2",
|
||||
"fs-extra": "5.0.0",
|
||||
"jsonfile": "4.0.0",
|
||||
"lerna": "2.9.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-hid": "0.5.7",
|
||||
"npm-run-all": "4.0.2",
|
||||
"pre-commit": "1.2.2",
|
||||
"request": "2.83.0",
|
||||
|
||||
1140
packages/uhk-agent/package-lock.json
generated
1140
packages/uhk-agent/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,7 @@
|
||||
"command-line-args": "4.0.7",
|
||||
"decompress": "4.2.0",
|
||||
"decompress-bzip2": "4.0.0",
|
||||
"node-hid": "0.5.4",
|
||||
"node-hid": "0.5.7",
|
||||
"sudo-prompt": "7.0.0",
|
||||
"tmp": "0.0.33",
|
||||
"uhk-common": "^1.0.0",
|
||||
|
||||
@@ -1,5 +1,15 @@
|
||||
import { ipcMain } from 'electron';
|
||||
import { ConfigurationReply, DeviceConnectionState, HardwareModules, IpcEvents, IpcResponse, LogService } from 'uhk-common';
|
||||
import {
|
||||
ConfigurationReply,
|
||||
DeviceConnectionState,
|
||||
getHardwareConfigFromDeviceResponse,
|
||||
HardwareModules,
|
||||
IpcEvents,
|
||||
IpcResponse,
|
||||
LogService,
|
||||
mapObjectToUserConfigBinaryBuffer,
|
||||
SaveUserConfigurationData
|
||||
} from 'uhk-common';
|
||||
import { snooze, UhkHidDevice, UhkOperations } from 'uhk-usb';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
@@ -14,6 +24,7 @@ import 'rxjs/add/operator/distinctUntilChanged';
|
||||
import { saveTmpFirmware } from '../util/save-extract-firmware';
|
||||
import { TmpFirmware } from '../models/tmp-firmware';
|
||||
import { QueueManager } from './queue-manager';
|
||||
import { backupUserConfiguration, getBackupUserConfigurationContent } from '../util/backup-user-confoguration';
|
||||
|
||||
/**
|
||||
* IpcMain pair of the UHK Communication
|
||||
@@ -78,10 +89,14 @@ export class DeviceService {
|
||||
rightModuleInfo: await this.operations.getRightModuleVersionInfo()
|
||||
};
|
||||
|
||||
const hardwareConfig = getHardwareConfigFromDeviceResponse(result.hardwareConfiguration);
|
||||
const uniqueId = hardwareConfig.uniqueId;
|
||||
|
||||
response = {
|
||||
success: true,
|
||||
...result,
|
||||
modules
|
||||
modules,
|
||||
backupConfiguration: await getBackupUserConfigurationContent(this.logService, uniqueId)
|
||||
};
|
||||
} catch (error) {
|
||||
response = {
|
||||
@@ -162,10 +177,13 @@ export class DeviceService {
|
||||
|
||||
private async saveUserConfiguration(event: Electron.Event, args: Array<string>): Promise<void> {
|
||||
const response = new IpcResponse();
|
||||
const json = args[0];
|
||||
const data: SaveUserConfigurationData = JSON.parse(args[0]);
|
||||
|
||||
try {
|
||||
await this.operations.saveUserConfiguration(json);
|
||||
await backupUserConfiguration(data);
|
||||
|
||||
const buffer = mapObjectToUserConfigBinaryBuffer(data.configuration);
|
||||
await this.operations.saveUserConfiguration(buffer);
|
||||
|
||||
response.success = true;
|
||||
}
|
||||
|
||||
32
packages/uhk-agent/src/util/backup-user-confoguration.ts
Normal file
32
packages/uhk-agent/src/util/backup-user-confoguration.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
import { app } from 'electron';
|
||||
import { LogService, UserConfiguration, SaveUserConfigurationData } from 'uhk-common';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs-extra';
|
||||
|
||||
export const getBackupUserConfigurationPath = (uniqueId: number): string => {
|
||||
const appDataDir = app.getPath('userData');
|
||||
|
||||
return path.join(appDataDir, `${uniqueId}.json`);
|
||||
};
|
||||
|
||||
export const backupUserConfiguration = (data: SaveUserConfigurationData): Promise<void> => {
|
||||
const backupFilePath = getBackupUserConfigurationPath(data.uniqueId);
|
||||
return fs.writeJSON(backupFilePath, data.configuration, {spaces: 2});
|
||||
};
|
||||
|
||||
export const getBackupUserConfigurationContent = async (logService: LogService, uniqueId: number): Promise<UserConfiguration> => {
|
||||
try {
|
||||
const backupFilePath = getBackupUserConfigurationPath(uniqueId);
|
||||
|
||||
if (await fs.pathExists(backupFilePath)) {
|
||||
const json = await fs.readJSON(backupFilePath);
|
||||
new UserConfiguration().fromJsonObject(json);
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (error) {
|
||||
logService.error('Can not load backup user configuration for device', {uniqueId, error});
|
||||
}
|
||||
};
|
||||
@@ -1,4 +1,5 @@
|
||||
import { HardwareModules } from './hardware-modules';
|
||||
import { UserConfiguration } from '../config-serializer/config-items';
|
||||
|
||||
export interface ConfigurationReply {
|
||||
success: boolean;
|
||||
@@ -6,4 +7,5 @@ export interface ConfigurationReply {
|
||||
hardwareConfiguration?: string;
|
||||
modules?: HardwareModules;
|
||||
error?: string;
|
||||
backupConfiguration?: UserConfiguration;
|
||||
}
|
||||
|
||||
@@ -7,3 +7,4 @@ export * from './version-information';
|
||||
export * from './device-connection-state';
|
||||
export * from './hardware-modules';
|
||||
export * from './hardware-module-info';
|
||||
export * from './save-user-configuration-data';
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface SaveUserConfigurationData {
|
||||
uniqueId: number;
|
||||
configuration: string;
|
||||
}
|
||||
33
packages/uhk-common/src/util/helpers.ts
Normal file
33
packages/uhk-common/src/util/helpers.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { HardwareConfiguration, UhkBuffer, UserConfiguration } from '../../index';
|
||||
|
||||
export const getHardwareConfigFromDeviceResponse = (json: string): HardwareConfiguration => {
|
||||
const data = JSON.parse(json);
|
||||
const hardwareConfig = new HardwareConfiguration();
|
||||
hardwareConfig.fromBinary(UhkBuffer.fromArray(data));
|
||||
|
||||
if (hardwareConfig.uniqueId > 0) {
|
||||
return hardwareConfig;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
export const getUserConfigFromDeviceResponse = (json: string): UserConfiguration => {
|
||||
const data = JSON.parse(json);
|
||||
const userConfig = new UserConfiguration();
|
||||
userConfig.fromBinary(UhkBuffer.fromArray(data));
|
||||
|
||||
if (userConfig.userConfigMajorVersion > 0) {
|
||||
return userConfig;
|
||||
}
|
||||
|
||||
throw Error('Invalid user configuration');
|
||||
};
|
||||
|
||||
export const mapObjectToUserConfigBinaryBuffer = (obj: any): Buffer => {
|
||||
const configuration = new UserConfiguration();
|
||||
configuration.fromJsonObject(obj);
|
||||
const buffer = new UhkBuffer();
|
||||
configuration.toBinary(buffer);
|
||||
|
||||
return buffer.getBufferContent();
|
||||
};
|
||||
@@ -1,6 +1,7 @@
|
||||
export { IpcEvents } from './ipcEvents';
|
||||
export * from './log';
|
||||
export * from './constants';
|
||||
export * from './helpers';
|
||||
|
||||
// Source: http://stackoverflow.com/questions/13720256/javascript-regex-camelcase-to-sentence
|
||||
export function camelCaseToSentence(camelCasedText: string): string {
|
||||
|
||||
172
packages/uhk-usb/package-lock.json
generated
172
packages/uhk-usb/package-lock.json
generated
@@ -23,7 +23,7 @@
|
||||
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
|
||||
"requires": {
|
||||
"delegates": "1.0.0",
|
||||
"readable-stream": "2.3.3"
|
||||
"readable-stream": "2.3.6"
|
||||
}
|
||||
},
|
||||
"bindings": {
|
||||
@@ -32,11 +32,12 @@
|
||||
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
|
||||
},
|
||||
"bl": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
|
||||
"integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=",
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||
"integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
|
||||
"requires": {
|
||||
"readable-stream": "2.3.3"
|
||||
"readable-stream": "2.3.6",
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"chownr": {
|
||||
@@ -59,6 +60,14 @@
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"requires": {
|
||||
"mimic-response": "1.0.0"
|
||||
}
|
||||
},
|
||||
"deep-extend": {
|
||||
"version": "0.4.2",
|
||||
"resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
|
||||
@@ -69,10 +78,15 @@
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
|
||||
"integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
|
||||
"integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
|
||||
"requires": {
|
||||
"once": "1.4.0"
|
||||
}
|
||||
@@ -113,9 +127,9 @@
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
|
||||
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"is-fullwidth-code-point": {
|
||||
"version": "1.0.0",
|
||||
@@ -130,6 +144,11 @@
|
||||
"resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
|
||||
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
|
||||
"integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
|
||||
@@ -151,14 +170,17 @@
|
||||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
|
||||
"integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY="
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz",
|
||||
"integrity": "sha512-6oxV13poCOv7TfGvhsSz6XZWpXeKkdGVh72++cs33OfMh3KAX8lN84dCvmqSETyDXAFcUHtV7eJrgFBoOqZbNQ=="
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.3.0.tgz",
|
||||
"integrity": "sha512-zwm6vU3SsVgw3e9fu48JBaRBCJGIvAgysDsqtf5+vEexFE71bEOtaMWb5zr/zODZNzTPtQlqUUpC79k68Hspow==",
|
||||
"requires": {
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"node-hid": {
|
||||
"version": "0.5.7",
|
||||
@@ -166,8 +188,8 @@
|
||||
"integrity": "sha512-dwwpOetL2+MGYgivbO22ML+45ieCGbueWv1rYxRgBoEc2QMp6UF6ZucEkYts1IA3YPWJNkmpGh6dqQ85n19szw==",
|
||||
"requires": {
|
||||
"bindings": "1.3.0",
|
||||
"nan": "2.7.0",
|
||||
"prebuild-install": "2.3.0"
|
||||
"nan": "2.10.0",
|
||||
"prebuild-install": "2.5.1"
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
@@ -210,62 +232,63 @@
|
||||
"integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.3.0.tgz",
|
||||
"integrity": "sha512-gzjq2oHB8oMbzJSsSh9MQ64zrXZGt092/uT4TLZlz2qnrPxpWqp4vYB7LZrDxnlxf5RfbCjkgDI/z0EIVuYzAw==",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz",
|
||||
"integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==",
|
||||
"requires": {
|
||||
"detect-libc": "1.0.3",
|
||||
"expand-template": "1.1.0",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-abi": "2.1.1",
|
||||
"node-abi": "2.3.0",
|
||||
"noop-logger": "0.1.1",
|
||||
"npmlog": "4.1.2",
|
||||
"os-homedir": "1.0.2",
|
||||
"pump": "1.0.2",
|
||||
"rc": "1.2.2",
|
||||
"simple-get": "1.4.3",
|
||||
"pump": "2.0.1",
|
||||
"rc": "1.2.6",
|
||||
"simple-get": "2.7.0",
|
||||
"tar-fs": "1.16.0",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"xtend": "4.0.1"
|
||||
"which-pm-runs": "1.0.0"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
|
||||
"integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
|
||||
},
|
||||
"pump": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
|
||||
"integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"end-of-stream": "1.4.1",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
|
||||
"integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz",
|
||||
"integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=",
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.4",
|
||||
"ini": "1.3.5",
|
||||
"minimist": "1.2.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
|
||||
"integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
|
||||
"version": "2.3.6",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
|
||||
"integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
|
||||
"requires": {
|
||||
"core-util-is": "1.0.2",
|
||||
"inherits": "2.0.3",
|
||||
"isarray": "1.0.0",
|
||||
"process-nextick-args": "1.0.7",
|
||||
"process-nextick-args": "2.0.0",
|
||||
"safe-buffer": "5.1.1",
|
||||
"string_decoder": "1.0.3",
|
||||
"string_decoder": "1.1.1",
|
||||
"util-deprecate": "1.0.2"
|
||||
}
|
||||
},
|
||||
@@ -274,6 +297,11 @@
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
|
||||
"integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
@@ -284,14 +312,19 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
|
||||
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz",
|
||||
"integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
|
||||
"integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
|
||||
"requires": {
|
||||
"decompress-response": "3.3.0",
|
||||
"once": "1.4.0",
|
||||
"unzip-response": "1.0.2",
|
||||
"xtend": "4.0.1"
|
||||
"simple-concat": "1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
@@ -305,9 +338,9 @@
|
||||
}
|
||||
},
|
||||
"string_decoder": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
|
||||
"integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
|
||||
"integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
|
||||
"requires": {
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
@@ -332,18 +365,29 @@
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"pump": "1.0.2",
|
||||
"tar-stream": "1.5.4"
|
||||
"pump": "1.0.3",
|
||||
"tar-stream": "1.5.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.1",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz",
|
||||
"integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=",
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.5.tgz",
|
||||
"integrity": "sha512-mQdgLPc/Vjfr3VWqWbfxW8yQNiJCbAZ+Gf6GDu1Cy0bdb33ofyiNGBtAY96jHFhDuivCwgW1H9DgTON+INiXgg==",
|
||||
"requires": {
|
||||
"bl": "1.2.1",
|
||||
"end-of-stream": "1.4.0",
|
||||
"readable-stream": "2.3.3",
|
||||
"bl": "1.2.2",
|
||||
"end-of-stream": "1.4.1",
|
||||
"readable-stream": "2.3.6",
|
||||
"xtend": "4.0.1"
|
||||
}
|
||||
},
|
||||
@@ -355,16 +399,16 @@
|
||||
"safe-buffer": "5.1.1"
|
||||
}
|
||||
},
|
||||
"unzip-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
|
||||
"integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
|
||||
@@ -105,8 +105,6 @@ export class UhkOperations {
|
||||
* @returns {Promise<Buffer>}
|
||||
*/
|
||||
public async loadConfiguration(configBufferId: ConfigBufferId): Promise<string> {
|
||||
let response = [];
|
||||
|
||||
const configBufferIdToName = ['HardwareConfig', 'StagingUserConfig', 'ValidatedUserConfig'];
|
||||
const configName = configBufferIdToName[configBufferId];
|
||||
|
||||
@@ -140,7 +138,8 @@ export class UhkOperations {
|
||||
}
|
||||
}
|
||||
}
|
||||
response = convertBufferToIntArray(configBuffer);
|
||||
const response = convertBufferToIntArray(configBuffer);
|
||||
|
||||
return Promise.resolve(JSON.stringify(response));
|
||||
} catch (error) {
|
||||
const errMsg = `[DeviceOperation] ${configName} from eeprom error`;
|
||||
@@ -165,10 +164,10 @@ export class UhkOperations {
|
||||
return configSize;
|
||||
}
|
||||
|
||||
public async saveUserConfiguration(json: string): Promise<void> {
|
||||
public async saveUserConfiguration(buffer: Buffer): Promise<void> {
|
||||
try {
|
||||
this.logService.debug('[DeviceOperation] USB[T]: Write user configuration to keyboard');
|
||||
await this.sendUserConfigToKeyboard(json);
|
||||
await this.sendUserConfigToKeyboard(buffer);
|
||||
this.logService.debug('[DeviceOperation] USB[T]: Write user configuration to EEPROM');
|
||||
await this.device.writeConfigToEeprom(ConfigBufferId.validatedUserConfig);
|
||||
}
|
||||
@@ -246,12 +245,11 @@ export class UhkOperations {
|
||||
|
||||
/**
|
||||
* IpcMain handler. Send the UserConfiguration to the UHK Device and send a response with the result.
|
||||
* @param {string} json - UserConfiguration in JSON format
|
||||
* @param {Buffer} buffer - UserConfiguration buffer
|
||||
* @returns {Promise<void>}
|
||||
* @private
|
||||
*/
|
||||
private async sendUserConfigToKeyboard(json: string): Promise<void> {
|
||||
const buffer: Buffer = new Buffer(JSON.parse(json).data);
|
||||
private async sendUserConfigToKeyboard(buffer: Buffer): Promise<void> {
|
||||
const fragments = getTransferBuffers(UsbCommand.WriteStagingUserConfig, buffer);
|
||||
for (const fragment of fragments) {
|
||||
await this.device.write(fragment);
|
||||
|
||||
773
packages/uhk-web/package-lock.json
generated
773
packages/uhk-web/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -38,7 +38,6 @@
|
||||
"@types/jasminewd2": "2.0.2",
|
||||
"@types/jquery": "3.2.9",
|
||||
"@types/lodash-es": "4.17.0",
|
||||
"@types/node-hid": "0.5.2",
|
||||
"@types/usb": "1.1.3",
|
||||
"angular-confirmation-popover": "3.2.0",
|
||||
"angular-notifier": "2.0.0",
|
||||
@@ -74,7 +73,6 @@
|
||||
"ng2-select2": "1.0.0-beta.10",
|
||||
"ngx-clipboard": "8.0.0",
|
||||
"ngrx-store-freeze": "0.1.9",
|
||||
"node-hid": "0.5.4",
|
||||
"nouislider": "^10.1.0",
|
||||
"postcss-loader": "1.3.3",
|
||||
"postcss-url": "5.1.2",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, HostListener, ViewEncapsulation } from '@angular/core';
|
||||
import { Component, ViewEncapsulation } from '@angular/core';
|
||||
import { animate, style, transition, trigger } from '@angular/animations';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
@@ -14,7 +14,6 @@ import {
|
||||
saveToKeyboardState
|
||||
} from './store';
|
||||
import { ProgressButtonState } from './store/reducers/progress-button-state';
|
||||
import { SaveUserConfigInBinaryFileAction, SaveUserConfigInJsonFileAction } from './store/actions/user-config';
|
||||
|
||||
@Component({
|
||||
selector: 'main-app',
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DeviceConfigurationComponent } from './configuration/device-configurati
|
||||
import { DeviceFirmwareComponent } from './firmware/device-firmware.component';
|
||||
import { MouseSpeedComponent } from './mouse-speed/mouse-speed.component';
|
||||
import { LEDBrightnessComponent } from './led-brightness/led-brightness.component';
|
||||
import { RestoreConfigurationComponent } from './restore-configuration/restore-configuration.component';
|
||||
|
||||
export const deviceRoutes: Routes = [
|
||||
{
|
||||
@@ -29,6 +30,10 @@ export const deviceRoutes: Routes = [
|
||||
{
|
||||
path: 'firmware',
|
||||
component: DeviceFirmwareComponent
|
||||
},
|
||||
{
|
||||
path: 'restore-user-configuration',
|
||||
component: RestoreConfigurationComponent
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -2,4 +2,5 @@ export * from './configuration/device-configuration.component';
|
||||
export * from './firmware/device-firmware.component';
|
||||
export * from './mouse-speed/mouse-speed.component';
|
||||
export * from './led-brightness/led-brightness.component';
|
||||
export * from './restore-configuration/restore-configuration.component';
|
||||
export * from './device.routes';
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
<h1>
|
||||
<i class="fa fa-exclamation-circle"></i>
|
||||
<span>Fix configuration</span>
|
||||
</h1>
|
||||
|
||||
<p>
|
||||
Your on-board device configuration is invalid.
|
||||
</p>
|
||||
<button class="btn btn-primary"
|
||||
*ngIf="state.hasBackupUserConfiguration"
|
||||
[disabled]="state.restoringUserConfiguration"
|
||||
(click)="restoreUserConfiguration()"> Restore the last valid device configuration
|
||||
</button>
|
||||
|
||||
<button class="btn btn-danger"
|
||||
*ngIf="!state.hasBackupUserConfiguration"
|
||||
[disabled]="state.restoringUserConfiguration"
|
||||
(click)="resetUserConfiguration()">Reset device configuration
|
||||
</button>
|
||||
@@ -0,0 +1,10 @@
|
||||
:host {
|
||||
overflow-y: auto;
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
p {
|
||||
margin: 1.5rem 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
import { ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { AppState, getBackupUserConfigurationState } from '../../../store';
|
||||
import { ResetUserConfigurationAction, RestoreUserConfigurationFromBackupAction } from '../../../store/actions/device';
|
||||
import { RestoreConfigurationState } from '../../../models/restore-configuration-state';
|
||||
|
||||
@Component({
|
||||
selector: 'restore-configuration',
|
||||
templateUrl: './restore-configuration.component.html',
|
||||
styleUrls: ['./restore-configuration.component.scss'],
|
||||
host: {
|
||||
'class': 'container-fluid'
|
||||
}
|
||||
})
|
||||
export class RestoreConfigurationComponent implements OnInit, OnDestroy {
|
||||
state: RestoreConfigurationState;
|
||||
|
||||
private stateSubscription: Subscription;
|
||||
|
||||
constructor(private store: Store<AppState>,
|
||||
private cdRef: ChangeDetectorRef) {
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
if (this.stateSubscription) {
|
||||
this.stateSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.stateSubscription = this.store
|
||||
.select(getBackupUserConfigurationState)
|
||||
.subscribe(data => {
|
||||
this.state = data;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
resetUserConfiguration() {
|
||||
this.store.dispatch(new ResetUserConfigurationAction());
|
||||
}
|
||||
|
||||
restoreUserConfiguration(): void {
|
||||
this.store.dispatch(new RestoreUserConfigurationFromBackupAction());
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,7 @@
|
||||
<input #deviceName cancelable
|
||||
class="pane-title__name"
|
||||
type="text"
|
||||
[readonly]="state.restoreUserConfiguration"
|
||||
(change)="editDeviceName($event.target.value)"
|
||||
(keyup.enter)="deviceName.blur()"
|
||||
(keyup)="calculateHeaderTextWidth($event.target.value)">
|
||||
@@ -17,33 +18,43 @@
|
||||
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'configuration')"></i>
|
||||
</div>
|
||||
<ul [@toggler]="animation['configuration']">
|
||||
<li class="sidebar__level-2--item">
|
||||
<li class="sidebar__level-2--item"
|
||||
*ngIf="!state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/mouse-speed']"
|
||||
[class.disabled]="updatingFirmware$ | async">Mouse speed</a>
|
||||
[class.disabled]="state.updatingFirmware">Mouse speed</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<li class="sidebar__level-2--item"
|
||||
*ngIf="!state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/led-brightness']"
|
||||
[class.disabled]="updatingFirmware$ | async">LED brightness</a>
|
||||
[class.disabled]="state.updatingFirmware">LED brightness</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<li class="sidebar__level-2--item"
|
||||
*ngIf="!state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/configuration']"
|
||||
[class.disabled]="updatingFirmware$ | async">Configuration</a>
|
||||
[class.disabled]="state.updatingFirmware">Configuration</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item"
|
||||
*ngIf="state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/restore-user-configuration']">Fix configuration</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/device/firmware']"
|
||||
[class.disabled]="updatingFirmware$ | async">Firmware</a>
|
||||
[class.disabled]="state.updatingFirmware">Firmware</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar__level-1--item">
|
||||
<li class="sidebar__level-1--item"
|
||||
*ngIf="!state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-1">
|
||||
<i class="fa fa-keyboard-o"></i> Keymaps
|
||||
<!--a [routerLink]="['/keymap/add']"
|
||||
@@ -55,10 +66,10 @@
|
||||
(click)="toggleHide($event, 'keymap')"></i>
|
||||
</div>
|
||||
<ul [@toggler]="animation['keymap']">
|
||||
<li *ngFor="let keymap of keymaps$ | async" class="sidebar__level-2--item">
|
||||
<li *ngFor="let keymap of state.keymaps" class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/keymap', keymap.abbreviation]"
|
||||
[class.disabled]="updatingFirmware$ | async">{{keymap.name}}</a>
|
||||
[class.disabled]="state.updatingFirmware">{{keymap.name}}</a>
|
||||
<i *ngIf="keymap.isDefault" class="fa fa-star sidebar__fav"
|
||||
title="This is the default keymap which gets activated when powering the keyboard."
|
||||
data-toggle="tooltip" data-placement="bottom"></i>
|
||||
@@ -66,26 +77,27 @@
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar__level-1--item">
|
||||
<li class="sidebar__level-1--item"
|
||||
*ngIf="!state.restoreUserConfiguration">
|
||||
<div class="sidebar__level-1">
|
||||
<i class="fa fa-play"></i> Macros
|
||||
<a (click)="addMacro()"
|
||||
class="btn btn-default pull-right btn-sm"
|
||||
[class.disabled]="updatingFirmware$ | async">
|
||||
[class.disabled]="state.updatingFirmware">
|
||||
<i class="fa fa-plus"></i>
|
||||
</a>
|
||||
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'macro')"></i>
|
||||
</div>
|
||||
<ul [@toggler]="animation['macro']">
|
||||
<li *ngFor="let macro of macros$ | async" class="sidebar__level-2--item">
|
||||
<li *ngFor="let macro of state.macros" class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/macro', macro.id]"
|
||||
[class.disabled]="updatingFirmware$ | async">{{macro.name}}</a>
|
||||
[class.disabled]="state.updatingFirmware">{{macro.name}}</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="sidebar__level-1--item" *ngIf="showAddonMenu$ | async">
|
||||
<li class="sidebar__level-1--item" *ngIf="state.showAddonMenu">
|
||||
<div class="sidebar__level-1">
|
||||
<i class="fa fa-puzzle-piece"></i> Add-on modules
|
||||
<i class="fa fa-chevron-up pull-right" (click)="toggleHide($event, 'addon')"></i>
|
||||
@@ -94,25 +106,25 @@
|
||||
<li class="sidebar__level-2--item" data-name="Key cluster" data-abbrev="">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/add-on', 'Key cluster']"
|
||||
[class.disabled]="updatingFirmware$ | async">Key cluster</a>
|
||||
[class.disabled]="state.updatingFirmware">Key cluster</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item" data-name="Trackball" data-abbrev="">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/add-on', 'Trackball']"
|
||||
[class.disabled]="updatingFirmware$ | async">Trackball</a>
|
||||
[class.disabled]="state.updatingFirmware">Trackball</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item" data-name="Toucpad" data-abbrev="">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/add-on', 'Touchpad']"
|
||||
[class.disabled]="updatingFirmware$ | async">Touchpad</a>
|
||||
[class.disabled]="state.updatingFirmware">Touchpad</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item" data-name="Trackpoint" data-abbrev="">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/add-on', 'Trackpoint']"
|
||||
[class.disabled]="updatingFirmware$ | async">Trackpoint</a>
|
||||
[class.disabled]="state.updatingFirmware">Trackpoint</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -123,19 +135,19 @@
|
||||
<div class="sidebar__level-0">
|
||||
<i class="uhk-icon uhk-icon-agent-icon"></i> Agent
|
||||
<i class="fa fa-chevron-up pull-right"
|
||||
(click)="toggleHide($event, 'agent')"></i>
|
||||
(click)="toggleHide($event, 'agent')"></i>
|
||||
</div>
|
||||
<ul [@toggler]="animation['agent']">
|
||||
<li class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/settings']"
|
||||
[class.disabled]="updatingFirmware$ | async">Settings</a>
|
||||
[class.disabled]="state.updatingFirmware">Settings</a>
|
||||
</div>
|
||||
</li>
|
||||
<li class="sidebar__level-2--item">
|
||||
<div class="sidebar__level-2" [routerLinkActive]="['active']">
|
||||
<a [routerLink]="['/about']"
|
||||
[class.disabled]="updatingFirmware$ | async">About</a>
|
||||
[class.disabled]="state.updatingFirmware">About</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -1,20 +1,27 @@
|
||||
import { AfterContentInit, Component, ElementRef, OnDestroy, Renderer2, ViewChild } from '@angular/core';
|
||||
import {
|
||||
AfterContentInit,
|
||||
ChangeDetectionStrategy,
|
||||
ChangeDetectorRef,
|
||||
Component,
|
||||
ElementRef,
|
||||
OnDestroy, OnInit,
|
||||
Renderer2,
|
||||
ViewChild
|
||||
} from '@angular/core';
|
||||
import { animate, state, style, transition, trigger } from '@angular/animations';
|
||||
import { Keymap, Macro } from 'uhk-common';
|
||||
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import 'rxjs/add/operator/do';
|
||||
import 'rxjs/add/operator/map';
|
||||
import 'rxjs/add/operator/let';
|
||||
|
||||
import { AppState, getDeviceName, runningInElectron, showAddonMenu, updatingFirmware } from '../../store';
|
||||
import { AppState, getSideMenuPageState } from '../../store';
|
||||
import { MacroActions } from '../../store/actions';
|
||||
import { getKeymaps, getMacros } from '../../store/reducers/user-configuration';
|
||||
import * as util from '../../util';
|
||||
import { RenameUserConfigurationAction } from '../../store/actions/user-config';
|
||||
import { SideMenuPageState } from '../../models/side-menu-page-state';
|
||||
|
||||
@Component({
|
||||
animations: [
|
||||
@@ -30,24 +37,19 @@ import { RenameUserConfigurationAction } from '../../store/actions/user-config';
|
||||
],
|
||||
selector: 'side-menu',
|
||||
templateUrl: './side-menu.component.html',
|
||||
styleUrls: ['./side-menu.component.scss']
|
||||
styleUrls: ['./side-menu.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush
|
||||
})
|
||||
export class SideMenuComponent implements AfterContentInit, OnDestroy {
|
||||
showAddonMenu$: Observable<boolean>;
|
||||
runInElectron$: Observable<boolean>;
|
||||
updatingFirmware$: Observable<boolean>;
|
||||
|
||||
deviceName$: Observable<string>;
|
||||
deviceNameSubscription: Subscription;
|
||||
keymaps$: Observable<Keymap[]>;
|
||||
macros$: Observable<Macro[]>;
|
||||
export class SideMenuComponent implements AfterContentInit, OnInit, OnDestroy {
|
||||
state: SideMenuPageState;
|
||||
animation: { [key: string]: 'active' | 'inactive' };
|
||||
deviceNameValue: string;
|
||||
updatingFirmware = false;
|
||||
updatingFirmwareSubscription: Subscription;
|
||||
@ViewChild('deviceName') deviceName: ElementRef;
|
||||
|
||||
constructor(private store: Store<AppState>, private renderer: Renderer2) {
|
||||
private stateSubscription: Subscription;
|
||||
|
||||
constructor(private store: Store<AppState>,
|
||||
private renderer: Renderer2,
|
||||
private cdRef: ChangeDetectorRef) {
|
||||
this.animation = {
|
||||
device: 'active',
|
||||
configuration: 'active',
|
||||
@@ -55,20 +57,13 @@ export class SideMenuComponent implements AfterContentInit, OnDestroy {
|
||||
macro: 'active',
|
||||
addon: 'active'
|
||||
};
|
||||
}
|
||||
|
||||
this.keymaps$ = store.let(getKeymaps());
|
||||
this.macros$ = store.let(getMacros());
|
||||
|
||||
this.showAddonMenu$ = this.store.select(showAddonMenu);
|
||||
this.runInElectron$ = this.store.select(runningInElectron);
|
||||
this.deviceName$ = store.select(getDeviceName);
|
||||
this.deviceNameSubscription = this.deviceName$.subscribe(name => {
|
||||
this.deviceNameValue = name;
|
||||
ngOnInit(): void {
|
||||
this.stateSubscription = this.store.select(getSideMenuPageState).subscribe(data => {
|
||||
this.state = data;
|
||||
this.setDeviceName();
|
||||
});
|
||||
this.updatingFirmware$ = store.select(updatingFirmware);
|
||||
this.updatingFirmwareSubscription = this.updatingFirmware$.subscribe(updating => {
|
||||
this.updatingFirmware = updating;
|
||||
this.cdRef.markForCheck();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -77,12 +72,13 @@ export class SideMenuComponent implements AfterContentInit, OnDestroy {
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.deviceNameSubscription.unsubscribe();
|
||||
this.updatingFirmwareSubscription.unsubscribe();
|
||||
if (this.stateSubscription) {
|
||||
this.stateSubscription.unsubscribe();
|
||||
}
|
||||
}
|
||||
|
||||
toggleHide(event: Event, type: string) {
|
||||
if (this.updatingFirmware) {
|
||||
if (this.state.updatingFirmware) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -110,7 +106,7 @@ export class SideMenuComponent implements AfterContentInit, OnDestroy {
|
||||
}
|
||||
|
||||
editDeviceName(name: string): void {
|
||||
if (!util.isValidName(name) || name.trim() === this.deviceNameValue) {
|
||||
if (!util.isValidName(name) || name.trim() === this.state.deviceName) {
|
||||
this.setDeviceName();
|
||||
return;
|
||||
}
|
||||
@@ -126,7 +122,7 @@ export class SideMenuComponent implements AfterContentInit, OnDestroy {
|
||||
|
||||
private setDeviceName(): void {
|
||||
if (this.deviceName) {
|
||||
this.renderer.setProperty(this.deviceName.nativeElement, 'value', this.deviceNameValue);
|
||||
this.renderer.setProperty(this.deviceName.nativeElement, 'value', this.state.deviceName);
|
||||
this.calculateHeaderTextWidth(this.deviceName.nativeElement.value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface RestoreConfigurationState {
|
||||
restoringUserConfiguration: boolean;
|
||||
hasBackupUserConfiguration: boolean;
|
||||
}
|
||||
11
packages/uhk-web/src/app/models/side-menu-page-state.ts
Normal file
11
packages/uhk-web/src/app/models/side-menu-page-state.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Keymap, Macro } from 'uhk-common';
|
||||
|
||||
export interface SideMenuPageState {
|
||||
showAddonMenu: boolean;
|
||||
runInElectron: boolean;
|
||||
updatingFirmware: boolean;
|
||||
deviceName: string;
|
||||
keymaps: Keymap[];
|
||||
macros: Macro[];
|
||||
restoreUserConfiguration: boolean;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable, NgZone } from '@angular/core';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
|
||||
import { DeviceConnectionState, IpcEvents, IpcResponse, LogService } from 'uhk-common';
|
||||
import { DeviceConnectionState, IpcEvents, IpcResponse, LogService, SaveUserConfigurationData } from 'uhk-common';
|
||||
import { AppState } from '../store';
|
||||
import { IpcCommonRenderer } from './ipc-common-renderer';
|
||||
import {
|
||||
@@ -26,8 +26,8 @@ export class DeviceRendererService {
|
||||
this.ipcRenderer.send(IpcEvents.device.setPrivilegeOnLinux);
|
||||
}
|
||||
|
||||
saveUserConfiguration(buffer: Buffer): void {
|
||||
this.ipcRenderer.send(IpcEvents.device.saveUserConfiguration, JSON.stringify(buffer));
|
||||
saveUserConfiguration(data: SaveUserConfigurationData): void {
|
||||
this.ipcRenderer.send(IpcEvents.device.saveUserConfiguration, JSON.stringify(data));
|
||||
}
|
||||
|
||||
loadConfigurationFromKeyboard(): void {
|
||||
|
||||
@@ -16,7 +16,8 @@ import {
|
||||
DeviceConfigurationComponent,
|
||||
DeviceFirmwareComponent,
|
||||
MouseSpeedComponent,
|
||||
LEDBrightnessComponent
|
||||
LEDBrightnessComponent,
|
||||
RestoreConfigurationComponent
|
||||
} from './components/device';
|
||||
import { KeymapAddComponent, KeymapEditComponent, KeymapHeaderComponent } from './components/keymap';
|
||||
import { LayersComponent } from './components/layers';
|
||||
@@ -174,7 +175,8 @@ import { Autofocus } from './directives/autofocus/autofocus.directive';
|
||||
XtermComponent,
|
||||
SliderWrapperComponent,
|
||||
EditableTextComponent,
|
||||
Autofocus
|
||||
Autofocus,
|
||||
RestoreConfigurationComponent
|
||||
],
|
||||
imports: [
|
||||
CommonModule,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { DeviceConnectionState, IpcResponse, type } from 'uhk-common';
|
||||
import { HardwareModules } from '../../../../../uhk-common/src/models';
|
||||
import { DeviceConnectionState, HardwareModules, IpcResponse, type } from 'uhk-common';
|
||||
|
||||
const PREFIX = '[device] ';
|
||||
|
||||
@@ -24,7 +23,10 @@ export const ActionTypes = {
|
||||
UPDATE_FIRMWARE_SUCCESS: type(PREFIX + 'update firmware success'),
|
||||
UPDATE_FIRMWARE_FAILED: type(PREFIX + 'update firmware failed'),
|
||||
UPDATE_FIRMWARE_OK_BUTTON: type(PREFIX + 'update firmware ok button click'),
|
||||
MODULES_INFO_LOADED: type(PREFIX + 'module info loaded')
|
||||
MODULES_INFO_LOADED: type(PREFIX + 'module info loaded'),
|
||||
HAS_BACKUP_USER_CONFIGURATION: type(PREFIX + 'Store backup user configuration'),
|
||||
RESTORE_CONFIGURATION_FROM_BACKUP: type(PREFIX + 'Restore configuration from backup'),
|
||||
RESTORE_CONFIGURATION_FROM_BACKUP_SUCCESS: type(PREFIX + 'Restore configuration from backup success')
|
||||
};
|
||||
|
||||
export class SetPrivilegeOnLinuxAction implements Action {
|
||||
@@ -123,6 +125,21 @@ export class HardwareModulesLoadedAction implements Action {
|
||||
}
|
||||
}
|
||||
|
||||
export class RestoreUserConfigurationFromBackupAction implements Action {
|
||||
type = ActionTypes.RESTORE_CONFIGURATION_FROM_BACKUP;
|
||||
}
|
||||
|
||||
export class HasBackupUserConfigurationAction implements Action {
|
||||
type = ActionTypes.HAS_BACKUP_USER_CONFIGURATION;
|
||||
|
||||
constructor(public payload: boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
export class RestoreUserConfigurationFromBackupSuccessAction implements Action {
|
||||
type = ActionTypes.RESTORE_CONFIGURATION_FROM_BACKUP_SUCCESS;
|
||||
}
|
||||
|
||||
export type Actions
|
||||
= SetPrivilegeOnLinuxAction
|
||||
| SetPrivilegeOnLinuxReplyAction
|
||||
@@ -142,4 +159,7 @@ export type Actions
|
||||
| UpdateFirmwareFailedAction
|
||||
| UpdateFirmwareOkButtonAction
|
||||
| HardwareModulesLoadedAction
|
||||
| RestoreUserConfigurationFromBackupAction
|
||||
| HasBackupUserConfigurationAction
|
||||
| RestoreUserConfigurationFromBackupSuccessAction
|
||||
;
|
||||
|
||||
@@ -13,11 +13,19 @@ import 'rxjs/add/operator/mergeMap';
|
||||
import 'rxjs/add/operator/withLatestFrom';
|
||||
import 'rxjs/add/operator/switchMap';
|
||||
|
||||
import { DeviceConnectionState, IpcResponse, NotificationType, UhkBuffer, UserConfiguration } from 'uhk-common';
|
||||
import {
|
||||
DeviceConnectionState,
|
||||
HardwareConfiguration,
|
||||
IpcResponse,
|
||||
NotificationType,
|
||||
UserConfiguration
|
||||
} from 'uhk-common';
|
||||
import {
|
||||
ActionTypes,
|
||||
ConnectionStateChangedAction,
|
||||
HideSaveToKeyboardButton,
|
||||
ResetUserConfigurationAction,
|
||||
RestoreUserConfigurationFromBackupSuccessAction,
|
||||
SaveConfigurationAction,
|
||||
SaveConfigurationReplyAction,
|
||||
SaveToKeyboardSuccessAction,
|
||||
@@ -93,9 +101,8 @@ export class DeviceEffects {
|
||||
saveConfiguration$: Observable<Action> = this.actions$
|
||||
.ofType(ActionTypes.SAVE_CONFIGURATION)
|
||||
.withLatestFrom(this.store)
|
||||
.map(([action, state]) => state.userConfiguration)
|
||||
.do((userConfiguration: UserConfiguration) => {
|
||||
setTimeout(() => this.sendUserConfigToKeyboard(userConfiguration), 100);
|
||||
.do(([action, state]) => {
|
||||
setTimeout(() => this.sendUserConfigToKeyboard(state.userConfiguration, state.app.hardwareConfig), 100);
|
||||
})
|
||||
.switchMap(() => Observable.empty());
|
||||
|
||||
@@ -122,8 +129,18 @@ export class DeviceEffects {
|
||||
@Effect()
|
||||
autoHideSaveToKeyboardButton$: Observable<Action> = this.actions$
|
||||
.ofType(ActionTypes.SAVE_TO_KEYBOARD_SUCCESS)
|
||||
.switchMap(() => Observable.timer(1000)
|
||||
.switchMap(() => Observable.of(new HideSaveToKeyboardButton()))
|
||||
.withLatestFrom(this.store)
|
||||
.switchMap(([action, state]) => Observable.timer(1000)
|
||||
.mergeMap(() => {
|
||||
const actions = [new HideSaveToKeyboardButton()];
|
||||
|
||||
if (state.device.hasBackupUserConfiguration) {
|
||||
actions.push(new RestoreUserConfigurationFromBackupSuccessAction());
|
||||
this.router.navigate(['/']);
|
||||
}
|
||||
|
||||
return actions;
|
||||
})
|
||||
);
|
||||
|
||||
@Effect()
|
||||
@@ -193,6 +210,10 @@ export class DeviceEffects {
|
||||
.ofType<UpdateFirmwareOkButtonAction>(ActionTypes.UPDATE_FIRMWARE_OK_BUTTON)
|
||||
.do(() => this.deviceRendererService.startConnectionPoller());
|
||||
|
||||
@Effect() restoreUserConfiguration$ = this.actions$
|
||||
.ofType<ResetUserConfigurationAction>(ActionTypes.RESTORE_CONFIGURATION_FROM_BACKUP)
|
||||
.map(() => new SaveConfigurationAction());
|
||||
|
||||
constructor(private actions$: Actions,
|
||||
private router: Router,
|
||||
private deviceRendererService: DeviceRendererService,
|
||||
@@ -201,9 +222,10 @@ export class DeviceEffects {
|
||||
private defaultUserConfigurationService: DefaultUserConfigurationService) {
|
||||
}
|
||||
|
||||
private sendUserConfigToKeyboard(userConfiguration: UserConfiguration): void {
|
||||
const uhkBuffer = new UhkBuffer();
|
||||
userConfiguration.toBinary(uhkBuffer);
|
||||
this.deviceRendererService.saveUserConfiguration(uhkBuffer.getBufferContent());
|
||||
private sendUserConfigToKeyboard(userConfiguration: UserConfiguration, hardwareConfig: HardwareConfiguration): void {
|
||||
this.deviceRendererService.saveUserConfiguration({
|
||||
uniqueId: hardwareConfig && hardwareConfig.uniqueId,
|
||||
configuration: userConfiguration.toJsonObject()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,9 @@ import 'rxjs/add/observable/of';
|
||||
import 'rxjs/add/observable/empty';
|
||||
|
||||
import {
|
||||
getHardwareConfigFromDeviceResponse,
|
||||
getUserConfigFromDeviceResponse,
|
||||
ConfigurationReply,
|
||||
HardwareConfiguration,
|
||||
LogService,
|
||||
NotificationType,
|
||||
UhkBuffer,
|
||||
@@ -43,7 +44,11 @@ import {
|
||||
ShowNotificationAction,
|
||||
UndoLastAction
|
||||
} from '../actions/app';
|
||||
import { HardwareModulesLoadedAction, ShowSaveToKeyboardButtonAction } from '../actions/device';
|
||||
import {
|
||||
HardwareModulesLoadedAction,
|
||||
ShowSaveToKeyboardButtonAction,
|
||||
HasBackupUserConfigurationAction
|
||||
} from '../actions/device';
|
||||
import { DeviceRendererService } from '../../services/device-renderer.service';
|
||||
import { UndoUserConfigData } from '../../models/undo-user-config-data';
|
||||
import { UploadFileData } from '../../models/upload-file-data';
|
||||
@@ -51,29 +56,6 @@ import { UploadFileData } from '../../models/upload-file-data';
|
||||
@Injectable()
|
||||
export class UserConfigEffects {
|
||||
|
||||
private static getUserConfigFromDeviceResponse(json: string): UserConfiguration {
|
||||
const data = JSON.parse(json);
|
||||
const userConfig = new UserConfiguration();
|
||||
userConfig.fromBinary(UhkBuffer.fromArray(data));
|
||||
|
||||
if (userConfig.userConfigMajorVersion > 0) {
|
||||
return userConfig;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static getHardwareConfigFromDeviceResponse(json: string): HardwareConfiguration {
|
||||
const data = JSON.parse(json);
|
||||
const hardwareConfig = new HardwareConfiguration();
|
||||
hardwareConfig.fromBinary(UhkBuffer.fromArray(data));
|
||||
|
||||
if (hardwareConfig.uniqueId > 0) {
|
||||
return hardwareConfig;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Effect() loadUserConfig$: Observable<Action> = defer(() => {
|
||||
return Observable.of(new LoadUserConfigSuccessAction(this.getUserConfiguration()));
|
||||
});
|
||||
@@ -146,23 +128,24 @@ export class UserConfigEffects {
|
||||
}
|
||||
|
||||
const result = [];
|
||||
let newPageDestination = ['/'];
|
||||
|
||||
try {
|
||||
const userConfig = UserConfigEffects.getUserConfigFromDeviceResponse(data.userConfiguration);
|
||||
const userConfig = getUserConfigFromDeviceResponse(data.userConfiguration);
|
||||
result.push(new LoadUserConfigSuccessAction(userConfig));
|
||||
|
||||
} catch (err) {
|
||||
this.logService.error('Eeprom user-config parse error:', err);
|
||||
result.push(
|
||||
new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: err
|
||||
}));
|
||||
const userConfig = new UserConfiguration().fromJsonObject(data.backupConfiguration);
|
||||
|
||||
result.push(new LoadUserConfigSuccessAction(this.getUserConfiguration()));
|
||||
result.push(new HasBackupUserConfigurationAction(!!data.backupConfiguration));
|
||||
result.push(new LoadUserConfigSuccessAction(userConfig));
|
||||
|
||||
newPageDestination = ['/device/restore-user-configuration'];
|
||||
}
|
||||
|
||||
try {
|
||||
const hardwareConfig = UserConfigEffects.getHardwareConfigFromDeviceResponse(data.hardwareConfiguration);
|
||||
const hardwareConfig = getHardwareConfigFromDeviceResponse(data.hardwareConfiguration);
|
||||
result.push(new LoadHardwareConfigurationSuccessAction(hardwareConfig));
|
||||
} catch (err) {
|
||||
this.logService.error('Eeprom hardware-config parse error:', err);
|
||||
@@ -175,7 +158,7 @@ export class UserConfigEffects {
|
||||
|
||||
result.push(new HardwareModulesLoadedAction(data.modules));
|
||||
|
||||
this.router.navigate(['/']);
|
||||
this.router.navigate(newPageDestination);
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@@ -39,7 +39,6 @@ export const metaReducers: MetaReducer<AppState>[] = environment.production
|
||||
: [storeFreeze];
|
||||
|
||||
export const getUserConfiguration = (state: AppState) => state.userConfiguration;
|
||||
export const getDeviceName = createSelector(getUserConfiguration, fromUserConfig.getDeviceName);
|
||||
|
||||
export const appState = (state: AppState) => state.app;
|
||||
|
||||
@@ -47,7 +46,6 @@ export const showAddonMenu = createSelector(appState, fromApp.showAddonMenu);
|
||||
export const getUndoableNotification = createSelector(appState, fromApp.getUndoableNotification);
|
||||
export const getPrevUserConfiguration = createSelector(appState, fromApp.getPrevUserConfiguration);
|
||||
export const runningInElectron = createSelector(appState, fromApp.runningInElectron);
|
||||
export const getHardwareConfiguration = createSelector(appState, fromApp.getHardwareConfiguration);
|
||||
export const getKeyboardLayout = createSelector(appState, fromApp.getKeyboardLayout);
|
||||
export const deviceConfigurationLoaded = createSelector(appState, fromApp.deviceConfigurationLoaded);
|
||||
export const getAgentVersionInfo = createSelector(appState, fromApp.getAgentVersionInfo);
|
||||
@@ -79,3 +77,28 @@ export const firmwareOkButtonDisabled = createSelector(deviceState, fromDevice.f
|
||||
// tslint:disable-next-line: max-line-length
|
||||
export const flashFirmwareButtonDisbabled = createSelector(runningInElectron, deviceState, (electron, state: fromDevice.State) => !electron || state.updatingFirmware);
|
||||
export const getHardwareModules = createSelector(deviceState, fromDevice.getHardwareModules);
|
||||
export const getBackupUserConfigurationState = createSelector(deviceState, fromDevice.getBackupUserConfigurationState);
|
||||
export const getRestoreUserConfiguration = createSelector(deviceState, fromDevice.getHasBackupUserConfiguration);
|
||||
|
||||
export const getSideMenuPageState = createSelector(
|
||||
showAddonMenu,
|
||||
runningInElectron,
|
||||
updatingFirmware,
|
||||
getUserConfiguration,
|
||||
getRestoreUserConfiguration,
|
||||
(showAddonMenuValue: boolean,
|
||||
runningInElectronValue: boolean,
|
||||
updatingFirmwareValue: boolean,
|
||||
userConfiguration: UserConfiguration,
|
||||
restoreUserConfiguration: boolean) => {
|
||||
return {
|
||||
showAddonMenu: showAddonMenuValue,
|
||||
runInElectron: runningInElectronValue,
|
||||
updatingFirmware: updatingFirmwareValue,
|
||||
deviceName: userConfiguration.deviceName,
|
||||
keymaps: userConfiguration.keymaps,
|
||||
macros: userConfiguration.macros,
|
||||
restoreUserConfiguration
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
@@ -152,7 +152,6 @@ export const showAddonMenu = (state: State) => state.showAddonMenu;
|
||||
export const getUndoableNotification = (state: State) => state.undoableNotification;
|
||||
export const getPrevUserConfiguration = (state: State) => state.prevUserConfig;
|
||||
export const runningInElectron = (state: State) => state.runningInElectron;
|
||||
export const getHardwareConfiguration = (state: State) => state.hardwareConfig;
|
||||
export const getKeyboardLayout = (state: State): KeyboardLayout => {
|
||||
if (state.hardwareConfig && state.hardwareConfig.isIso) {
|
||||
return KeyboardLayout.ISO;
|
||||
|
||||
@@ -6,11 +6,13 @@ import {
|
||||
ConnectionStateChangedAction,
|
||||
HardwareModulesLoadedAction,
|
||||
SaveConfigurationAction,
|
||||
HasBackupUserConfigurationAction,
|
||||
UpdateFirmwareFailedAction
|
||||
} from '../actions/device';
|
||||
import { ActionTypes as AppActions, ElectronMainLogReceivedAction } from '../actions/app';
|
||||
import { initProgressButtonState, ProgressButtonState } from './progress-button-state';
|
||||
import { XtermCssClass, XtermLog } from '../../models/xterm-log';
|
||||
import { RestoreConfigurationState } from '../../models/restore-configuration-state';
|
||||
|
||||
export interface State {
|
||||
connected: boolean;
|
||||
@@ -20,6 +22,8 @@ export interface State {
|
||||
firmwareUpdateFinished: boolean;
|
||||
modules: HardwareModules;
|
||||
log: Array<XtermLog>;
|
||||
restoringUserConfiguration: boolean;
|
||||
hasBackupUserConfiguration: boolean;
|
||||
}
|
||||
|
||||
export const initialState: State = {
|
||||
@@ -37,7 +41,9 @@ export const initialState: State = {
|
||||
firmwareVersion: ''
|
||||
}
|
||||
},
|
||||
log: [{message: '', cssClass: XtermCssClass.standard}]
|
||||
log: [{message: '', cssClass: XtermCssClass.standard}],
|
||||
restoringUserConfiguration: false,
|
||||
hasBackupUserConfiguration: false
|
||||
};
|
||||
|
||||
export function reducer(state = initialState, action: Action) {
|
||||
@@ -87,7 +93,8 @@ export function reducer(state = initialState, action: Action) {
|
||||
showButton: true,
|
||||
text: 'Saved!',
|
||||
action: null
|
||||
}
|
||||
},
|
||||
restoringUserConfiguration: false
|
||||
};
|
||||
}
|
||||
|
||||
@@ -167,6 +174,25 @@ export function reducer(state = initialState, action: Action) {
|
||||
modules: (action as HardwareModulesLoadedAction).payload
|
||||
};
|
||||
|
||||
case ActionTypes.RESET_USER_CONFIGURATION:
|
||||
case ActionTypes.RESTORE_CONFIGURATION_FROM_BACKUP:
|
||||
return {
|
||||
...state,
|
||||
restoringUserConfiguration: true
|
||||
};
|
||||
|
||||
case ActionTypes.HAS_BACKUP_USER_CONFIGURATION:
|
||||
return {
|
||||
...state,
|
||||
hasBackupUserConfiguration: (action as HasBackupUserConfigurationAction).payload
|
||||
};
|
||||
|
||||
case ActionTypes.RESTORE_CONFIGURATION_FROM_BACKUP_SUCCESS:
|
||||
return {
|
||||
...state,
|
||||
hasBackupUserConfiguration: false
|
||||
};
|
||||
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
@@ -179,3 +205,10 @@ export const getSaveToKeyboardState = (state: State) => state.saveToKeyboard;
|
||||
export const xtermLog = (state: State) => state.log;
|
||||
export const firmwareOkButtonDisabled = (state: State) => !state.firmwareUpdateFinished;
|
||||
export const getHardwareModules = (state: State) => state.modules;
|
||||
export const getHasBackupUserConfiguration = (state: State) => state.hasBackupUserConfiguration;
|
||||
export const getBackupUserConfigurationState = (state: State): RestoreConfigurationState => {
|
||||
return {
|
||||
restoringUserConfiguration: state.restoringUserConfiguration,
|
||||
hasBackupUserConfiguration: state.hasBackupUserConfiguration
|
||||
};
|
||||
};
|
||||
|
||||
@@ -494,5 +494,3 @@ function setKeyActionToLayer(newLayer: Layer, moduleIndex: number, keyIndex: num
|
||||
newModule.keyActions = newModule.keyActions.slice();
|
||||
newModule.keyActions[keyIndex] = newKeyAction;
|
||||
}
|
||||
|
||||
export const getDeviceName = (state: UserConfiguration) => state.deviceName;
|
||||
|
||||
1
packages/usb/invalid-config.bin
Normal file
1
packages/usb/invalid-config.bin
Normal file
@@ -0,0 +1 @@
|
||||
@#%#@^^@#^@#$invalid config@#$@^%@^@@%
|
||||
117
packages/usb/package-lock.json
generated
117
packages/usb/package-lock.json
generated
@@ -149,6 +149,14 @@
|
||||
"strip-dirs": "2.1.0"
|
||||
}
|
||||
},
|
||||
"decompress-response": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
|
||||
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
|
||||
"requires": {
|
||||
"mimic-response": "1.0.0"
|
||||
}
|
||||
},
|
||||
"decompress-tar": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz",
|
||||
@@ -216,6 +224,11 @@
|
||||
"resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
|
||||
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
|
||||
},
|
||||
"detect-libc": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
|
||||
"integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
|
||||
},
|
||||
"end-of-stream": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
|
||||
@@ -339,9 +352,9 @@
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
||||
},
|
||||
"ini": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
|
||||
"integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
|
||||
"version": "1.3.5",
|
||||
"resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
|
||||
"integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
|
||||
},
|
||||
"interpret": {
|
||||
"version": "1.0.4",
|
||||
@@ -386,6 +399,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz",
|
||||
"integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4="
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
@@ -415,14 +433,17 @@
|
||||
}
|
||||
},
|
||||
"nan": {
|
||||
"version": "2.6.2",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
|
||||
"integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U="
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
|
||||
"integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA=="
|
||||
},
|
||||
"node-abi": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz",
|
||||
"integrity": "sha512-6oxV13poCOv7TfGvhsSz6XZWpXeKkdGVh72++cs33OfMh3KAX8lN84dCvmqSETyDXAFcUHtV7eJrgFBoOqZbNQ=="
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.3.0.tgz",
|
||||
"integrity": "sha512-zwm6vU3SsVgw3e9fu48JBaRBCJGIvAgysDsqtf5+vEexFE71bEOtaMWb5zr/zODZNzTPtQlqUUpC79k68Hspow==",
|
||||
"requires": {
|
||||
"semver": "5.5.0"
|
||||
}
|
||||
},
|
||||
"node-hid": {
|
||||
"version": "0.5.7",
|
||||
@@ -430,8 +451,8 @@
|
||||
"integrity": "sha512-dwwpOetL2+MGYgivbO22ML+45ieCGbueWv1rYxRgBoEc2QMp6UF6ZucEkYts1IA3YPWJNkmpGh6dqQ85n19szw==",
|
||||
"requires": {
|
||||
"bindings": "1.3.0",
|
||||
"nan": "2.6.2",
|
||||
"prebuild-install": "2.3.0"
|
||||
"nan": "2.10.0",
|
||||
"prebuild-install": "2.5.1"
|
||||
}
|
||||
},
|
||||
"noop-logger": {
|
||||
@@ -512,24 +533,25 @@
|
||||
}
|
||||
},
|
||||
"prebuild-install": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.3.0.tgz",
|
||||
"integrity": "sha512-gzjq2oHB8oMbzJSsSh9MQ64zrXZGt092/uT4TLZlz2qnrPxpWqp4vYB7LZrDxnlxf5RfbCjkgDI/z0EIVuYzAw==",
|
||||
"version": "2.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.1.tgz",
|
||||
"integrity": "sha512-3DX9L6pzwc1m1ksMkW3Ky2WLgPQUBiySOfXVl3WZyAeJSyJb4wtoH9OmeRGcubAWsMlLiL8BTHbwfm/jPQE9Ag==",
|
||||
"requires": {
|
||||
"detect-libc": "1.0.3",
|
||||
"expand-template": "1.1.0",
|
||||
"github-from-package": "0.0.0",
|
||||
"minimist": "1.2.0",
|
||||
"mkdirp": "0.5.1",
|
||||
"node-abi": "2.1.1",
|
||||
"node-abi": "2.3.0",
|
||||
"noop-logger": "0.1.1",
|
||||
"npmlog": "4.1.2",
|
||||
"os-homedir": "1.0.2",
|
||||
"pump": "1.0.2",
|
||||
"rc": "1.2.2",
|
||||
"simple-get": "1.4.3",
|
||||
"pump": "2.0.1",
|
||||
"rc": "1.2.6",
|
||||
"simple-get": "2.7.0",
|
||||
"tar-fs": "1.16.0",
|
||||
"tunnel-agent": "0.6.0",
|
||||
"xtend": "4.0.1"
|
||||
"which-pm-runs": "1.0.0"
|
||||
}
|
||||
},
|
||||
"process-nextick-args": {
|
||||
@@ -538,21 +560,21 @@
|
||||
"integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
|
||||
},
|
||||
"pump": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
|
||||
"integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
|
||||
"integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
},
|
||||
"rc": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz",
|
||||
"integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=",
|
||||
"version": "1.2.6",
|
||||
"resolved": "https://registry.npmjs.org/rc/-/rc-1.2.6.tgz",
|
||||
"integrity": "sha1-6xiYnG1PTxYsOZ953dKfODVWgJI=",
|
||||
"requires": {
|
||||
"deep-extend": "0.4.2",
|
||||
"ini": "1.3.4",
|
||||
"ini": "1.3.5",
|
||||
"minimist": "1.2.0",
|
||||
"strip-json-comments": "2.0.1"
|
||||
}
|
||||
@@ -610,6 +632,11 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
|
||||
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
|
||||
},
|
||||
"set-blocking": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
|
||||
@@ -640,14 +667,19 @@
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-concat": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
|
||||
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
|
||||
},
|
||||
"simple-get": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz",
|
||||
"integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=",
|
||||
"version": "2.7.0",
|
||||
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
|
||||
"integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
|
||||
"requires": {
|
||||
"decompress-response": "3.3.0",
|
||||
"once": "1.4.0",
|
||||
"unzip-response": "1.0.2",
|
||||
"xtend": "4.0.1"
|
||||
"simple-concat": "1.0.0"
|
||||
}
|
||||
},
|
||||
"string-width": {
|
||||
@@ -704,8 +736,19 @@
|
||||
"requires": {
|
||||
"chownr": "1.0.1",
|
||||
"mkdirp": "0.5.1",
|
||||
"pump": "1.0.2",
|
||||
"pump": "1.0.3",
|
||||
"tar-stream": "1.5.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"pump": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
||||
"requires": {
|
||||
"end-of-stream": "1.4.0",
|
||||
"once": "1.4.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tar-stream": {
|
||||
@@ -754,16 +797,16 @@
|
||||
"through": "2.3.8"
|
||||
}
|
||||
},
|
||||
"unzip-response": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
|
||||
"integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
|
||||
},
|
||||
"which-pm-runs": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
|
||||
"integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
|
||||
},
|
||||
"wide-align": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
|
||||
|
||||
21
packages/usb/write-userconfig.js
Executable file
21
packages/usb/write-userconfig.js
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs');
|
||||
const program = require('commander');
|
||||
const uhk = require('./uhk');
|
||||
|
||||
(async function() {
|
||||
program
|
||||
.usage(`configPath`)
|
||||
.parse(process.argv);
|
||||
|
||||
if (program.args.length < 1) {
|
||||
console.error('No configPath path specified.');
|
||||
exit(1);
|
||||
}
|
||||
const configPath = program.args[0];
|
||||
|
||||
const device = uhk.getUhkDevice();
|
||||
const configBuffer = fs.readFileSync(configPath);
|
||||
await uhk.writeConfig(device, configBuffer, false);
|
||||
await uhk.launchEepromTransfer(device, uhk.eepromOperations.write, uhk.configBufferIds.stagingUserConfig);
|
||||
})();
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env ts-node
|
||||
///<reference path="./node_modules/@types/node/index.d.ts"/>
|
||||
|
||||
import { UhkBlhost, UhkHidDevice, UhkOperations } from 'uhk-usb';
|
||||
import { LogService } from 'uhk-common';
|
||||
import * as fs from 'fs';
|
||||
|
||||
if (process.argv.length < 3) {
|
||||
console.log(`use: write-userconfig <path to config file.bin>`);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const fileContent = fs.readFileSync(process.argv[2]);
|
||||
const json = JSON.stringify(fileContent);
|
||||
const logger = new LogService();
|
||||
const uhkDevice = new UhkHidDevice(logger);
|
||||
const uhkBlHost = new UhkBlhost(logger, '.');
|
||||
const uhkOperations = new UhkOperations(logger, uhkBlHost, uhkDevice, '.');
|
||||
|
||||
const init = async (): Promise<void> => {
|
||||
await uhkOperations.saveUserConfiguration(json);
|
||||
};
|
||||
|
||||
init()
|
||||
.then(() => {
|
||||
console.log('Success');
|
||||
})
|
||||
.catch(error => {
|
||||
console.log(error);
|
||||
process.exit(-1);
|
||||
});
|
||||
Reference in New Issue
Block a user