• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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