• 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<unknown> = [];
34  private detailsSource: Array<unknown> = [];
35  private boxDetails: HTMLDivElement | null | undefined;
36  private slicerTrack: LitSlicerTrack | null | undefined;
37
38  set data(valSystemDetails: SelectionParam | unknown) {
39    this.slicerTrack!.style.visibility = 'hidden';
40    this.queryDataByDB(valSystemDetails);
41  }
42
43  connectedCallback(): void {
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): void => {
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): void {
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(): void {
108    this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.tr').forEach((tr): void => {
109      tr.style.gridTemplateColumns = '120px 1fr';
110    });
111    this.detailsTbl!.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => {
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 | unknown): void {
126    Promise.all([
127      // @ts-ignore
128      querySystemWorkData(val.rightNs),
129      // @ts-ignore
130      querySysLockDetailsData(val.rightNs, 'POWER_RUNNINGLOCK'),
131      // @ts-ignore
132      querySysLocationDetailsData(val.rightNs, 'GNSS_STATE'),
133    ]).then((result): void => {
134      let itemList: Array<unknown> = [];
135      // @ts-ignore
136      let systemWorkData = this.getSystemWorkData(result[0], val.leftNs, val.rightNs);
137      if (systemWorkData.length > 0) {
138        systemWorkData.forEach((item) => {
139          itemList.push(item);
140        });
141      }
142      // @ts-ignore
143      let systemLockData = this.getSystemLockData(result[1], val.leftNs);
144      if (systemLockData.length > 0) {
145        systemLockData.forEach((item): void => {
146          itemList.push(item);
147        });
148      }
149      // @ts-ignore
150      let systemLocationData = this.getSystemLocationData(result[2], val.leftNs);
151      if (systemLocationData.length > 0) {
152        systemLocationData.forEach((item): void => {
153          itemList.push(item);
154        });
155      }
156      itemList.sort((leftData: unknown, rightData: unknown) => {
157        // @ts-ignore
158        return leftData.ts - rightData.ts;
159      });
160      this.eventSource = [];
161      this.eventSource.push({
162        ts: 'Time',
163        interval: 0,
164        level: 0,
165        name: '',
166        state: 0,
167        tag: '',
168        type: '',
169        uid: 0,
170        pid: 0,
171        workId: '',
172        message: '',
173        log_level: '',
174        eventName: 'Event Name',
175      });
176      this.tblSystemDetails!.recycleDataSource = this.eventSource.concat(itemList);
177      this.detailsTbl!.dataSource = [];
178      this.boxDetails!.style.width = '100%';
179      this.tblSystemDetailsStyle();
180    });
181  }
182
183  tblSystemDetailsStyle(): void {
184    this.tblSystemDetails?.shadowRoot?.querySelectorAll<HTMLDivElement>('.td').forEach((td): void => {
185      td.style.fontSize = '14px';
186      if (td.getAttribute('title') === 'Event Name' || td.getAttribute('title') === 'Time') {
187        td.style.fontWeight = '700';
188      } else {
189        td.style.fontWeight = '400';
190        td.style.opacity = '0.9';
191        td.style.lineHeight = '16px';
192      }
193    });
194  }
195
196  private getSystemWorkData(data: Array<unknown>, leftNs: number, rightNs: number): unknown[] {
197    let values = this.getConvertData(data);
198    let lifeCycleData: Array<unknown> = [];
199    let watchIndex: Array<string> = [];
200    for (let index = 0; index < values.length; index++) {
201      let filterData: unknown = values[index];
202      // @ts-ignore
203      if (filterData.name === SpHiSysEnergyChart.app_name) {
204        // @ts-ignore
205        if (filterData.eventName.indexOf('WORK_ADD') > -1) {
206          // @ts-ignore
207          watchIndex.push(filterData.workId);
208          // @ts-ignore
209          let number = watchIndex.indexOf(filterData.workId);
210          lifeCycleData[number] = {
211            startData: {},
212            endData: {},
213            rangeData: [],
214          };
215          // @ts-ignore
216          lifeCycleData[number].startData = filterData;
217          let virtualEndData = JSON.parse(JSON.stringify(filterData));
218          virtualEndData.ts = rightNs;
219          virtualEndData.eventName = 'WORK_REMOVE';
220          // @ts-ignore
221          lifeCycleData[number].endData = virtualEndData;
222          // @ts-ignore
223        } else if (filterData.eventName.indexOf('WORK_REMOVE') > -1) {
224          // @ts-ignore
225          let number = watchIndex.indexOf(filterData.workId);
226          if (number > -1) {
227            // @ts-ignore
228            lifeCycleData[number].endData = filterData;
229            // @ts-ignore
230            watchIndex[number] = number + filterData.ts;
231          }
232        } else {
233          lifeCycleData = this.getSysDataExtend(rightNs, watchIndex, filterData, lifeCycleData);
234        }
235      }
236    }
237    let resultData: Array<unknown> = [];
238    lifeCycleData.forEach((life: unknown): void => {
239      // @ts-ignore
240      if (life.endData.ts >= leftNs) {
241        // @ts-ignore
242        let midData = life.rangeData;
243        midData.forEach((rang: unknown, index: number): void => {
244          // @ts-ignore
245          if (rang.eventName.indexOf('WORK_STOP') > -1 && rang.ts >= leftNs) {
246            // @ts-ignore
247            resultData.push(life.startData);
248            if (index - 1 >= 0 && midData[index - 1].eventName.indexOf('WORK_START') > -1) {
249              resultData.push(midData[index - 1]);
250            }
251            resultData.push(rang);
252          }
253        });
254      }
255    });
256    return resultData;
257  }
258
259  getSysDataExtend(
260    rightNs: number,
261    watchIndex: Array<string>,
262    filterData: unknown,
263    lifeCycleData: unknown[]
264  ): unknown[] {
265    // @ts-ignore
266    let number = watchIndex.indexOf(filterData.workId);
267    if (number > -1) {
268      // @ts-ignore
269      lifeCycleData[number].rangeData.push(filterData);
270      let virtualEndData = JSON.parse(JSON.stringify(filterData));
271      virtualEndData.ts = rightNs;
272      virtualEndData.eventName = 'WORK_REMOVE';
273      // @ts-ignore
274      lifeCycleData[number].endData = virtualEndData;
275    } else {
276      // @ts-ignore
277      if (filterData.eventName.indexOf('WORK_START') > -1) {
278        lifeCycleData.push({
279          startData: {},
280          endData: {},
281          rangeData: [],
282        });
283        // @ts-ignore
284        watchIndex.push(filterData.workId);
285        // @ts-ignore
286        number = watchIndex.indexOf(filterData.workId);
287        let virtualData = JSON.parse(JSON.stringify(filterData));
288        // @ts-ignore
289        if (filterData.ts > 0) {
290          virtualData.ts = 0;
291        } else {
292          // @ts-ignore
293          virtualData.ts = filterData.ts - 1;
294        }
295        virtualData.eventName = 'WORK_ADD';
296        // @ts-ignore
297        lifeCycleData[number].startData = virtualData;
298        // @ts-ignore
299        lifeCycleData[number].rangeData.push(filterData);
300        let virtualEndData = JSON.parse(JSON.stringify(filterData));
301        virtualEndData.ts = rightNs;
302        virtualEndData.eventName = 'WORK_REMOVE';
303        // @ts-ignore
304        lifeCycleData[number].endData = virtualEndData;
305      }
306    }
307    return lifeCycleData;
308  }
309
310  private getSystemLocationData(data: Array<unknown>, leftNs: number): unknown[] {
311    let values = this.getConvertData(data);
312    let fillMap: Map<unknown, unknown> = new Map<unknown, unknown>();
313    let leftMap: Map<unknown, unknown> = new Map<unknown, unknown>();
314    let watchIndex: Array<string> = [];
315    for (let index = 0; index < values.length; index++) {
316      let filterData: unknown = values[index];
317      // @ts-ignore
318      if (filterData.state.indexOf('start') > -1) {
319        // @ts-ignore
320        leftMap.set(filterData.pid, filterData);
321        // @ts-ignore
322        watchIndex.push(filterData.pid);
323      } else {
324        // @ts-ignore
325        let i = watchIndex.indexOf(filterData.pid);
326        if (i > -1) {
327          // @ts-ignore
328          fillMap.set(leftMap.get(filterData.pid), filterData);
329          // @ts-ignore
330          watchIndex.splice(i, 1, undefined);
331          // @ts-ignore
332          leftMap.delete(filterData.pid);
333        }
334      }
335    }
336
337    let locationData: Array<unknown> = [];
338    fillMap.forEach((value, key): void => {
339      // @ts-ignore
340      if (value.ts >= leftNs) {
341        locationData.push(key);
342        locationData.push(value);
343      }
344    });
345    leftMap.forEach((value, key): void => {
346      locationData.push(value);
347    });
348    return locationData;
349  }
350
351  private getSystemLockData(data: Array<unknown>, leftNs: number): unknown[] {
352    let values = this.getConvertData(data);
353    let watchIndex: Array<string> = [];
354    let fillMap: Map<unknown, unknown> = new Map<unknown, unknown>();
355    let leftMap: Map<unknown, unknown> = new Map<unknown, unknown>();
356    for (let index = 0; index < values.length; index++) {
357      let filterData: unknown = values[index];
358      // @ts-ignore
359      if (filterData.tag.indexOf('ADD') > -1) {
360        // @ts-ignore
361        leftMap.set(filterData.message, filterData);
362        // @ts-ignore
363        watchIndex.push(filterData.message);
364      } else {
365        // @ts-ignore
366        let i = watchIndex.indexOf(filterData.message);
367        if (i > -1) {
368          // @ts-ignore
369          fillMap.set(leftMap.get(filterData.message), filterData);
370          // @ts-ignore
371          watchIndex.splice(i, 1, undefined);
372          // @ts-ignore
373          leftMap.delete(filterData.message);
374        }
375      }
376    }
377    let lockData: Array<unknown> = [];
378    fillMap.forEach((value, key): void => {
379      // @ts-ignore
380      if (value.ts >= leftNs) {
381        lockData.push(key);
382        lockData.push(value);
383      }
384    });
385    leftMap.forEach((value, key): void => {
386      lockData.push(value);
387    });
388    return lockData;
389  }
390
391  private getConvertData(data: Array<unknown>): unknown[] {
392    let convertItem: unknown = {};
393    data.forEach((item: unknown): void => {
394      // @ts-ignore
395      if (convertItem[item.ts + item.eventName] === undefined) {
396        // @ts-ignore
397        convertItem[item.ts + item.eventName] = {};
398        // @ts-ignore
399        convertItem[item.ts + item.eventName].ts = item.ts;
400        // @ts-ignore
401        convertItem[item.ts + item.eventName].eventName = item.eventName;
402        // @ts-ignore
403        convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue;
404      } else {
405        // @ts-ignore
406        convertItem[item.ts + item.eventName][item.appKey.toLocaleLowerCase()] = item.appValue;
407      }
408    });
409    // @ts-ignore
410    return Object.values(convertItem);
411  }
412
413  initHtml(): string {
414    return `
415        <style>
416        :host{
417            display: flex;
418            flex-direction: column;
419            padding: 10px 10px 0 10px;
420        }
421        .sys-detail-progress{
422            bottom: 33px;
423            position: absolute;
424            height: 1px;
425            left: 0;
426            right: 0;
427        }
428        </style>
429        <div class="sys-detail-content" style="display: flex;flex-direction: column">
430            <div style="display: flex;flex-direction: row">
431                <lit-slicer style="width:100%">
432                    <div class="box-details" style="width: 100%">
433                        <lit-table id="tb-system-data" style="height: auto">
434                            <lit-table-column class="sys-detail-column" width="300px" title="" data-index="eventName" key="eventName"  align="flex-start" order>
435                            </lit-table-column>
436                            <lit-table-column class="sys-detail-column" width="300px" title="" data-index="ts" key="ts"  align="flex-start" order>
437                            </lit-table-column>
438                        </lit-table>
439                    </div>
440                    <lit-slicer-track ></lit-slicer-track>
441                    <lit-table id="tb-system-details-data" no-head hideDownload style="height: auto;border-left: 1px solid var(--dark-border1,#e2e2e2)">
442                        <lit-table-column class="sys-detail-column" width="100px" title="" data-index="key" key="key"  align="flex-start" >
443                        </lit-table-column>
444                        <lit-table-column class="sys-detail-column" width="1fr" title="" data-index="value" key="value"  align="flex-start">
445                        </lit-table-column>
446                    </lit-table>
447                </lit-slicer>
448            </div>
449            <lit-progress-bar class="progress sys-detail-progress"></lit-progress-bar>
450        </div>
451        `;
452  }
453}
454