feat: show firmware version of the device/modules on firmware page (#589)

This commit is contained in:
Róbert Kiss
2018-03-23 07:10:02 +01:00
committed by László Monda
parent 2f00a5eaf4
commit b25bc9d81d
13 changed files with 143 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
import { ipcMain } from 'electron'; import { ipcMain } from 'electron';
import { ConfigurationReply, DeviceConnectionState, IpcEvents, IpcResponse, LogService } from 'uhk-common'; import { ConfigurationReply, DeviceConnectionState, HardwareModules, IpcEvents, IpcResponse, LogService } from 'uhk-common';
import { snooze, UhkHidDevice, UhkOperations } from 'uhk-usb'; import { snooze, UhkHidDevice, UhkOperations } from 'uhk-usb';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
@@ -73,10 +73,15 @@ export class DeviceService {
try { try {
await this.device.waitUntilKeyboardBusy(); await this.device.waitUntilKeyboardBusy();
const result = await this.operations.loadConfigurations(); const result = await this.operations.loadConfigurations();
const modules: HardwareModules = {
leftModuleInfo: await this.operations.getLeftModuleVersionInfo(),
rightModuleInfo: await this.operations.getRightModuleVersionInfo()
};
response = { response = {
success: true, success: true,
...result ...result,
modules
}; };
} catch (error) { } catch (error) {
response = { response = {

View File

@@ -1,6 +1,9 @@
import { HardwareModules } from './hardware-modules';
export interface ConfigurationReply { export interface ConfigurationReply {
success: boolean; success: boolean;
userConfiguration?: string; userConfiguration?: string;
hardwareConfiguration?: string; hardwareConfiguration?: string;
modules?: HardwareModules;
error?: string; error?: string;
} }

View File

@@ -0,0 +1,4 @@
export interface HardwareModuleInfo {
firmwareVersion?: string;
moduleProtocolVersion?: string;
}

View File

@@ -0,0 +1,6 @@
import { HardwareModuleInfo } from './hardware-module-info';
export interface HardwareModules {
leftModuleInfo?: HardwareModuleInfo;
rightModuleInfo?: HardwareModuleInfo;
}

View File

@@ -5,3 +5,5 @@ export * from './app-start-info';
export * from './configuration-reply'; export * from './configuration-reply';
export * from './version-information'; export * from './version-information';
export * from './device-connection-state'; export * from './device-connection-state';
export * from './hardware-modules';
export * from './hardware-module-info';

View File

@@ -22,7 +22,7 @@ export enum UsbCommand {
GetDebugBuffer = 0x0b, GetDebugBuffer = 0x0b,
GetAdcValue = 0x0c, GetAdcValue = 0x0c,
SetLedPwmBrightness = 0x0d, SetLedPwmBrightness = 0x0d,
GetModuleProperties = 0x0e GetModuleProperty = 0x0e
} }
export enum EepromOperation { export enum EepromOperation {
@@ -81,3 +81,7 @@ export enum KbootCommands {
ping = 1, ping = 1,
reset = 2 reset = 2
} }
export enum ModulePropertyId {
protocolVersions = 0
}

View File

@@ -1,5 +1,12 @@
import { LogService } from 'uhk-common'; import { HardwareModuleInfo, LogService, UhkBuffer } from 'uhk-common';
import { EnumerationModes, EnumerationNameToProductId, KbootCommands, ModuleSlotToI2cAddress, ModuleSlotToId } from './constants'; import {
EnumerationModes,
EnumerationNameToProductId,
KbootCommands,
ModulePropertyId,
ModuleSlotToI2cAddress,
ModuleSlotToId
} from './constants';
import * as path from 'path'; import * as path from 'path';
import * as fs from 'fs'; import * as fs from 'fs';
import { UhkBlhost } from './uhk-blhost'; import { UhkBlhost } from './uhk-blhost';
@@ -193,6 +200,50 @@ export class UhkOperations {
return false; return false;
} }
public async getLeftModuleVersionInfo(): Promise<HardwareModuleInfo> {
try {
this.logService.debug('[DeviceOperation] USB[T]: Read left module version information');
const command = new Buffer([
UsbCommand.GetModuleProperty,
ModuleSlotToId.leftHalf,
ModulePropertyId.protocolVersions
]);
const buffer = await this.device.write(command);
const uhkBuffer = UhkBuffer.fromArray(convertBufferToIntArray(buffer));
// skip the first 2 byte
uhkBuffer.readUInt16();
return {
moduleProtocolVersion: `${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}`,
firmwareVersion: `${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}`
};
}
catch (error) {
this.logService.error('[DeviceOperation] Could not read left module version information', error);
}
return {
moduleProtocolVersion: '',
firmwareVersion: ''
};
}
public async getRightModuleVersionInfo(): Promise<HardwareModuleInfo> {
this.logService.debug('[DeviceOperation] USB[T]: Read right module version information');
const command = new Buffer([UsbCommand.GetProperty, DevicePropertyIds.ProtocolVersions]);
const buffer = await this.device.write(command);
const uhkBuffer = UhkBuffer.fromArray(convertBufferToIntArray(buffer));
// skip the first byte
uhkBuffer.readUInt8();
return {
firmwareVersion: `${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}.${uhkBuffer.readUInt16()}`
};
}
/** /**
* IpcMain handler. Send the UserConfiguration to the UHK Device and send a response with the result. * IpcMain handler. Send the UserConfiguration to the UHK Device and send a response with the result.
* @param {string} json - UserConfiguration in JSON format * @param {string} json - UserConfiguration in JSON format

View File

@@ -7,12 +7,19 @@
<span>Firmware</span> <span>Firmware</span>
</h1> </h1>
<p><i> <p>
Firmware {{ hardwareModules.leftModuleInfo.firmwareVersion }} is running on the left keyboard half.<br>
Firmware {{ hardwareModules.rightModuleInfo.firmwareVersion }} is running on the right keyboard half.
</p>
<p>
<i>
Please note that the firmware update process may sometimes fail. If if fails then Please note that the firmware update process may sometimes fail. If if fails then
simply retry until it succeeds. If the left half becomes unresponsive after a failed simply retry until it succeeds. If the left half becomes unresponsive after a failed
update then retry and follow the instructions displayed during the update to fix it. update then retry and follow the instructions displayed during the update to fix it.
We'll make the firmware update process more robust. We'll make the firmware update process more robust.
</i></p> </i>
</p>
<p> <p>
<button class="btn btn-primary" <button class="btn btn-primary"

View File

@@ -2,9 +2,16 @@ import { Component, ElementRef, OnDestroy, ViewChild } from '@angular/core';
import { Store } from '@ngrx/store'; import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable'; import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription'; import { Subscription } from 'rxjs/Subscription';
import { VersionInformation } from 'uhk-common'; import { HardwareModules, VersionInformation } from 'uhk-common';
import { AppState, firmwareOkButtonDisabled, flashFirmwareButtonDisbabled, getAgentVersionInfo, xtermLog } from '../../../store'; import {
AppState,
firmwareOkButtonDisabled,
flashFirmwareButtonDisbabled,
getAgentVersionInfo,
getHardwareModules,
xtermLog
} from '../../../store';
import { UpdateFirmwareAction, UpdateFirmwareOkButtonAction, UpdateFirmwareWithAction } from '../../../store/actions/device'; import { UpdateFirmwareAction, UpdateFirmwareOkButtonAction, UpdateFirmwareWithAction } from '../../../store/actions/device';
import { XtermLog } from '../../../models/xterm-log'; import { XtermLog } from '../../../models/xterm-log';
@@ -22,6 +29,8 @@ export class DeviceFirmwareComponent implements OnDestroy {
xtermLogSubscription: Subscription; xtermLogSubscription: Subscription;
getAgentVersionInfo$: Observable<VersionInformation>; getAgentVersionInfo$: Observable<VersionInformation>;
firmwareOkButtonDisabled$: Observable<boolean>; firmwareOkButtonDisabled$: Observable<boolean>;
hardwareModulesSubscription: Subscription;
hardwareModules: HardwareModules;
@ViewChild('scrollMe') divElement: ElementRef; @ViewChild('scrollMe') divElement: ElementRef;
@@ -37,10 +46,14 @@ export class DeviceFirmwareComponent implements OnDestroy {
}); });
this.getAgentVersionInfo$ = store.select(getAgentVersionInfo); this.getAgentVersionInfo$ = store.select(getAgentVersionInfo);
this.firmwareOkButtonDisabled$ = store.select(firmwareOkButtonDisabled); this.firmwareOkButtonDisabled$ = store.select(firmwareOkButtonDisabled);
this.hardwareModulesSubscription = store.select(getHardwareModules).subscribe(data => {
this.hardwareModules = data;
});
} }
ngOnDestroy(): void { ngOnDestroy(): void {
this.xtermLogSubscription.unsubscribe(); this.xtermLogSubscription.unsubscribe();
this.hardwareModulesSubscription.unsubscribe();
} }
onUpdateFirmware(): void { onUpdateFirmware(): void {

View File

@@ -1,5 +1,6 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { DeviceConnectionState, IpcResponse, type } from 'uhk-common'; import { DeviceConnectionState, IpcResponse, type } from 'uhk-common';
import { HardwareModules } from '../../../../../uhk-common/src/models';
const PREFIX = '[device] '; const PREFIX = '[device] ';
@@ -22,7 +23,8 @@ export const ActionTypes = {
UPDATE_FIRMWARE_REPLY: type(PREFIX + 'update firmware reply'), UPDATE_FIRMWARE_REPLY: type(PREFIX + 'update firmware reply'),
UPDATE_FIRMWARE_SUCCESS: type(PREFIX + 'update firmware success'), UPDATE_FIRMWARE_SUCCESS: type(PREFIX + 'update firmware success'),
UPDATE_FIRMWARE_FAILED: type(PREFIX + 'update firmware failed'), UPDATE_FIRMWARE_FAILED: type(PREFIX + 'update firmware failed'),
UPDATE_FIRMWARE_OK_BUTTON: type(PREFIX + 'update firmware ok button click') UPDATE_FIRMWARE_OK_BUTTON: type(PREFIX + 'update firmware ok button click'),
MODULES_INFO_LOADED: type(PREFIX + 'module info loaded')
}; };
export class SetPrivilegeOnLinuxAction implements Action { export class SetPrivilegeOnLinuxAction implements Action {
@@ -114,6 +116,13 @@ export class ResetMouseSpeedSettingsAction implements Action {
type = ActionTypes.RESET_MOUSE_SPEED_SETTINGS; type = ActionTypes.RESET_MOUSE_SPEED_SETTINGS;
} }
export class HardwareModulesLoadedAction implements Action {
type = ActionTypes.MODULES_INFO_LOADED;
constructor(public payload: HardwareModules) {
}
}
export type Actions export type Actions
= SetPrivilegeOnLinuxAction = SetPrivilegeOnLinuxAction
| SetPrivilegeOnLinuxReplyAction | SetPrivilegeOnLinuxReplyAction
@@ -132,4 +141,5 @@ export type Actions
| UpdateFirmwareSuccessAction | UpdateFirmwareSuccessAction
| UpdateFirmwareFailedAction | UpdateFirmwareFailedAction
| UpdateFirmwareOkButtonAction | UpdateFirmwareOkButtonAction
| HardwareModulesLoadedAction
; ;

View File

@@ -43,7 +43,7 @@ import {
ShowNotificationAction, ShowNotificationAction,
UndoLastAction UndoLastAction
} from '../actions/app'; } from '../actions/app';
import { ShowSaveToKeyboardButtonAction } from '../actions/device'; import { HardwareModulesLoadedAction, ShowSaveToKeyboardButtonAction } from '../actions/device';
import { DeviceRendererService } from '../../services/device-renderer.service'; import { DeviceRendererService } from '../../services/device-renderer.service';
import { UndoUserConfigData } from '../../models/undo-user-config-data'; import { UndoUserConfigData } from '../../models/undo-user-config-data';
import { UploadFileData } from '../../models/upload-file-data'; import { UploadFileData } from '../../models/upload-file-data';
@@ -173,6 +173,8 @@ export class UserConfigEffects {
})); }));
} }
result.push(new HardwareModulesLoadedAction(data.modules));
this.router.navigate(['/']); this.router.navigate(['/']);
return result; return result;

View File

@@ -77,3 +77,4 @@ export const xtermLog = createSelector(deviceState, fromDevice.xtermLog);
export const firmwareOkButtonDisabled = createSelector(deviceState, fromDevice.firmwareOkButtonDisabled); export const firmwareOkButtonDisabled = createSelector(deviceState, fromDevice.firmwareOkButtonDisabled);
// tslint:disable-next-line: max-line-length // tslint:disable-next-line: max-line-length
export const flashFirmwareButtonDisbabled = createSelector(runningInElectron, deviceState, (electron, state: fromDevice.State) => !electron || state.updatingFirmware); export const flashFirmwareButtonDisbabled = createSelector(runningInElectron, deviceState, (electron, state: fromDevice.State) => !electron || state.updatingFirmware);
export const getHardwareModules = createSelector(deviceState, fromDevice.getHardwareModules);

View File

@@ -1,8 +1,10 @@
import { Action } from '@ngrx/store'; import { Action } from '@ngrx/store';
import { HardwareModules } from 'uhk-common';
import { import {
ActionTypes, ActionTypes,
ConnectionStateChangedAction, ConnectionStateChangedAction,
HardwareModulesLoadedAction,
SaveConfigurationAction, SaveConfigurationAction,
UpdateFirmwareFailedAction UpdateFirmwareFailedAction
} from '../actions/device'; } from '../actions/device';
@@ -16,6 +18,7 @@ export interface State {
saveToKeyboard: ProgressButtonState; saveToKeyboard: ProgressButtonState;
updatingFirmware: boolean; updatingFirmware: boolean;
firmwareUpdateFinished: boolean; firmwareUpdateFinished: boolean;
modules: HardwareModules;
log: Array<XtermLog>; log: Array<XtermLog>;
} }
@@ -25,6 +28,15 @@ export const initialState: State = {
saveToKeyboard: initProgressButtonState, saveToKeyboard: initProgressButtonState,
updatingFirmware: false, updatingFirmware: false,
firmwareUpdateFinished: false, firmwareUpdateFinished: false,
modules: {
leftModuleInfo: {
firmwareVersion: '',
moduleProtocolVersion: ''
},
rightModuleInfo: {
firmwareVersion: ''
}
},
log: [{message: '', cssClass: XtermCssClass.standard}] log: [{message: '', cssClass: XtermCssClass.standard}]
}; };
@@ -148,6 +160,13 @@ export function reducer(state = initialState, action: Action) {
log: [...state.log, logEntry] log: [...state.log, logEntry]
}; };
} }
case ActionTypes.MODULES_INFO_LOADED:
return {
...state,
modules: (action as HardwareModulesLoadedAction).payload
};
default: default:
return state; return state;
} }
@@ -159,3 +178,4 @@ export const hasDevicePermission = (state: State) => state.hasPermission;
export const getSaveToKeyboardState = (state: State) => state.saveToKeyboard; export const getSaveToKeyboardState = (state: State) => state.saveToKeyboard;
export const xtermLog = (state: State) => state.log; export const xtermLog = (state: State) => state.log;
export const firmwareOkButtonDisabled = (state: State) => !state.firmwareUpdateFinished; export const firmwareOkButtonDisabled = (state: State) => !state.firmwareUpdateFinished;
export const getHardwareModules = (state: State) => state.modules;