1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { SpSystemTrace } from '../SpSystemTrace'; 17import { info } from '../../../log/Log'; 18import { TraceRow } from '../trace/base/TraceRow'; 19import { BaseStruct } from '../../bean/BaseStruct'; 20import { EnergyAnomalyRender, EnergyAnomalyStruct } from '../../database/ui-worker/ProcedureWorkerEnergyAnomaly'; 21import { EnergySystemStruct, EnergySystemRender } from '../../database/ui-worker/ProcedureWorkerEnergySystem'; 22import { EnergyPowerStruct, EnergyPowerRender } from '../../database/ui-worker/ProcedureWorkerEnergyPower'; 23import { EnergyStateStruct, EnergyStateRender } from '../../database/ui-worker/ProcedureWorkerEnergyState'; 24import { renders } from '../../database/ui-worker/ProcedureWorker'; 25import { EmptyRender } from '../../database/ui-worker/cpu/ProcedureWorkerCPU'; 26import { TreeItemData } from '../../../base-ui/tree/LitTree'; 27import { 28 energySysEventSender, 29 hiSysEnergyAnomalyDataSender, 30 hiSysEnergyPowerSender, 31 hiSysEnergyStateSender, 32} from '../../database/data-trafic/EnergySysEventSender'; 33import { 34 queryAnomalyData, 35 queryConfigEnergyAppName, 36 queryEnergyAppName, 37 queryEnergyEventExits, 38 queryMaxStateValue, 39 queryStateInitValue, 40} from '../../database/sql/SqlLite.sql'; 41import { queryPowerData } from '../../database/sql/ProcessThread.sql'; 42import { NUM_200, NUM_3 } from '../../bean/NumBean'; 43 44export class SpHiSysEnergyChart { 45 static app_name: string | null; 46 trace: SpSystemTrace; 47 private energyTraceRow: TraceRow<BaseStruct> | undefined; 48 private timer: number | undefined; 49 private eventNameMap: Map<number, string> = new Map(); 50 private appKeyMap: Map<number, string> = new Map(); 51 private eventValueMap: Map<number, string> = new Map(); 52 private powerEventNameMap: Map<number, string> = new Map(); 53 private powerAppKeyNameMap: Map<number, string> = new Map(); 54 private powerEventValueMap: Map<number, string> = new Map(); 55 private stateName: Array<string> = [ 56 'BRIGHTNESS_NIT', 57 'SIGNAL_LEVEL', 58 'WIFI_EVENT_RECEIVED', 59 'AUDIO_STREAM_CHANGE', 60 'AUDIO_VOLUME_CHANGE', 61 'WIFI_STATE', 62 'BLUETOOTH_BR_SWITCH_STATE', 63 'BR_SWITCH_STATE', 64 'LOCATION_SWITCH_STATE', 65 'SENSOR_STATE', 66 ]; 67 private initValueList: Array<string> = [ 68 'brightness', 69 'nocolumn', 70 'nocolumn', 71 'nocolumn', 72 'nocolumn', 73 'wifi', 74 'bt_state', 75 'bt_state', 76 'location', 77 'nocolumn', 78 ]; 79 private stateList: Array<string> = [ 80 'Brightness Nit', 81 'Signal Level', 82 'Wifi Event Received', 83 'Audio Stream Change', 84 'Audio Volume Change', 85 'Wifi State', 86 'Bluetooth Br Switch State', 87 'Br Switch State', 88 'Location Switch State', 89 'Sensor State', 90 ]; 91 92 constructor(trace: SpSystemTrace) { 93 this.trace = trace; 94 } 95 96 async init(): Promise<void> { 97 let result = await queryEnergyEventExits(); 98 if (result.length <= 0) { 99 return; 100 } 101 let anomalyData = await queryAnomalyData(); 102 let powerData = await queryPowerData(); 103 for (let index = 0; index < anomalyData.length; index++) { 104 let item = anomalyData[index]; 105 this.eventNameMap.set(item.id!, item.eventName ?? ''); 106 this.appKeyMap.set(item.id!, item.appKey ?? ''); 107 this.eventValueMap.set(item.id!, item.eventValue ?? ''); 108 } 109 for (let index = 0; index < powerData.length; index++) { 110 let item = powerData[index]; 111 this.powerEventNameMap.set(item.id, item.eventName ?? ''); 112 this.powerAppKeyNameMap.set(item.id, item.appKey ?? ''); 113 this.powerEventValueMap.set(item.id, item.eventValue ?? ''); 114 } 115 await this.initEnergyRow(); 116 this.initAnomaly(); 117 this.initSystem(); 118 this.initPower(); 119 await this.initState(); 120 } 121 122 private async initEnergyRow(): Promise<void> { 123 await this.initEnergyChartRow(); 124 this.energyTraceRow!.favoriteChangeHandler = this.trace.favoriteChangeHandler; 125 this.energyTraceRow!.selectChangeHandler = this.trace.selectChangeHandler; 126 this.energyTraceRow!.supplier = (): Promise<BaseStruct[]> => 127 new Promise<Array<BaseStruct>>((resolve) => resolve([])); 128 this.energyTraceRow!.onThreadHandler = (useCache: boolean): void => { 129 this.energyTraceRow?.canvasSave(this.trace.canvasPanelCtx!); 130 if (this.energyTraceRow!.expansion) { 131 // @ts-ignore 132 this.trace.canvasPanelCtx?.clearRect(0, 0, this.energyTraceRow!.frame.width, this.energyTraceRow!.frame.height); 133 } else { 134 (renders.empty as EmptyRender).renderMainThread( 135 { 136 context: this.trace.canvasPanelCtx, 137 useCache: useCache, 138 type: '', 139 }, 140 this.energyTraceRow! 141 ); 142 } 143 this.energyTraceRow?.canvasRestore(this.trace.canvasPanelCtx!, this.trace); 144 }; 145 this.energyTraceRow!.addEventListener('expansion-change', () => { 146 TraceRow.range!.refresh = true; 147 this.trace.refreshCanvas(false); 148 if (this.timer) { 149 clearTimeout(this.timer); 150 } 151 this.timer = window.setTimeout((): void => { 152 TraceRow.range!.refresh = false; 153 }, NUM_200); 154 }); 155 this.trace.rowsEL?.appendChild(this.energyTraceRow!); 156 } 157 158 private initAnomaly = (): void => { 159 let time = new Date().getTime(); 160 let anomalyTraceRow = this.initAnomalyChartRow(); 161 anomalyTraceRow.supplierFrame = async (): Promise<EnergyAnomalyStruct[]> => { 162 return hiSysEnergyAnomalyDataSender(anomalyTraceRow).then((res: EnergyAnomalyStruct[]) => { 163 for (let index = 0; index < res.length; index++) { 164 let item = res[index]; 165 item.eventName = this.eventNameMap.get(res[index].id!); 166 item.appKey = this.appKeyMap.get(res[index].id!); 167 item.eventValue = this.eventValueMap.get(res[index].id!); 168 } 169 return res; 170 }); 171 }; 172 anomalyTraceRow.findHoverStruct = (): void => { 173 EnergyAnomalyStruct.hoverEnergyAnomalyStruct = anomalyTraceRow.getHoverStruct(); 174 }; 175 anomalyTraceRow.onThreadHandler = (useCache: boolean): void => { 176 let context: CanvasRenderingContext2D; 177 if (anomalyTraceRow.currentContext) { 178 context = anomalyTraceRow.currentContext; 179 } else { 180 context = anomalyTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 181 } 182 anomalyTraceRow.canvasSave(context); 183 (renders.energyAnomaly as EnergyAnomalyRender).renderMainThread( 184 { 185 context: context, 186 useCache: useCache, 187 type: 'energyAnomaly', 188 appName: SpHiSysEnergyChart.app_name || '', 189 canvasWidth: this.trace.canvasPanel?.width || 0, 190 }, 191 anomalyTraceRow 192 ); 193 anomalyTraceRow.canvasRestore(context, this.trace); 194 }; 195 this.energyTraceRow?.addChildTraceRow(anomalyTraceRow); 196 let durTime = new Date().getTime() - time; 197 info('The time to load the anomaly is: ', durTime); 198 }; 199 200 private initSystem = (): void => { 201 let time = new Date().getTime(); 202 let systemTraceRow = this.initSystemChartRow(); 203 systemTraceRow.supplierFrame = async (): Promise<EnergySystemStruct[]> => { 204 return energySysEventSender(systemTraceRow).then((res: EnergySystemStruct[]) => { 205 return res; 206 }); 207 }; 208 systemTraceRow.findHoverStruct = (): void => { 209 EnergySystemStruct.hoverEnergySystemStruct = systemTraceRow.getHoverStruct(); 210 }; 211 systemTraceRow.onThreadHandler = (useCache: boolean): void => { 212 let context: CanvasRenderingContext2D; 213 if (systemTraceRow.currentContext) { 214 context = systemTraceRow.currentContext; 215 } else { 216 context = systemTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 217 } 218 systemTraceRow.canvasSave(context); 219 (renders.energySystem as EnergySystemRender).renderMainThread( 220 { 221 context: context, 222 useCache: useCache, 223 type: 'energySystem', 224 }, 225 systemTraceRow 226 ); 227 systemTraceRow.canvasRestore(context, this.trace); 228 }; 229 this.energyTraceRow?.addChildTraceRow(systemTraceRow); 230 let durTime = new Date().getTime() - time; 231 info('The time to load the Ability Memory is: ', durTime); 232 }; 233 234 private initPower = (): void => { 235 let time = new Date().getTime(); 236 let powerTraceRow = this.initPowerChartRow(); 237 powerTraceRow.supplierFrame = async (): Promise<EnergyPowerStruct[]> => { 238 return hiSysEnergyPowerSender(powerTraceRow).then((res) => { 239 for (let index = 0; index < res.length; index++) { 240 let item = res[index]; 241 item.eventName = this.powerEventNameMap.get(res[index].id!); 242 item.appKey = this.powerAppKeyNameMap.get(res[index].id!); 243 item.eventValue = this.powerEventValueMap.get(res[index].id!); 244 } 245 return this.getPowerData(res); 246 }); 247 }; 248 powerTraceRow.onThreadHandler = (useCache: boolean): void => { 249 let context: CanvasRenderingContext2D; 250 if (powerTraceRow.currentContext) { 251 context = powerTraceRow.currentContext; 252 } else { 253 context = powerTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 254 } 255 powerTraceRow.canvasSave(context); 256 (renders.energyPower as EnergyPowerRender).renderMainThread( 257 { 258 context: context, 259 useCache: useCache, 260 type: 'energyPower', 261 appName: SpHiSysEnergyChart.app_name || '', 262 }, 263 powerTraceRow! 264 ); 265 powerTraceRow!.canvasRestore(context, this.trace); 266 }; 267 this.energyTraceRow?.addChildTraceRow(powerTraceRow); 268 let durTime = new Date().getTime() - time; 269 info('The time to load the energy power is: ', durTime); 270 }; 271 272 private initState = async (): Promise<void> => { 273 let time = new Date().getTime(); 274 for (let index = 0; index < this.stateList.length; index++) { 275 let stateResult = await queryStateInitValue(this.stateName[index], this.initValueList[index]); 276 let maxStateData = await queryMaxStateValue(this.stateName[index]); 277 if (!maxStateData[0]) { 278 continue; 279 } 280 let maxStateTotal = this.getMaxStateTotal(maxStateData); 281 let stateTraceRow = this.initStatChartRow(index); 282 stateTraceRow.supplierFrame = async (): Promise<EnergyStateStruct[]> => { 283 const res = await hiSysEnergyStateSender(this.stateName, index, stateTraceRow); 284 let stateInitValue = this.initValueList[index] === 'nocolumn' ? [] : stateResult; 285 for (let i = 0; i < res.length; i++) { 286 let item = res[i]; 287 item.type = this.stateName[index]; 288 } 289 return stateInitValue.concat(res); 290 }; 291 stateTraceRow.onThreadHandler = (useCache: boolean): void => { 292 let context: CanvasRenderingContext2D; 293 if (stateTraceRow.currentContext) { 294 context = stateTraceRow.currentContext; 295 } else { 296 context = stateTraceRow.collect ? this.trace.canvasFavoritePanelCtx! : this.trace.canvasPanelCtx!; 297 } 298 stateTraceRow.canvasSave(context); 299 (renders.energyState as EnergyStateRender).renderMainThread( 300 { 301 context: context, 302 useCache: useCache, 303 type: `energyState${index}`, 304 maxState: maxStateData[0].maxValue, 305 maxStateName: maxStateData[0].type.toLocaleLowerCase().endsWith('br_switch_state') 306 ? '-1' 307 : maxStateTotal.toString(), 308 }, 309 stateTraceRow 310 ); 311 stateTraceRow.canvasRestore(context, this.trace); 312 }; 313 this.energyTraceRow?.addChildTraceRow(stateTraceRow); 314 let durTime = new Date().getTime() - time; 315 info('The time to load the Ability Memory is: ', durTime); 316 } 317 }; 318 319 private getMaxStateTotal( 320 maxStateData: Array<{ 321 type: string; 322 maxValue: number; 323 }> 324 ): string { 325 let maxStateTotal = maxStateData[0].maxValue.toString(); 326 let statType = maxStateData[0].type.toLocaleLowerCase(); 327 if (statType.includes('state') && !statType.endsWith('br_switch_state')) { 328 if (maxStateData[0].maxValue === 0) { 329 maxStateTotal = 'enable'; 330 } else { 331 maxStateTotal = 'disable'; 332 } 333 } else if (statType.includes('sensor')) { 334 if (statType.includes('enable')) { 335 maxStateTotal = 'enable'; 336 } else { 337 maxStateTotal = 'disable'; 338 } 339 } 340 return maxStateTotal; 341 } 342 343 private initStatChartRow(index: number): TraceRow<EnergyStateStruct> { 344 let stateTraceRow = TraceRow.skeleton<EnergyStateStruct>(); 345 stateTraceRow.rowParentId = 'energy'; 346 stateTraceRow.rowHidden = true; 347 stateTraceRow.rowId = `energy-state-${this.stateList[index]}`; 348 stateTraceRow.rowType = TraceRow.ROW_TYPE_STATE_ENERGY; 349 stateTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 350 stateTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 351 stateTraceRow.style.height = '40px'; 352 stateTraceRow.style.width = '100%'; 353 stateTraceRow.setAttribute('children', ''); 354 stateTraceRow.name = `${this.stateList[index]}`; 355 stateTraceRow.focusHandler = (): void => { 356 let tip; 357 if (EnergyStateStruct.hoverEnergyStateStruct?.type!.toLocaleLowerCase().includes('state')) { 358 tip = `<span>Switch Status: ${ 359 EnergyStateStruct.hoverEnergyStateStruct?.value === 1 ? 'disable' : 'enable' 360 }</span>`; 361 if (EnergyStateStruct.hoverEnergyStateStruct?.type!.toLocaleLowerCase().endsWith('br_switch_state')) { 362 tip = `<span>${SpHiSysEnergyChart.getBlueToothState(EnergyStateStruct.hoverEnergyStateStruct?.value)}</span>`; 363 } 364 } else { 365 tip = `<span>value: ${EnergyStateStruct.hoverEnergyStateStruct?.value?.toFixed(2) || 0}</span>`; 366 } 367 this.trace?.displayTip(stateTraceRow, EnergyStateStruct.hoverEnergyStateStruct, tip); 368 }; 369 return stateTraceRow; 370 } 371 372 private async initEnergyChartRow(): Promise<void> { 373 SpHiSysEnergyChart.app_name = ''; 374 let appNameFromTable = await queryEnergyAppName(); 375 let configAppName = await queryConfigEnergyAppName(); 376 if (configAppName.length > 0 && appNameFromTable.length > 0) { 377 let name = configAppName[0].process_name; 378 if (name !== null) { 379 let filterList = appNameFromTable.filter((appNameFromTableElement) => { 380 return appNameFromTableElement.string_value?.trim() === name; 381 }); 382 if (filterList.length > 0) { 383 SpHiSysEnergyChart.app_name = name; 384 } 385 } 386 } 387 if (appNameFromTable.length > 0 && SpHiSysEnergyChart.app_name === '') { 388 SpHiSysEnergyChart.app_name = appNameFromTable[0].string_value; 389 } 390 this.energyTraceRow = TraceRow.skeleton<BaseStruct>(); 391 this.energyTraceRow.addRowSettingPop(); 392 this.energyTraceRow.rowSetting = 'enable'; 393 this.energyTraceRow.rowSettingPopoverDirection = 'bottomLeft'; 394 let nameList: Array<TreeItemData> = []; 395 for (let index = 0; index < appNameFromTable.length; index++) { 396 let appName = appNameFromTable[index].string_value; 397 nameList.push({ 398 key: `${appName}`, 399 title: `${appName}`, 400 checked: index === 0, 401 }); 402 } 403 this.energyTraceRow.rowSettingList = nameList; 404 this.energyTraceRow.onRowSettingChangeHandler = (value): void => { 405 SpHiSysEnergyChart.app_name = value[0]; 406 this.trace.refreshCanvas(false); 407 }; 408 this.energyTraceRow.rowId = 'energy'; 409 this.energyTraceRow.rowType = TraceRow.ROW_TYPE_ENERGY; 410 this.energyTraceRow.rowParentId = ''; 411 this.energyTraceRow.folder = true; 412 this.energyTraceRow.addTemplateTypes('EnergyEvent'); 413 this.energyTraceRow.name = 'Energy'; 414 this.energyTraceRow.style.height = '40px'; 415 } 416 417 private initAnomalyChartRow(): TraceRow<EnergyAnomalyStruct> { 418 let anomalyTraceRow = TraceRow.skeleton<EnergyAnomalyStruct>(); 419 anomalyTraceRow.rowParentId = 'energy'; 420 anomalyTraceRow.rowHidden = true; 421 anomalyTraceRow.rowId = 'energy-anomaly'; 422 anomalyTraceRow.rowType = TraceRow.ROW_TYPE_ANOMALY_ENERGY; 423 anomalyTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 424 anomalyTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 425 anomalyTraceRow.setAttribute('height', '55px'); 426 let element = anomalyTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 427 element!.style.height = '55px'; 428 anomalyTraceRow.style.width = '100%'; 429 anomalyTraceRow.setAttribute('children', ''); 430 anomalyTraceRow.name = 'Anomaly Event'; 431 anomalyTraceRow.focusHandler = (): void => { 432 this.trace?.displayTip( 433 anomalyTraceRow, 434 EnergyAnomalyStruct.hoverEnergyAnomalyStruct, 435 `<span>AnomalyName:${EnergyAnomalyStruct.hoverEnergyAnomalyStruct?.eventName || ''}</span>` 436 ); 437 }; 438 return anomalyTraceRow; 439 } 440 441 private initSystemChartRow(): TraceRow<EnergySystemStruct> { 442 let systemTraceRow = TraceRow.skeleton<EnergySystemStruct>(); 443 systemTraceRow.rowParentId = 'energy'; 444 systemTraceRow.rowHidden = true; 445 systemTraceRow.rowId = 'energy-system'; 446 systemTraceRow.rowType = TraceRow.ROW_TYPE_SYSTEM_ENERGY; 447 systemTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 448 systemTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 449 systemTraceRow.setAttribute('height', '80px'); 450 let element = systemTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 451 element!.style.height = '90px'; 452 systemTraceRow.style.width = '100%'; 453 systemTraceRow.setAttribute('children', ''); 454 systemTraceRow.name = 'System Event'; 455 systemTraceRow.focusHandler = (): void => { 456 this.trace?.displayTip(systemTraceRow, EnergySystemStruct.hoverEnergySystemStruct, this.getSystemFocusHtml()); 457 }; 458 return systemTraceRow; 459 } 460 461 private getSystemFocusHtml(): string { 462 return ` 463<div style="width: 250px"> 464 <div style=" display: flex"> 465 <div style="width: 75%;text-align: left">WORKSCHEDULER: </div> 466 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.workScheduler! || 0}</div> 467 </div> 468 <div style="display: flex"> 469 <div style="width: 75%;text-align: left">POWER_RUNNINGLOCK: </div> 470 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.power! || 0}</div> 471 </div> 472 <div style="display: flex"> 473 <div style="width: 75%;text-align: left">LOCATION: </div> 474 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.location! || 0}</div> 475 </div> 476</div>`; 477 } 478 479 private getPowerFocusHtml(): string { 480 return ` 481<div style="width: 120px"> 482 <div style="display: flex"> 483 <div style="width: 80%;text-align: left">CPU: </div> 484 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.cpu! || 0}</div> 485 </div> 486 <div style="display: flex"> 487 <div style="width: 80%;text-align: left">location: </div> 488 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.location! || 0}</div> 489 </div> 490 <div style="display: flex"> 491 <div style="width: 80%;text-align: left">GPU: </div> 492 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.gpu! || 0}</div> 493 </div> 494 <div style="display: flex"> 495 <div style="width: 80%;text-align: left">display: </div> 496 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.display! || 0}</div> 497 </div> 498 <div style="display: flex"> 499 <div style="width: 80%;text-align: left">camera: </div> 500 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.camera! || 0}</div> 501 </div> 502 <div style="display: flex"> 503 <div style="width: 80%;text-align: left">bluetooth: </div> 504 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.bluetooth! || 0}</div> 505 </div> 506 <div style="display: flex"> 507 <div style="width: 80%;text-align: left">flashlight: </div> 508 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.flashlight! || 0}</div> 509 </div> 510 <div style="display: flex"> 511 <div style="width: 80%;text-align: left">audio: </div> 512 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.audio! || 0}</div> 513 </div> 514 <div style="display: flex"> 515 <div style="width: 80%;text-align: left">wifiScan: </div> 516 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.wifiscan! || 0}</div> 517 </div> 518</div>`; 519 } 520 521 private initPowerChartRow(): TraceRow<EnergyPowerStruct> { 522 let powerTraceRow = TraceRow.skeleton<EnergyPowerStruct>(); 523 powerTraceRow.rowParentId = 'energy'; 524 powerTraceRow.rowHidden = true; 525 powerTraceRow.rowId = 'energy-power'; 526 powerTraceRow.rowType = TraceRow.ROW_TYPE_POWER_ENERGY; 527 powerTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 528 powerTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 529 powerTraceRow.setAttribute('height', '200px'); 530 let element = powerTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 531 element!.style.height = '200px'; 532 powerTraceRow.style.width = '100%'; 533 powerTraceRow.setAttribute('children', ''); 534 powerTraceRow.name = 'Power'; 535 powerTraceRow.focusHandler = (): void => { 536 this.trace?.displayTip(powerTraceRow, EnergyPowerStruct.hoverEnergyPowerStruct, this.getPowerFocusHtml()); 537 }; 538 return powerTraceRow; 539 } 540 541 private getPowerData(items: unknown): EnergyPowerStruct[] { 542 let powerDataMap: unknown = {}; 543 let appNameList: string[] = []; //@ts-ignore 544 items.forEach( 545 (item: { id: number; startNS: number; eventName: string; appKey: string; eventValue: string }): void => { 546 //@ts-ignore 547 let dataItem = powerDataMap[item.startNS]; 548 if (dataItem === undefined) { 549 if (item.appKey === 'APPNAME') { 550 let appMap: unknown = {}; 551 let appNames = item.eventValue.split(','); 552 appNameList = appNames; 553 if (appNames.length > 0) { 554 for (let appNamesKey of appNames) { 555 //@ts-ignore 556 appMap[appNamesKey] = new EnergyPowerStruct(); //@ts-ignore 557 appMap[appNamesKey].name = appNamesKey; //@ts-ignore 558 appMap[appNamesKey].ts = item.startNS; 559 } //@ts-ignore 560 powerDataMap[item.startNS] = appMap; 561 } 562 } 563 } else { 564 if (item.appKey !== 'APPNAME') { 565 this.powerDataMap(item.eventName, item.eventValue, appNameList, dataItem); 566 } else { 567 //@ts-ignore 568 let dataMap = powerDataMap[item.startNS]; 569 let appNames = item.eventValue.split(','); 570 appNameList = appNames; 571 if (appNames.length > 0) { 572 for (let appNamesKey of appNames) { 573 dataMap[appNamesKey] = new EnergyPowerStruct(); 574 dataMap[appNamesKey].name = appNamesKey; 575 dataMap[appNamesKey].ts = item.startNS; 576 } 577 } 578 } 579 } 580 } 581 ); 582 //@ts-ignore 583 return Object.values(powerDataMap); 584 } 585 586 private powerDataMap(name: string, eventValue: string, appNameList: string[], dataItem: unknown): void { 587 let values = eventValue.split(','); 588 for (let i = 0; i < values.length; i++) { 589 let appName = appNameList[i]; //@ts-ignore 590 let obj = dataItem[appName]; 591 if (obj !== undefined) { 592 let eventName = name.split('_'); 593 let s = eventName[eventName.length - 1].toLocaleLowerCase(); 594 if (obj[s] === undefined) { 595 obj[s] = parseInt(values[i]); 596 } else { 597 obj[s] += parseInt(values[i]); 598 } 599 } 600 } 601 } 602 603 public static getBlueToothState(num: number | undefined): string { 604 switch (num) { 605 case 0: 606 return 'STATE_TURNING_ON'; 607 case 1: 608 return 'STATE_TURN_ON'; 609 case 2: 610 return 'STATE_TURNING_OFF'; 611 case NUM_3: 612 return 'STATE_TURN_OFF'; 613 default: 614 return 'UNKNOWN_STATE'; 615 } 616 } 617} 618