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