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 appNameFromTable.sort((a, b) => { 388 return a.string_value!.localeCompare(b.string_value!); 389 }); 390 if (appNameFromTable.length > 0 && SpHiSysEnergyChart.app_name === '') { 391 SpHiSysEnergyChart.app_name = appNameFromTable[0].string_value; 392 } 393 this.energyTraceRow = TraceRow.skeleton<BaseStruct>(); 394 this.energyTraceRow.addRowSettingPop(); 395 this.energyTraceRow.rowSetting = 'enable'; 396 this.energyTraceRow.rowSettingPopoverDirection = 'bottomLeft'; 397 let nameList: Array<TreeItemData> = []; 398 for (let index = 0; index < appNameFromTable.length; index++) { 399 let appName = appNameFromTable[index].string_value; 400 nameList.push({ 401 key: `${appName}`, 402 title: `${appName}`, 403 checked: index === 0, 404 }); 405 } 406 this.energyTraceRow.rowSettingList = nameList; 407 this.energyTraceRow.onRowSettingChangeHandler = (value): void => { 408 SpHiSysEnergyChart.app_name = value[0]; 409 this.trace.refreshCanvas(false); 410 }; 411 this.energyTraceRow.rowId = 'energy'; 412 this.energyTraceRow.rowType = TraceRow.ROW_TYPE_ENERGY; 413 this.energyTraceRow.rowParentId = ''; 414 this.energyTraceRow.folder = true; 415 this.energyTraceRow.addTemplateTypes('EnergyEvent'); 416 this.energyTraceRow.name = 'Energy'; 417 this.energyTraceRow.style.height = '40px'; 418 } 419 420 private initAnomalyChartRow(): TraceRow<EnergyAnomalyStruct> { 421 let anomalyTraceRow = TraceRow.skeleton<EnergyAnomalyStruct>(); 422 anomalyTraceRow.rowParentId = 'energy'; 423 anomalyTraceRow.rowHidden = true; 424 anomalyTraceRow.rowId = 'energy-anomaly'; 425 anomalyTraceRow.rowType = TraceRow.ROW_TYPE_ANOMALY_ENERGY; 426 anomalyTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 427 anomalyTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 428 anomalyTraceRow.setAttribute('height', '55px'); 429 let element = anomalyTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 430 element!.style.height = '55px'; 431 anomalyTraceRow.style.width = '100%'; 432 anomalyTraceRow.setAttribute('children', ''); 433 anomalyTraceRow.name = 'Anomaly Event'; 434 anomalyTraceRow.focusHandler = (): void => { 435 this.trace?.displayTip( 436 anomalyTraceRow, 437 EnergyAnomalyStruct.hoverEnergyAnomalyStruct, 438 `<span>AnomalyName:${EnergyAnomalyStruct.hoverEnergyAnomalyStruct?.eventName || ''}</span>` 439 ); 440 }; 441 return anomalyTraceRow; 442 } 443 444 private initSystemChartRow(): TraceRow<EnergySystemStruct> { 445 let systemTraceRow = TraceRow.skeleton<EnergySystemStruct>(); 446 systemTraceRow.rowParentId = 'energy'; 447 systemTraceRow.rowHidden = true; 448 systemTraceRow.rowId = 'energy-system'; 449 systemTraceRow.rowType = TraceRow.ROW_TYPE_SYSTEM_ENERGY; 450 systemTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 451 systemTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 452 systemTraceRow.setAttribute('height', '80px'); 453 let element = systemTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 454 element!.style.height = '90px'; 455 systemTraceRow.style.width = '100%'; 456 systemTraceRow.setAttribute('children', ''); 457 systemTraceRow.name = 'System Event'; 458 systemTraceRow.focusHandler = (): void => { 459 this.trace?.displayTip(systemTraceRow, EnergySystemStruct.hoverEnergySystemStruct, this.getSystemFocusHtml()); 460 }; 461 return systemTraceRow; 462 } 463 464 private getSystemFocusHtml(): string { 465 return ` 466<div style="width: 250px"> 467 <div style=" display: flex"> 468 <div style="width: 75%;text-align: left">WORKSCHEDULER: </div> 469 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.workScheduler! || 0}</div> 470 </div> 471 <div style="display: flex"> 472 <div style="width: 75%;text-align: left">POWER_RUNNINGLOCK: </div> 473 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.power! || 0}</div> 474 </div> 475 <div style="display: flex"> 476 <div style="width: 75%;text-align: left">LOCATION: </div> 477 <div style="width: 20%;text-align: left">${EnergySystemStruct.hoverEnergySystemStruct?.location! || 0}</div> 478 </div> 479</div>`; 480 } 481 482 private getPowerFocusHtml(): string { 483 return ` 484<div style="width: 120px"> 485 <div style="display: flex"> 486 <div style="width: 80%;text-align: left">CPU: </div> 487 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.cpu! || 0}</div> 488 </div> 489 <div style="display: flex"> 490 <div style="width: 80%;text-align: left">location: </div> 491 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.location! || 0}</div> 492 </div> 493 <div style="display: flex"> 494 <div style="width: 80%;text-align: left">GPU: </div> 495 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.gpu! || 0}</div> 496 </div> 497 <div style="display: flex"> 498 <div style="width: 80%;text-align: left">display: </div> 499 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.display! || 0}</div> 500 </div> 501 <div style="display: flex"> 502 <div style="width: 80%;text-align: left">camera: </div> 503 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.camera! || 0}</div> 504 </div> 505 <div style="display: flex"> 506 <div style="width: 80%;text-align: left">bluetooth: </div> 507 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.bluetooth! || 0}</div> 508 </div> 509 <div style="display: flex"> 510 <div style="width: 80%;text-align: left">flashlight: </div> 511 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.flashlight! || 0}</div> 512 </div> 513 <div style="display: flex"> 514 <div style="width: 80%;text-align: left">audio: </div> 515 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.audio! || 0}</div> 516 </div> 517 <div style="display: flex"> 518 <div style="width: 80%;text-align: left">wifiScan: </div> 519 <div style="width: 20%;text-align: left">${EnergyPowerStruct.hoverEnergyPowerStruct?.wifiscan! || 0}</div> 520 </div> 521</div>`; 522 } 523 524 private initPowerChartRow(): TraceRow<EnergyPowerStruct> { 525 let powerTraceRow = TraceRow.skeleton<EnergyPowerStruct>(); 526 powerTraceRow.rowParentId = 'energy'; 527 powerTraceRow.rowHidden = true; 528 powerTraceRow.rowId = 'energy-power'; 529 powerTraceRow.rowType = TraceRow.ROW_TYPE_POWER_ENERGY; 530 powerTraceRow.favoriteChangeHandler = this.trace.favoriteChangeHandler; 531 powerTraceRow.selectChangeHandler = this.trace.selectChangeHandler; 532 powerTraceRow.setAttribute('height', '200px'); 533 let element = powerTraceRow.shadowRoot?.querySelector('.root') as HTMLDivElement; 534 element!.style.height = '200px'; 535 powerTraceRow.style.width = '100%'; 536 powerTraceRow.setAttribute('children', ''); 537 powerTraceRow.name = 'Power'; 538 powerTraceRow.focusHandler = (): void => { 539 this.trace?.displayTip(powerTraceRow, EnergyPowerStruct.hoverEnergyPowerStruct, this.getPowerFocusHtml()); 540 }; 541 return powerTraceRow; 542 } 543 544 private getPowerData(items: unknown): EnergyPowerStruct[] { 545 let powerDataMap: unknown = {}; 546 let appNameList: string[] = []; //@ts-ignore 547 items.forEach( 548 (item: { id: number; startNS: number; eventName: string; appKey: string; eventValue: string }): void => { 549 //@ts-ignore 550 let dataItem = powerDataMap[item.startNS]; 551 if (dataItem === undefined) { 552 if (item.appKey === 'APPNAME') { 553 let appMap: unknown = {}; 554 let appNames = item.eventValue.split(','); 555 appNameList = appNames; 556 if (appNames.length > 0) { 557 for (let appNamesKey of appNames) { 558 //@ts-ignore 559 appMap[appNamesKey] = new EnergyPowerStruct(); //@ts-ignore 560 appMap[appNamesKey].name = appNamesKey; //@ts-ignore 561 appMap[appNamesKey].ts = item.startNS; 562 } //@ts-ignore 563 powerDataMap[item.startNS] = appMap; 564 } 565 } 566 } else { 567 if (item.appKey !== 'APPNAME') { 568 this.powerDataMap(item.eventName, item.eventValue, appNameList, dataItem); 569 } else { 570 //@ts-ignore 571 let dataMap = powerDataMap[item.startNS]; 572 let appNames = item.eventValue.split(','); 573 appNameList = appNames; 574 if (appNames.length > 0) { 575 for (let appNamesKey of appNames) { 576 dataMap[appNamesKey] = new EnergyPowerStruct(); 577 dataMap[appNamesKey].name = appNamesKey; 578 dataMap[appNamesKey].ts = item.startNS; 579 } 580 } 581 } 582 } 583 } 584 ); 585 //@ts-ignore 586 return Object.values(powerDataMap); 587 } 588 589 private powerDataMap(name: string, eventValue: string, appNameList: string[], dataItem: unknown): void { 590 let values = eventValue.split(','); 591 for (let i = 0; i < values.length; i++) { 592 let appName = appNameList[i]; //@ts-ignore 593 let obj = dataItem[appName]; 594 if (obj !== undefined) { 595 let eventName = name.split('_'); 596 let s = eventName[eventName.length - 1].toLocaleLowerCase(); 597 if (obj[s] === undefined) { 598 obj[s] = parseInt(values[i]); 599 } else { 600 obj[s] += parseInt(values[i]); 601 } 602 } 603 } 604 } 605 606 public static getBlueToothState(num: number | undefined): string { 607 switch (num) { 608 case 0: 609 return 'STATE_TURNING_ON'; 610 case 1: 611 return 'STATE_TURN_ON'; 612 case 2: 613 return 'STATE_TURNING_OFF'; 614 case NUM_3: 615 return 'STATE_TURN_OFF'; 616 default: 617 return 'UNKNOWN_STATE'; 618 } 619 } 620} 621