Add a number of properties to the user config that are related to mou… (#501)
* Add a number of properties to the user config that are related to mouse movement, LED brightness, data model versioning, and double tap switch layer timeout. Update firmware related version numbers. * use default config if parse loaded config from device failed * add asserts to the new user config fields * separate user and hardware config parser * fix indent * fix user-config size read
This commit is contained in:
@@ -118,7 +118,7 @@ export class DeviceService {
|
||||
|
||||
if (firstRead && config === UsbCommand.ReadUserConfig) {
|
||||
firstRead = false;
|
||||
configSize = readBuffer[3] + (readBuffer[4] << 8);
|
||||
configSize = readBuffer[6] + (readBuffer[7] << 8);
|
||||
}
|
||||
}
|
||||
response = convertBufferToIntArray(configBuffer);
|
||||
|
||||
@@ -11,48 +11,47 @@ export class ModuleConfiguration {
|
||||
id: number;
|
||||
|
||||
@assertUInt8
|
||||
initialPointerSpeed: number;
|
||||
deceleratedPointerSpeedMultiplier: number;
|
||||
|
||||
@assertUInt8
|
||||
pointerAcceleration: number;
|
||||
basePointerSpeedMultiplier: number;
|
||||
|
||||
@assertUInt8
|
||||
maxPointerSpeed: number;
|
||||
acceleratedPointerSpeedMultiplier: number;
|
||||
|
||||
fromJsonObject(jsonObject: any): ModuleConfiguration {
|
||||
this.id = jsonObject.id;
|
||||
this.initialPointerSpeed = jsonObject.initialPointerSpeed;
|
||||
this.pointerAcceleration = jsonObject.pointerAcceleration;
|
||||
this.maxPointerSpeed = jsonObject.maxPointerSpeed;
|
||||
this.deceleratedPointerSpeedMultiplier = jsonObject.deceleratedPointerSpeedMultiplier;
|
||||
this.basePointerSpeedMultiplier = jsonObject.basePointerSpeedMultiplier;
|
||||
this.acceleratedPointerSpeedMultiplier = jsonObject.acceleratedPointerSpeedMultiplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
fromBinary(buffer: UhkBuffer): ModuleConfiguration {
|
||||
this.id = buffer.readUInt8();
|
||||
this.initialPointerSpeed = buffer.readUInt8();
|
||||
this.pointerAcceleration = buffer.readUInt8();
|
||||
this.maxPointerSpeed = buffer.readUInt8();
|
||||
this.deceleratedPointerSpeedMultiplier = buffer.readUInt8();
|
||||
this.basePointerSpeedMultiplier = buffer.readUInt8();
|
||||
this.acceleratedPointerSpeedMultiplier = buffer.readUInt8();
|
||||
return this;
|
||||
}
|
||||
|
||||
toJsonObject(): any {
|
||||
return {
|
||||
id: this.id,
|
||||
initialPointerSpeed: this.initialPointerSpeed,
|
||||
pointerAcceleration: this.pointerAcceleration,
|
||||
maxPointerSpeed: this.maxPointerSpeed
|
||||
deceleratedPointerSpeedMultiplier: this.deceleratedPointerSpeedMultiplier,
|
||||
basePointerSpeedMultiplier: this.basePointerSpeedMultiplier,
|
||||
acceleratedPointerSpeedMultiplier: this.acceleratedPointerSpeedMultiplier
|
||||
};
|
||||
}
|
||||
|
||||
toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt8(this.id);
|
||||
buffer.writeUInt8(this.initialPointerSpeed);
|
||||
buffer.writeUInt8(this.pointerAcceleration);
|
||||
buffer.writeUInt8(this.maxPointerSpeed);
|
||||
buffer.writeUInt8(this.deceleratedPointerSpeedMultiplier);
|
||||
buffer.writeUInt8(this.basePointerSpeedMultiplier);
|
||||
buffer.writeUInt8(this.acceleratedPointerSpeedMultiplier);
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<ModuleConfiguration id="${this.id}" >`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { assertUInt16 } from '../assert';
|
||||
import { assertUInt8, assertUInt16 } from '../assert';
|
||||
import { UhkBuffer } from '../uhk-buffer';
|
||||
import { Keymap } from './keymap';
|
||||
import { Macro } from './macro';
|
||||
@@ -8,13 +8,61 @@ import { ConfigSerializer } from '../config-serializer';
|
||||
export class UserConfiguration {
|
||||
|
||||
@assertUInt16
|
||||
dataModelVersion: number;
|
||||
dataModelMajorVersion: number;
|
||||
|
||||
@assertUInt16
|
||||
dataModelMinorVersion: number;
|
||||
|
||||
@assertUInt16
|
||||
dataModelPatchVersion: number;
|
||||
|
||||
@assertUInt16
|
||||
userConfigurationLength: number;
|
||||
|
||||
deviceName: string;
|
||||
|
||||
@assertUInt16
|
||||
doubleTapSwitchLayerTimeout: number;
|
||||
|
||||
@assertUInt8
|
||||
iconsAndLayerTextsBrightness: number;
|
||||
|
||||
@assertUInt8
|
||||
alphanumericSegmentsBrightness: number;
|
||||
|
||||
@assertUInt8
|
||||
keyBacklightBrightness: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseMoveInitialSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseMoveAcceleration: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseMoveDeceleratedSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseMoveBaseSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseMoveAcceleratedSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseScrollInitialSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseScrollAcceleration: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseScrollDeceleratedSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseScrollBaseSpeed: number;
|
||||
|
||||
@assertUInt8
|
||||
mouseScrollAcceleratedSpeed: number;
|
||||
|
||||
moduleConfigurations: ModuleConfiguration[] = [];
|
||||
|
||||
keymaps: Keymap[] = [];
|
||||
@@ -26,9 +74,25 @@ export class UserConfiguration {
|
||||
}
|
||||
|
||||
fromJsonObject(jsonObject: any): UserConfiguration {
|
||||
this.dataModelVersion = jsonObject.dataModelVersion;
|
||||
this.dataModelMajorVersion = jsonObject.dataModelMajorVersion;
|
||||
this.dataModelMinorVersion = jsonObject.dataModelMinorVersion;
|
||||
this.dataModelPatchVersion = jsonObject.dataModelPatchVersion;
|
||||
this.deviceName = jsonObject.deviceName;
|
||||
this.setDefaultDeviceName();
|
||||
this.doubleTapSwitchLayerTimeout = jsonObject.doubleTapSwitchLayerTimeout;
|
||||
this.iconsAndLayerTextsBrightness = jsonObject.iconsAndLayerTextsBrightness;
|
||||
this.alphanumericSegmentsBrightness = jsonObject.alphanumericSegmentsBrightness;
|
||||
this.keyBacklightBrightness = jsonObject.keyBacklightBrightness;
|
||||
this.mouseMoveInitialSpeed = jsonObject.mouseMoveInitialSpeed;
|
||||
this.mouseMoveAcceleration = jsonObject.mouseMoveAcceleration;
|
||||
this.mouseMoveDeceleratedSpeed = jsonObject.mouseMoveDeceleratedSpeed;
|
||||
this.mouseMoveBaseSpeed = jsonObject.mouseMoveBaseSpeed;
|
||||
this.mouseMoveAcceleratedSpeed = jsonObject.mouseMoveAcceleratedSpeed;
|
||||
this.mouseScrollInitialSpeed = jsonObject.mouseScrollInitialSpeed;
|
||||
this.mouseScrollAcceleration = jsonObject.mouseScrollAcceleration;
|
||||
this.mouseScrollDeceleratedSpeed = jsonObject.mouseScrollAcceleration;
|
||||
this.mouseScrollBaseSpeed = jsonObject.mouseScrollBaseSpeed;
|
||||
this.mouseScrollAcceleratedSpeed = jsonObject.mouseScrollAcceleratedSpeed;
|
||||
this.moduleConfigurations = jsonObject.moduleConfigurations.map((moduleConfiguration: any) => {
|
||||
return new ModuleConfiguration().fromJsonObject(moduleConfiguration);
|
||||
});
|
||||
@@ -43,10 +107,26 @@ export class UserConfiguration {
|
||||
}
|
||||
|
||||
fromBinary(buffer: UhkBuffer): UserConfiguration {
|
||||
this.dataModelVersion = buffer.readUInt16();
|
||||
this.dataModelMajorVersion = buffer.readUInt16();
|
||||
this.dataModelMinorVersion = buffer.readUInt16();
|
||||
this.dataModelPatchVersion = buffer.readUInt16();
|
||||
this.userConfigurationLength = buffer.readUInt16();
|
||||
this.deviceName = buffer.readString();
|
||||
this.setDefaultDeviceName();
|
||||
this.doubleTapSwitchLayerTimeout = buffer.readUInt16();
|
||||
this.iconsAndLayerTextsBrightness = buffer.readUInt8();
|
||||
this.alphanumericSegmentsBrightness = buffer.readUInt8();
|
||||
this.keyBacklightBrightness = buffer.readUInt8();
|
||||
this.mouseMoveInitialSpeed = buffer.readUInt8();
|
||||
this.mouseMoveAcceleration = buffer.readUInt8();
|
||||
this.mouseMoveDeceleratedSpeed = buffer.readUInt8();
|
||||
this.mouseMoveBaseSpeed = buffer.readUInt8();
|
||||
this.mouseMoveAcceleratedSpeed = buffer.readUInt8();
|
||||
this.mouseScrollInitialSpeed = buffer.readUInt8();
|
||||
this.mouseScrollAcceleration = buffer.readUInt8();
|
||||
this.mouseScrollDeceleratedSpeed = buffer.readUInt8();
|
||||
this.mouseScrollBaseSpeed = buffer.readUInt8();
|
||||
this.mouseScrollAcceleratedSpeed = buffer.readUInt8();
|
||||
this.moduleConfigurations = buffer.readArray<ModuleConfiguration>(uhkBuffer => {
|
||||
return new ModuleConfiguration().fromBinary(uhkBuffer);
|
||||
});
|
||||
@@ -67,8 +147,24 @@ export class UserConfiguration {
|
||||
|
||||
toJsonObject(): any {
|
||||
return {
|
||||
dataModelVersion: this.dataModelVersion,
|
||||
dataModelMajorVersion: this.dataModelMajorVersion,
|
||||
dataModelMinorVersion: this.dataModelMinorVersion,
|
||||
dataModelPatchVersion: this.dataModelPatchVersion,
|
||||
deviceName: this.deviceName,
|
||||
doubleTapSwitchLayerTimeout: this.doubleTapSwitchLayerTimeout,
|
||||
iconsAndLayerTextsBrightness: this.iconsAndLayerTextsBrightness,
|
||||
alphanumericSegmentsBrightness: this.alphanumericSegmentsBrightness,
|
||||
keyBacklightBrightness: this.keyBacklightBrightness,
|
||||
mouseMoveInitialSpeed: this.mouseMoveInitialSpeed,
|
||||
mouseMoveAcceleration: this.mouseMoveAcceleration,
|
||||
mouseMoveDeceleratedSpeed: this.mouseMoveDeceleratedSpeed,
|
||||
mouseMoveBaseSpeed: this.mouseMoveBaseSpeed,
|
||||
mouseMoveAcceleratedSpeed: this.mouseMoveAcceleratedSpeed,
|
||||
mouseScrollInitialSpeed: this.mouseScrollInitialSpeed,
|
||||
mouseScrollAcceleration: this.mouseScrollAcceleration,
|
||||
mouseScrollDeceleratedSpeed: this.mouseScrollDeceleratedSpeed,
|
||||
mouseScrollBaseSpeed: this.mouseScrollBaseSpeed,
|
||||
mouseScrollAcceleratedSpeed: this.mouseScrollAcceleratedSpeed,
|
||||
moduleConfigurations: this.moduleConfigurations.map(moduleConfiguration => moduleConfiguration.toJsonObject()),
|
||||
keymaps: this.keymaps.map(keymap => keymap.toJsonObject(this.macros)),
|
||||
macros: this.macros.map(macro => macro.toJsonObject())
|
||||
@@ -76,9 +172,25 @@ export class UserConfiguration {
|
||||
}
|
||||
|
||||
toBinary(buffer: UhkBuffer): void {
|
||||
buffer.writeUInt16(this.dataModelVersion);
|
||||
buffer.writeUInt16(this.dataModelMajorVersion);
|
||||
buffer.writeUInt16(this.dataModelMinorVersion);
|
||||
buffer.writeUInt16(this.dataModelPatchVersion);
|
||||
buffer.writeUInt16(this.userConfigurationLength);
|
||||
buffer.writeString(this.deviceName);
|
||||
buffer.writeUInt16(this.doubleTapSwitchLayerTimeout);
|
||||
buffer.writeUInt8(this.iconsAndLayerTextsBrightness);
|
||||
buffer.writeUInt8(this.alphanumericSegmentsBrightness);
|
||||
buffer.writeUInt8(this.keyBacklightBrightness);
|
||||
buffer.writeUInt8(this.mouseMoveInitialSpeed);
|
||||
buffer.writeUInt8(this.mouseMoveAcceleration);
|
||||
buffer.writeUInt8(this.mouseMoveDeceleratedSpeed);
|
||||
buffer.writeUInt8(this.mouseMoveBaseSpeed);
|
||||
buffer.writeUInt8(this.mouseMoveAcceleratedSpeed);
|
||||
buffer.writeUInt8(this.mouseScrollInitialSpeed);
|
||||
buffer.writeUInt8(this.mouseScrollAcceleration);
|
||||
buffer.writeUInt8(this.mouseScrollDeceleratedSpeed);
|
||||
buffer.writeUInt8(this.mouseScrollBaseSpeed);
|
||||
buffer.writeUInt8(this.mouseScrollAcceleratedSpeed);
|
||||
buffer.writeArray(this.moduleConfigurations);
|
||||
buffer.writeArray(this.macros);
|
||||
buffer.writeArray(this.keymaps, (uhkBuffer: UhkBuffer, keymap: Keymap) => {
|
||||
@@ -87,7 +199,8 @@ export class UserConfiguration {
|
||||
}
|
||||
|
||||
toString(): string {
|
||||
return `<UserConfiguration dataModelVersion="${this.dataModelVersion}">`;
|
||||
return `<UserConfiguration dataModelVersion="${this.dataModelMajorVersion}.\
|
||||
${this.dataModelMinorVersion}.${this.dataModelPatchVersion}">`;
|
||||
}
|
||||
|
||||
getKeymap(keymapAbbreviation: string): Keymap {
|
||||
|
||||
@@ -82,7 +82,9 @@ export class KeymapEditComponent {
|
||||
site: 'https://ultimatehackingkeyboard.com',
|
||||
description: 'Ultimate Hacking Keyboard keymap',
|
||||
keyboardModel: 'UHK60',
|
||||
dataModelVersion: userConfiguration.dataModelVersion,
|
||||
dataModelMajorVersion: userConfiguration.dataModelMajorVersion,
|
||||
dataModelMinorVersion: userConfiguration.dataModelMinorVersion,
|
||||
dataModelPatchVersion: userConfiguration.dataModelPatchVersion,
|
||||
objectType: 'keymap',
|
||||
objectValue: keymap.toJsonObject()
|
||||
};
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
{
|
||||
"dataModelVersion": 4,
|
||||
"dataModelMajorVersion": 3,
|
||||
"dataModelMinorVersion": 0,
|
||||
"dataModelPatchVersion": 0,
|
||||
"deviceName": "My UHK",
|
||||
"doubleTapSwitchLayerTimeout": 300,
|
||||
"keyBacklightBrightness": 255,
|
||||
"mouseMoveInitialSpeed": 5,
|
||||
"mouseMoveAcceleration": 35,
|
||||
"mouseMoveDeceleratedSpeed": 10,
|
||||
"mouseMoveBaseSpeed": 40,
|
||||
"mouseMoveAcceleratedSpeed": 80,
|
||||
"mouseScrollInitialSpeed": 20,
|
||||
"mouseScrollAcceleration": 20,
|
||||
"mouseScrollDeceleratedSpeed": 20,
|
||||
"mouseScrollBaseSpeed": 20,
|
||||
"mouseScrollAcceleratedSpeed": 50,
|
||||
"moduleConfigurations": [
|
||||
{
|
||||
"id": 1,
|
||||
@@ -7134,4 +7148,4 @@
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
import { Actions, Effect, toPayload } from '@ngrx/effects';
|
||||
import { Actions, Effect } from '@ngrx/effects';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { defer } from 'rxjs/observable/defer';
|
||||
import { Action, Store } from '@ngrx/store';
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
|
||||
import {
|
||||
ActionTypes,
|
||||
LoadConfigFromDeviceReplyAction,
|
||||
LoadUserConfigSuccessAction,
|
||||
RenameUserConfigurationAction,
|
||||
SaveUserConfigSuccessAction
|
||||
@@ -33,7 +34,12 @@ import { DataStorageRepositoryService } from '../../services/datastorage-reposit
|
||||
import { DefaultUserConfigurationService } from '../../services/default-user-configuration.service';
|
||||
import { AppState, getPrevUserConfiguration, getUserConfiguration } from '../index';
|
||||
import { KeymapAction, KeymapActions, MacroAction, MacroActions } from '../actions';
|
||||
import { ShowNotificationAction, DismissUndoNotificationAction, LoadHardwareConfigurationSuccessAction } from '../actions/app';
|
||||
import {
|
||||
DismissUndoNotificationAction,
|
||||
LoadHardwareConfigurationSuccessAction,
|
||||
ShowNotificationAction,
|
||||
UndoLastAction
|
||||
} from '../actions/app';
|
||||
import { ShowSaveToKeyboardButtonAction } from '../actions/device';
|
||||
import { DeviceRendererService } from '../../services/device-renderer.service';
|
||||
import { UndoUserConfigData } from '../../models/undo-user-config-data';
|
||||
@@ -46,7 +52,7 @@ export class UserConfigEffects {
|
||||
const userConfig = new UserConfiguration();
|
||||
userConfig.fromBinary(UhkBuffer.fromArray(data));
|
||||
|
||||
if (userConfig.dataModelVersion > 0) {
|
||||
if (userConfig.dataModelMajorVersion > 0) {
|
||||
return userConfig;
|
||||
}
|
||||
|
||||
@@ -111,8 +117,8 @@ export class UserConfigEffects {
|
||||
});
|
||||
|
||||
@Effect() undoUserConfig$: Observable<Action> = this.actions$
|
||||
.ofType(KeymapActions.UNDO_LAST_ACTION)
|
||||
.map(toPayload)
|
||||
.ofType<UndoLastAction>(KeymapActions.UNDO_LAST_ACTION)
|
||||
.map(action => action.payload)
|
||||
.mergeMap((payload: UndoUserConfigData) => {
|
||||
const config = new UserConfiguration().fromJsonObject(payload.config);
|
||||
this.dataStorageRepository.saveConfig(config);
|
||||
@@ -125,8 +131,8 @@ export class UserConfigEffects {
|
||||
.do(() => this.deviceRendererService.loadConfigurationFromKeyboard());
|
||||
|
||||
@Effect() loadConfigFromDeviceReply$ = this.actions$
|
||||
.ofType(ActionTypes.LOAD_CONFIG_FROM_DEVICE_REPLY)
|
||||
.map(toPayload)
|
||||
.ofType<LoadConfigFromDeviceReplyAction>(ActionTypes.LOAD_CONFIG_FROM_DEVICE_REPLY)
|
||||
.map(action => action.payload)
|
||||
.mergeMap((data: ConfigurationReply): any => {
|
||||
if (!data.success) {
|
||||
return [new ShowNotificationAction({
|
||||
@@ -135,22 +141,37 @@ export class UserConfigEffects {
|
||||
})];
|
||||
}
|
||||
|
||||
const result = [];
|
||||
try {
|
||||
const userConfig = UserConfigEffects.getUserConfigFromDeviceResponse(data.userConfiguration);
|
||||
const hardwareConfig = UserConfigEffects.getHardwareConfigFromDeviceResponse(data.hardwareConfiguration);
|
||||
this.router.navigate(['/']);
|
||||
result.push(new LoadUserConfigSuccessAction(userConfig));
|
||||
|
||||
return [
|
||||
new LoadUserConfigSuccessAction(userConfig),
|
||||
new LoadHardwareConfigurationSuccessAction(hardwareConfig)
|
||||
];
|
||||
} catch (err) {
|
||||
this.logService.error('Eeprom parse error:', err);
|
||||
return [new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: err
|
||||
})];
|
||||
this.logService.error('Eeprom user-config parse error:', err);
|
||||
result.push(
|
||||
new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: err
|
||||
}));
|
||||
|
||||
result.push(new LoadUserConfigSuccessAction(this.getUserConfiguration()));
|
||||
}
|
||||
|
||||
try {
|
||||
const hardwareConfig = UserConfigEffects.getHardwareConfigFromDeviceResponse(data.hardwareConfiguration);
|
||||
result.push(new LoadHardwareConfigurationSuccessAction(hardwareConfig));
|
||||
} catch (err) {
|
||||
this.logService.error('Eeprom hardware-config parse error:', err);
|
||||
result.push(
|
||||
new ShowNotificationAction({
|
||||
type: NotificationType.Error,
|
||||
message: err
|
||||
}));
|
||||
}
|
||||
|
||||
this.router.navigate(['/']);
|
||||
|
||||
return result;
|
||||
});
|
||||
|
||||
@Effect({dispatch: false}) saveUserConfigInJsonFile$ = this.actions$
|
||||
@@ -186,7 +207,8 @@ export class UserConfigEffects {
|
||||
let config: UserConfiguration;
|
||||
|
||||
if (configJsonObject) {
|
||||
if (configJsonObject.dataModelVersion === this.defaultUserConfigurationService.getDefault().dataModelVersion) {
|
||||
if (configJsonObject.dataModelMajorVersion ===
|
||||
this.defaultUserConfigurationService.getDefault().dataModelMajorVersion) {
|
||||
config = new UserConfiguration().fromJsonObject(configJsonObject);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,6 +6,10 @@ function getUint32(buffer, offset) {
|
||||
return (buffer[offset]) + (buffer[offset+1] << 8) + (buffer[offset+2] << 16) + (buffer[offset+3] << 24);
|
||||
}
|
||||
|
||||
function getUint16(buffer, offset) {
|
||||
return (buffer[offset]) + (buffer[offset+1] << 8);
|
||||
}
|
||||
|
||||
function getDebugInfo() {
|
||||
const payload = new Buffer([uhk.usbCommands.getDebugInfo]);
|
||||
console.log('Sending ', uhk.bufferToString(payload));
|
||||
|
||||
Reference in New Issue
Block a user