Commit 5ebd2b7a authored by martin hou's avatar martin hou

feat: 增加固件更新

parent be445719
......@@ -3,7 +3,7 @@ enum Level {
info = 'info',
error = 'error',
}
type Message = {
export type Message = {
level: Level;
module: string;
procedure: string;
......@@ -26,17 +26,17 @@ export const Logger = {
messages: [] as Message[],
consoleOutput: true,
printModule: [],
info(module: string, procedure: string, message: string) {
this._append(Level.info, module, procedure, message);
info: (module: string, procedure: string, message: string) => {
Logger._append(Level.info, module, procedure, message);
},
debug(module: string, procedure: string, message: string) {
this._append(Level.debug, module, procedure, message);
debug: (module: string, procedure: string, message: string) => {
Logger._append(Level.debug, module, procedure, message);
},
error(module: string, procedure: string, message: string) {
this._append(Level.error, module, procedure, message);
error: (module: string, procedure: string, message: string) => {
Logger._append(Level.error, module, procedure, message);
},
save(module: string, procedure: string, message: any) { },
_append(level: Level, module: string, procedure: string, message: string) {
save: (module: string, procedure: string, message: any) => { },
_append: (level: Level, module: string, procedure: string, message: string) => {
let log = {
level,
module,
......@@ -44,13 +44,13 @@ export const Logger = {
message: String(message),
time: new Date().getTime(),
};
this.messages.push(log);
if (this.consoleOutput) {
this._print(log);
Logger.messages.push(log);
if (Logger.consoleOutput) {
Logger._print(log);
}
if (this.messages.length > 15000) this.messages.shift();
if (Logger.messages.length > 15000) Logger.messages.shift();
},
_print(log: Message) {
_print: (log: Message) => {
let time = new Date(log.time);
console.info(
'[' +
......
......@@ -11,6 +11,11 @@ button {
outline: none;
border: 1px solid #ccc;
}
button:hover
{
cursor: pointer;
border: solid 1px #999;
}
.result-container {
display: flex;
flex-direction: row;
......
......@@ -3,7 +3,7 @@ import Jensen, { BluetoothDevice } from '..';
import './index.css';
import { Logger } from './Logger'
const jensen = new Jensen();
const jensen = new Jensen(Logger);
const firmwareVersions = [
{ model: 'hidock-p1:mini', version: '2.1.0', url: 'https://jensen.test.hidock.com/firmwares/mini-2.1.0.bin' },
{ model: 'hidock-p1', version: '1.2.18', url: 'https://jensen.test.hidock.com/firmwares/eason-1.2.18.bin' },
......@@ -16,6 +16,7 @@ export function Home() {
const [devices, setDevices] = useState<Jensen.BluetoothDevice[]>([]);
const [greeting, setGreeting] = useState<string|null>(null);
const [firmwares, setFirmwares] = useState<typeof firmwareVersions|null>(null);
const [logs, setLogs] = useState<string[]>([]);
useEffect(() => {
jensen.connect();
......@@ -35,10 +36,22 @@ export function Home() {
// console.log('onerror', e);
// alert('此设备已经在其它已打开的HiNotes网页上建立连接');
// };
setInterval(function()
{
Logger.info('hearbeat', 'tick', 'xxxx');
}, 5000);
// 创建日志更新定时器
const logUpdateInterval = setInterval(() => {
// 从Logger.messages中获取最后500条记录
let last = Logger.messages.slice(-500).reverse();
// 将last转换为字符串数组
let logStr: string[] = last.map((item) => {
return `[${item.level === 'error' ? 'x' : '*'}] [${new Date(item.time).toLocaleString()}] (${item.module} - ${item.procedure}) ${item.message}`;
});
setLogs(logStr);
}, 1000);
// 清理函数
return () => {
clearInterval(logUpdateInterval);
};
}, []);
const getFilePart = () => {
......@@ -121,7 +134,14 @@ export function Home() {
const getTime = async () => {
let time = await jensen.getTime();
alert(JSON.stringify(time));
// alert(JSON.stringify(time));
Logger.info('jensen', 'getTime', 'Time: ' + JSON.stringify(time));
}
const info = async () => {
let info = await jensen.getDeviceInfo();
// alert(JSON.stringify(info));
Logger.info('jensen', 'info', 'Device Info: ' + JSON.stringify(info));
}
const listFiles = async () => {
......@@ -134,7 +154,8 @@ export function Home() {
const getBluetoothStatus = async () => {
let info = await jensen.getBluetoothStatus();
alert(JSON.stringify(info));
// alert(JSON.stringify(info));
Logger.info('jensen', 'getBluetoothStatus', 'Bluetooth: ' + JSON.stringify(info));
}
const readFilePartial = async() => {
......@@ -197,7 +218,8 @@ export function Home() {
const batteryStatus = async () => {
let status = await jensen.getBatteryStatus(5);
alert(JSON.stringify(status));
// alert(JSON.stringify(status));
Logger.info('jensen', 'batteryStatus', 'Battery: ' + JSON.stringify(status));
}
let filename = '';
......@@ -306,16 +328,29 @@ export function Home() {
return;
}
Logger.info('jensen', 'ota', 'firmware download start');
let xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status != 200) return alert('Http Error: ' + this.status);
Logger.info('jensen', 'ota', 'firmware download complete');
Logger.info('jensen', 'ota', 'firmware upgrade start');
jensen.requestFirmwareUpgrade(versionNumber, this.response.byteLength, 30).then((info) => {
Logger.info('jensen', 'ota', 'firmware upgrade: ' + JSON.stringify(info));
if (info.result == 'accepted') {
// alert('firmware upgrade accepted');
Logger.info('jensen', 'ota', 'firmware transfer start');
jensen.uploadFirmware(Array.from(new Uint8Array(this.response)), 30).then((info) => {
alert(JSON.stringify(info));
if (info == null)
{
Logger.info('jensen', 'ota', 'firmware transfer timedout');
}
else
{
Logger.info('jensen', 'ota', 'firmware transfer complete: ' + JSON.stringify(info));
Logger.info('jensen', 'ota', 'please wait for the firmware upgrade to complete');
}
});
}
else
......@@ -331,6 +366,7 @@ export function Home() {
<>
<div style={{ display: 'flex', flexDirection: 'row', gap: '16px', padding: '16px', alignItems: 'center', flexWrap: 'wrap' }}>
<button onClick={connect}>Connect</button>
<button onClick={info}>Info</button>
<button onClick={getTime}>Get Time</button>
<button onClick={listFiles}>List Files</button>
<button onClick={transferFile}>Transfer</button>
......@@ -387,9 +423,7 @@ export function Home() {
</div>
</div>
<div className="log-container">
<textarea id="log" style={{ width: '100%', height: '100%' }}>{Logger.messages.slice(-400).reverse().map((item) => {
return `${item.level} ${item.module} ${item.procedure} ${item.message}\n`;
}).join('')}</textarea>
<textarea id="log" style={{ width: '100%', height: '100%' }} value={logs.join('\n')} readOnly />
</div>
</div>
</>
......
......@@ -7,16 +7,16 @@ const level = {
export const Logger = {
messages: [],
consoleOutput: true,
info(module, procedure, message) {
this._append(level.info, module, procedure, message);
info: (module, procedure, message) => {
Logger._append(level.info, module, procedure, message);
},
debug(module, procedure, message) {
this._append(level.debug, module, procedure, message);
debug: (module, procedure, message) => {
Logger._append(level.debug, module, procedure, message);
},
error(module, procedure, message) {
this._append(level.error, module, procedure, message);
error: (module, procedure, message) => {
Logger._append(level.error, module, procedure, message);
},
_append(level, module, procedure, message) {
_append: (level, module, procedure, message) => {
const log = {
level,
module,
......@@ -24,28 +24,28 @@ export const Logger = {
message: message,
time: new Date().getTime()
};
this.messages.push(log);
if (this.consoleOutput) this._print(log);
if (this.messages.length > 15000) this.messages.shift();
Logger.messages.push(log);
if (Logger.consoleOutput) Logger._print(log);
if (Logger.messages.length > 15000) Logger.messages.shift();
},
_print(log) {
_print: (log) => {
let time = new Date(log.time);
console.info(`[${log.level === 'error' ? 'x' : '*'}][${time.toLocaleString()}](${log.module} - ${log.procedure}) ${log.message}`);
},
filter(module, procedure) {
return this.messages.filter((i) => i.module === module && i.procedure === procedure);
filter: (module, procedure) => {
return Logger.messages.filter((i) => i.module === module && i.procedure === procedure);
},
enableConsoleOutput() {
this.consoleOutput = true;
enableConsoleOutput: () => {
Logger.consoleOutput = true;
},
disableConsoleOutput() {
this.consoleOutput = false;
disableConsoleOutput: () => {
Logger.consoleOutput = false;
},
peek(rows) {
return this.messages.slice(-rows);
peek: (rows) => {
return Logger.messages.slice(-rows);
},
search(module, procedure, keyword) {
return this.messages.filter((i) => {
search: (module, procedure, keyword) => {
return Logger.messages.filter((i) => {
let r = i.module === module;
if (!r) return false;
if (procedure) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment