• 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 { SystemDetailsEnergy } from '../../../../bean/EnergyStruct';
17import { BaseElement, element } from '../../../../../base-ui/BaseElement';
18import { LitTable } from '../../../../../base-ui/table/lit-table';
19import { SelectionParam } from '../../../../bean/BoxSelection';
20import { SpHiSysEnergyChart } from '../../../chart/SpHiSysEnergyChart';
21import { resizeObserver } from '../SheetUtils';
22import { type LitSlicerTrack } from '../../../../../base-ui/slicer/lit-slicer';
23import {
24  querySysLocationDetailsData,
25  querySysLockDetailsData,
26  querySystemWorkData
27} from "../../../../database/sql/SqlLite.sql";
28
29@element('tabpane-system-details')
30export class TabPaneSystemDetails extends BaseElement {
31  private tblSystemDetails: LitTable | null | undefined;
32  private detailsTbl: LitTable | null | undefined;
33  private eventSource: Array<any> = [];
34  private detailsSource: Array<any> = [];
35  private boxDetails: HTMLDivElement | null | undefined;
36  private slicerTrack: LitSlicerTrack | null | undefined;
37
38  set data(valSystemDetails: SelectionParam | any) {
39    this.slicerTrack!.style.visibility = 'hidden';
40    this.queryDataByDB(valSystemDetails);
41  }
42
43  connectedCallback() {
44    super.connectedCallback();
45    resizeObserver(this.parentElement!, this.tblSystemDetails!);
46  }
47
48  initElements(): void {
49    this.boxDetails = this.shadowRoot?.querySelector<HTMLDivElement>('.box-details');
50    this.tblSystemDetails = this.shadowRoot?.querySelector<LitTable>('#tb-system-data');
51    this.detailsTbl = this.shadowRoot?.querySelector<LitTable>('#tb-system-details-data');
52    this.slicerTrack = this.shadowRoot?.querySelector<LitSlicerTrack>('lit-slicer-track');
53    this.tblSystemDetails!.addEventListener('row-click', (e) => {
54      this.detailsSource = [];
55      // @ts-ignore
56      let data = e.detail.data as SystemDetailsEnergy;
57      this.convertData(data);
58    });
59  }
60
61  convertData(data: SystemDetailsEnergy) {
62    if (data.eventName === 'Event Name') {
63      this.slicerTrack!.style.visibility = 'hidden';
64      this.detailsTbl!.dataSource = [];
65      this.boxDetails!.style.width = '100%';
66    } else {
67      this.slicerTrack!.style.visibility = 'visible';
68      this.detailsSource.push({
69        key: 'EVENT_NAME : ',
70        value: data.eventName,
71      });
72      this.detailsSource.push({ key: 'PID : ', value: data.pid });
73      this.detailsSource.push({ key: 'UID : ', value: data.uid });
74      if (data.eventName === 'GNSS_STATE') {
75        this.detailsSource.push({ key: 'STATE : ', value: data.state });
76      } else if (data.eventName === 'POWER_RUNNINGLOCK') {
77        this.detailsSource.push({ key: 'TYPE : ', value: data.type });
78        this.detailsSource.push({ key: 'STATE : ', value: data.state });
79        this.detailsSource.push({
80          key: 'LOG_LEVEL : ',
81          value: data.log_level,
82        });
83        this.detailsSource.push({ key: 'NAME : ', value: data.name });
84        this.detailsSource.push({
85          key: 'MESSAGE : ',
86          value: data.message,
87        });
88        this.detailsSource.push({ key: 'TAG : ', value: data.tag });
89      } else {
90        this.detailsSource.push({ key: 'TYPE : ', value: data.type });
91        this.detailsSource.push({
92          key: 'WORK_ID : ',
93          value: data.workId,
94        });
95        this.detailsSource.push({ key: 'NAME : ', value: data.name });
96        this.detailsSource.push({
97          key: 'INTERVAL : ',
98          value: data.interval,
99        });
100      }
101      this.detailsTbl!.dataSource = this.detailsSource;
102      this.boxDetails!.style.width = '65%';
103    }
104   this.detailsTblStyle();
105  }
106
107  detailsTblStyle(){
108    this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.tr').forEach((tr) => {
109      tr.style.gridTemplateColumns = '120px 1fr';
110    });
111    this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td) => {
112      let item = td.getAttribute('title');
113      td.style.fontSize = '14px';
114      td.style.fontWeight = '400';
115      if (item != null && item.indexOf(':') > -1) {
116        td.style.opacity = '0.9';
117        td.style.lineHeight = '16px';
118      } else {
119        td.style.opacity = '0.6';
120        td.style.lineHeight = '20px';
121      }
122    });
123  }
124
125  queryDataByDB(val: SelectionParam | any) {
126    Promise.all([
127      querySystemWorkData(val.rightNs),
128      querySysLockDetailsData(val.rightNs, 'POWER_RUNNINGLOCK'),
129      querySysLocationDetailsData(val.rightNs, 'GNSS_STATE'),
130    ]).then((result) => {
131      let itemList: Array<any> = [];
132      let systemWorkData = this.getSystemWorkData(result[0], val.leftNs, val.rightNs);
133      if (systemWorkData.length > 0) {
134        systemWorkData.forEach((item) => {
135          itemList.push(item);
136        });
137      }
138      let systemLockData = this.getSystemLockData(result[1], val.leftNs);
139      if (systemLockData.length > 0) {
140        systemLockData.forEach((item) => {
141          itemList.push(item);
142        });
143      }
144      let systemLocationData = this.getSystemLocationData(result[2], val.leftNs);
145      if (systemLocationData.length > 0) {
146        systemLocationData.forEach((item) => {
147          itemList.push(item);
148        });
149      }
150      itemList.sort((leftData: any, rightData: any) => {
151        return leftData.ts - rightData.ts;
152      });
153      this.eventSource = [];
154      this.eventSource.push({
155        ts: 'Time',
156        interval: 0,
157        level: 0,
158        name: '',
159        state: 0,
160        tag: '',
161        type: '',
162        uid: 0,
163        pid: 0,
164        workId: '',
165        message: '',
166        log_level: '',
167        eventName: 'Event Name',
168      });
169      this.tblSystemDetails!.recycleDataSource = this.eventSource.concat(itemList);
170      this.detailsTbl!.dataSource = [];
171      this.boxDetails!.style.width = '100%';
172      this.tblSystemDetailsStyle();
173    });
174  }
175
176  tblSystemDetailsStyle(){
177    this.tblSystemDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td) => {
178      td.style.fontSize = '14px';
179      if (td.getAttribute('title') === 'Event Name' || td.getAttribute('title') === 'Time') {
180        td.style.fontWeight = '700';
181      } else {
182        td.style.fontWeight = '400';
183        td.style.opacity = '0.9';
184        td.style.lineHeight = '16px';
185      }
186    });
187  }
188
189  private getSystemWorkData(data: Array<any>, leftNs: number, rightNs: number) {
190    let values = this.getConvertData(data);
191    let lifeCycleData: Array<any> = [];
192    let watchIndex: Array<string> = [];
193    for (let index = 0; index < values.length; index++) {
194      let filterData: any = values[index];
195      if (filterData.name == SpHiSysEnergyChart.app_name) {
196        if (filterData.eventName.indexOf('WORK_ADD') > -1) {
197          watchIndex.push(filterData.workId);
198          let number = watchIndex.indexOf(filterData.workId);
199          lifeCycleData[number] = {
200            startData: {},
201            endData: {},
202            rangeData: [],
203          };
204          lifeCycleData[number].startData = filterData;
205          let virtualEndData = JSON.parse(JSON.stringify(filterData));
206          virtualEndData.ts = rightNs;
207          virtualEndData.eventName = 'WORK_REMOVE';
208          lifeCycleData[number].endData = virtualEndData;
209        } else if (filterData.eventName.indexOf('WORK_REMOVE') > -1) {
210          let number = watchIndex.indexOf(filterData.workId);
211          if (number > -1) {
212            lifeCycleData[number].endData = filterData;
213            watchIndex[number] = number + filterData.ts;
214          }
215        } else {
216          lifeCycleData = this.getSysDataExtend(rightNs, watchIndex, filterData, lifeCycleData)
217        }
218      }
219    }
220    let resultData: Array<any> = [];
221    lifeCycleData.forEach((life: any) => {
222      if (life.endData.ts >= leftNs) {
223        let midData = life.rangeData;
224        midData.forEach((rang: any, index: number) => {
225          if (rang.eventName.indexOf('WORK_STOP') > -1 && rang.ts >= leftNs) {
226            resultData.push(life.startData);
227            if (index - 1 >= 0 && midData[index - 1].eventName.indexOf('WORK_START') > -1) {
228              resultData.push(midData[index - 1]);
229            }
230            resultData.push(rang);
231          }
232        });
233      }
234    });
235    return resultData;
236  }
237
238  getSysDataExtend(
239    rightNs: number,
240    watchIndex: Array<string>,
241    filterData: any,
242    lifeCycleData: any[]
243  ): any[]{
244    let number = watchIndex.indexOf(filterData.workId);
245    if (number > -1) {
246      lifeCycleData[number].rangeData.push(filterData);
247      let virtualEndData = JSON.parse(JSON.stringify(filterData));
248      virtualEndData.ts = rightNs;
249      virtualEndData.eventName = 'WORK_REMOVE';
250      lifeCycleData[number].endData = virtualEndData;
251    } else {
252      if (filterData.eventName.indexOf('WORK_START') > -1) {
253        lifeCycleData.push({
254          startData: {},
255          endData: {},
256          rangeData: [],
257        });
258        watchIndex.push(filterData.workId);
259        number = watchIndex.indexOf(filterData.workId);
260        let virtualData = JSON.parse(JSON.stringify(filterData));
261        if (filterData.ts > 0) {
262          virtualData.ts = 0;
263        } else {
264          virtualData.ts = filterData.ts - 1;
265        }
266        virtualData.eventName = 'WORK_ADD';
267        lifeCycleData[number].startData = virtualData;
268        lifeCycleData[number].rangeData.push(filterData);
269        let virtualEndData = JSON.parse(JSON.stringify(filterData));
270        virtualEndData.ts = rightNs;
271        virtualEndData.eventName = 'WORK_REMOVE';
272        lifeCycleData[number].endData = virtualEndData;
273      }
274    }
275    return lifeCycleData;
276  }
277
278  private getSystemLocationData(data: Array<any>, leftNs: number) {
279    let values = this.getConvertData(data);
280    let fillMap: Map<any, any> = new Map<any, any>();
281    let leftMap: Map<any, any> = new Map<any, any>();
282    let watchIndex: Array<string> = [];
283    for (let index = 0; index < values.length; index++) {
284      let filterData: any = values[index];
285      if (filterData.state.indexOf('start') > -1) {
286        leftMap.set(filterData.pid, filterData);
287        watchIndex.push(filterData.pid);
288      } else {
289        let i = watchIndex.indexOf(filterData.pid);
290        if (i > -1) {
291          fillMap.set(leftMap.get(filterData.pid), filterData);
292          delete watchIndex[i];
293          leftMap.delete(filterData.pid);
294        }
295      }
296    }
297
298    let locationData: Array<any> = [];
299    fillMap.forEach((value, key) => {
300      if (value.ts >= leftNs) {
301        locationData.push(key);
302        locationData.push(value);
303      }
304    });
305    leftMap.forEach((value, key) => {
306      locationData.push(value);
307    });
308    return locationData;
309  }
310
311  private getSystemLockData(data: Array<any>, leftNs: number) {
312    let values = this.getConvertData(data);
313    let watchIndex: Array<string> = [];
314    let fillMap: Map<any, any> = new Map<any, any>();
315    let leftMap: Map<any, any> = new Map<any, any>();
316    for (let index = 0; index < values.length; index++) {
317      let filterData: any = values[index];
318      if (filterData.tag.indexOf('ADD') > -1) {
319        leftMap.set(filterData.message, filterData);
320        watchIndex.push(filterData.message);
321      } else {
322        let i = watchIndex.indexOf(filterData.message);
323        if (i > -1) {
324          fillMap.set(leftMap.get(filterData.message), filterData);
325          delete watchIndex[i];
326          leftMap.delete(filterData.message);
327        }
328      }
329    }
330    let lockData: Array<any> = [];
331    fillMap.forEach((value, key) => {
332      if (value.ts >= leftNs) {
333        lockData.push(key);
334        lockData.push(value);
335      }
336    });
337    leftMap.forEach((value, key) => {
338      lockData.push(value);
339    });
340    return lockData;
341  }
342
343  private getConvertData(data: Array<any>) {
344    let convertItem: any = {};
345    data.forEach((item: any) => {
346      if (convertItem[item.ts + item.eventName] == undefined) {
347        convertItem[item.ts + item.eventName] = {};
348        convertItem[item.ts + item.eventName]['ts'] = item.ts;
349        convertItem[item.ts + item.eventName]['eventName'] = item.eventName;
350        convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue;
351      } else {
352        convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue;
353      }
354    });
355    // @ts-ignore
356    return Object.values(convertItem);
357  }
358
359  initHtml(): string {
360    return `
361        <style>
362        :host{
363            display: flex;
364            flex-direction: column;
365            padding: 10px 10px 0 10px;
366        }
367        .sys-detail-progress{
368            bottom: 33px;
369            position: absolute;
370            height: 1px;
371            left: 0;
372            right: 0;
373        }
374        </style>
375        <div class="sys-detail-content" style="display: flex;flex-direction: column">
376            <div style="display: flex;flex-direction: row">
377                <lit-slicer style="width:100%">
378                    <div class="box-details" style="width: 100%">
379                        <lit-table id="tb-system-data" style="height: auto">
380                            <lit-table-column class="sys-detail-column" width="300px" title="" data-index="eventName" key="eventName"  align="flex-start" order>
381                            </lit-table-column>
382                            <lit-table-column class="sys-detail-column" width="300px" title="" data-index="ts" key="ts"  align="flex-start" order>
383                            </lit-table-column>
384                        </lit-table>
385                    </div>
386                    <lit-slicer-track ></lit-slicer-track>
387                    <lit-table id="tb-system-details-data" no-head hideDownload style="height: auto;border-left: 1px solid var(--dark-border1,#e2e2e2)">
388                        <lit-table-column class="sys-detail-column" width="100px" title="" data-index="key" key="key"  align="flex-start" >
389                        </lit-table-column>
390                        <lit-table-column class="sys-detail-column" width="1fr" title="" data-index="value" key="value"  align="flex-start">
391                        </lit-table-column>
392                    </lit-table>
393                </lit-slicer>
394            </div>
395            <lit-progress-bar class="progress sys-detail-progress"></lit-progress-bar>
396        </div>
397        `;
398  }
399}
400