diff --git a/src/app/app.component.html b/src/app/app.component.html index 81866bc777ed353014e371e2ff61d5f744b17b1b..226caffee149e381b1a47715d9dbeff7b3f3f6f4 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,3 +1,5 @@ <app-map class="wrapper"></app-map> -<chart-timeline></chart-timeline> \ No newline at end of file +<chart-timeline></chart-timeline> + +<app-table class="wrapper"></app-table> diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 4a78b20e4d20b43c054750214fb229be1c710bb2..8a01d75e95e5021f78dfee7450b5960e7641c9f4 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -28,6 +28,7 @@ import { MapComponent } from './components/map/map.component'; import { AppRoutingModule } from './app-routing.module'; import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; import { ChartTimelineComponent } from './components/chart-timeline/chart-timeline.component'; +import { TableComponent } from './components/table/table.component'; @@ -36,7 +37,8 @@ import { ChartTimelineComponent } from './components/chart-timeline/chart-timeli declarations: [ AppComponent, MapComponent, - ChartTimelineComponent + ChartTimelineComponent, + TableComponent ], imports: [ BrowserModule, diff --git a/src/app/components/chart-timeline/chart-timeline.component.html b/src/app/components/chart-timeline/chart-timeline.component.html index 0630e1b469e88478d849c62b224a57da3d50a91a..06fc6e29536b219ba4f664c2b1b43127f33911bd 100644 --- a/src/app/components/chart-timeline/chart-timeline.component.html +++ b/src/app/components/chart-timeline/chart-timeline.component.html @@ -1,5 +1,5 @@ -<div id="chart" class="wrapper"> - <apx-chart +<div id="chart" class="wrapper" *ngIf="chartOptions.series.length > 0"> + <apx-chart [series]="chartOptions.series" [chart]="chartOptions.chart" [dataLabels]="chartOptions.dataLabels" diff --git a/src/app/components/table/table.component.html b/src/app/components/table/table.component.html new file mode 100644 index 0000000000000000000000000000000000000000..4cfcaf8c5ef355274f4fe5d856528ae5c4d06ece --- /dev/null +++ b/src/app/components/table/table.component.html @@ -0,0 +1,56 @@ +<div class="table" *ngIf="dataSource.length > 0"> + <table mat-table [dataSource]="dataSource" class="mat-elevation-z8"> + + <!-- Agent --> + <ng-container matColumnDef="agent"> + <th mat-header-cell *matHeaderCellDef> + <mat-icon aria-hidden="false" aria-label="Agent">people</mat-icon> Agent + </th> + <td mat-cell *matCellDef="let element"> {{element.id}} </td> + </ng-container> + + <!-- Type --> + <ng-container matColumnDef="type"> + <th mat-header-cell *matHeaderCellDef> + <mat-icon aria-hidden="false" aria-label="Type">style</mat-icon> Type + </th> + <td mat-cell *matCellDef="let element"> {{element.type}} </td> + </ng-container> + + <!-- Time --> + <ng-container matColumnDef="time"> + <th mat-header-cell *matHeaderCellDef> + <mat-icon aria-hidden="false" aria-label="Time">access_time</mat-icon> Time + </th> + <td mat-cell *matCellDef="let element"> {{element.lastPosUpdate | date:"h:mm:ss" }} </td> + </ng-container> + + <!-- Zone --> + <ng-container matColumnDef="zone"> + <th mat-header-cell *matHeaderCellDef> + <mat-icon aria-hidden="false" aria-label="Zone">hive</mat-icon> Zone + </th> + <td mat-cell *matCellDef="let element"> + <mat-chip-list> + <mat-chip *ngFor="let zone of element.zoneDescriptors"> {{ zone.zoneId }} </mat-chip> + </mat-chip-list> + </td> + </ng-container> + + <!-- Position --> + <ng-container matColumnDef="position"> + <th mat-header-cell *matHeaderCellDef> + <mat-icon aria-hidden="false" aria-label="Position">room</mat-icon> Position + </th> + <td mat-cell *matCellDef="let element"> + <span *ngFor="let dim of (element.position.point | keyvalue)"> + {{dim.key}}: {{dim.value}} + </span> + </td> + </ng-container> + + <tr mat-header-row *matHeaderRowDef="displayedColumns"></tr> + <tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr> + + </table> +</div> \ No newline at end of file diff --git a/src/app/components/table/table.component.scss b/src/app/components/table/table.component.scss new file mode 100644 index 0000000000000000000000000000000000000000..16b7d98500301fc06640165a2d0a351efdb0a414 --- /dev/null +++ b/src/app/components/table/table.component.scss @@ -0,0 +1,17 @@ +.map { + margin-bottom: 20px; + height: 70vh + } + + table { + width: 100%; + } + + .table { + margin-bottom: 35px; + + th.mat-header-cell { + vertical-align: middle; + } + } + \ No newline at end of file diff --git a/src/app/components/table/table.component.spec.ts b/src/app/components/table/table.component.spec.ts new file mode 100644 index 0000000000000000000000000000000000000000..e2f8acc7d0dba344ceaf1566f628b6aa5ed518b7 --- /dev/null +++ b/src/app/components/table/table.component.spec.ts @@ -0,0 +1,25 @@ +import { ComponentFixture, TestBed } from '@angular/core/testing'; + +import { TableComponent } from './table.component'; + +describe('TableComponent', () => { + let component: TableComponent; + let fixture: ComponentFixture<TableComponent>; + + beforeEach(async () => { + await TestBed.configureTestingModule({ + declarations: [ TableComponent ] + }) + .compileComponents(); + }); + + beforeEach(() => { + fixture = TestBed.createComponent(TableComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/components/table/table.component.ts b/src/app/components/table/table.component.ts new file mode 100644 index 0000000000000000000000000000000000000000..9d71cab3dfff2ced23af4134939bd78c30851874 --- /dev/null +++ b/src/app/components/table/table.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import {PositionUpdate, ZoneDesc} from 'src/app/model/base-model'; + +import { IMqttMessage, MqttService } from 'ngx-mqtt'; +import { Subscription } from 'rxjs'; +import { MatTable } from '@angular/material/table'; + + +@Component({ + selector: 'app-table', + templateUrl: './table.component.html', + styleUrls: ['./table.component.scss'] +}) +export class TableComponent implements OnInit { + + @ViewChild(MatTable) + table!: MatTable<Object>; + + private subsPosition: Subscription; + + displayedColumns: string[] = ['agent', 'type', 'time', 'zone', 'position']; + + + // testMessages: PositionUpdate[] = [ + // { "objects": [{ "id": "turtlebot", "sensorId": "98:CD:AC:26:2D:18", "type": "ROBOT", "sensorType": "RFID_SCANNER", "position": { "refSystemId": "ROOT", "point": { "x": 2.1, "y": 0.4, "z": 0.5 }, "accuracy": 0.1 }, "orientation": { }, "lastPosUpdate": "2021-11-02T09:24:49.394953789+00:00", "zoneDescriptors": [{ "zoneId": "cobot1_door_zone", "notificationType": "EntryNotification" }, { "zoneId": "robolab_east", "notificationType": "EntryNotification" }] }], "type": "EntryNotification" }, + // { "objects": [{ "id": "turtlebot", "sensorId": "UWB_1", "type": "ROBOT", "sensorType": "UWB", "position": { "refSystemId": "ROOT", "point": { "x": 3.0, "y": 1.5, "z": 3.0 }, "accuracy": 10.0 }, "orientation": { "x": 1.0, "y": 0.5, "z": 1.0, "w": 1.5 }, "lastPosUpdate": "2021-10-14T19:32:23+00:00", "zoneDescriptors": [{ "zoneId": "cobot1_door_zone", "notificationType": "EntryNotification" }, { "zoneId": "robolab_east", "notificationType": "EntryNotification" }] }], "type": "EntryNotification" }, + // { "objects": [{ "id": "turtlebot", "sensorId": "UWB_1", "type": "ROBOT", "sensorType": "UWB", "position": { "refSystemId": "ROOT", "point": { "x": -3.0, "y": 4.5, "z": 3.0 }, "accuracy": 10.0 }, "orientation": { "x": 1.0, "y": 0.5, "z": 1.0, "w": 1.5 }, "lastPosUpdate": "2021-10-14T19:32:22+00:00", "zoneDescriptors": [{ "zoneId": "robolab_east", "notificationType": "EntryNotification" }, { "zoneId": "robolab_west", "notificationType": "EntryNotification" }] }], "type": "EntryNotification" }, + // { "objects": [{ "id": "turtlebot", "sensorId": "UWB_1", "type": "ROBOT", "sensorType": "UWB", "position": { "refSystemId": "ROOT", "point": { "x": 3.0, "y": 4.5, "z": 3.0 }, "accuracy": 10.0 }, "orientation": { "x": 1.0, "y": 0.5, "z": 1.0, "w": 1.5 }, "lastPosUpdate": "2021-10-14T19:32:21+00:00", "zoneDescriptors": [{ "zoneId": "robolab_east", "notificationType": "EntryNotification" }, { "zoneId": "cobot1_window_zone", "notificationType": "EntryNotification" }] }], "type": "EntryNotification" }, + // { "objects": [{ "id": "turtlebot", "sensorId": "UWB_1", "type": "ROBOT", "sensorType": "UWB", "position": { "refSystemId": "ROOT", "point": { "x": 3.0, "y": 1.5, "z": 3.0 }, "accuracy": 10.0 }, "orientation": { "x": 1.0, "y": 0.5, "z": 1.0, "w": 1.5 }, "lastPosUpdate": "2021-10-14T19:32:20+00:00", "zoneDescriptors": [{ "zoneId": "cobot1_door_zone", "notificationType": "EntryNotification" }, { "zoneId": "robolab_east", "notificationType": "EntryNotification" }] }], "type": "EntryNotification" } + // ].map(obj => JSON.parse(JSON.stringify(obj))) + + dataSource: Object[] = [] + + constructor(private _mqttService: MqttService) { + // this.testMessages.forEach(upd => this.dataSource.push(...upd.objects)) + + this.subsPosition = this._mqttService.observe('ipos/client/position').subscribe((message: IMqttMessage) => { + let upd: PositionUpdate = JSON.parse(message.payload.toString()) + console.log(upd.objects) + this.dataSource.push(...upd.objects); + this.table?.renderRows(); + }); + } + + ngOnInit(): void { + } + +} diff --git a/src/app/model/base-model.ts b/src/app/model/base-model.ts index 445e5230778b080faa5b3b55e455127af4b3b089..645e133e395be338e00a978ef570988cc57d2201 100644 --- a/src/app/model/base-model.ts +++ b/src/app/model/base-model.ts @@ -33,7 +33,7 @@ export interface RelativePos { z?: number } -interface ZoneDesc { +export interface ZoneDesc { zoneId: string notificationType: NotificationType } diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index f0e4e7731db0767106863586118d750ba103a512..4495b4851812728133750f2e37f465bf89fd08e2 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -22,6 +22,8 @@ import { MatCardModule } from '@angular/material/card'; import { MatExpansionModule } from '@angular/material/expansion'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatTooltipModule } from '@angular/material/tooltip'; +import { MatTableModule } from '@angular/material/table'; +import {MatChipsModule} from '@angular/material/chips'; // Animation import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; @@ -48,6 +50,7 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; MatExpansionModule, MatSidenavModule, MatTooltipModule, + MatTableModule ], exports: [ FormsModule, @@ -68,6 +71,8 @@ import { BrowserAnimationsModule } from '@angular/platform-browser/animations'; MatExpansionModule, MatSidenavModule, MatTooltipModule, + MatTableModule, + MatChipsModule ] }) export class SharedModule { } diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 6086b80d8f4506781e8d4285e67bd1cfdd50663d..c12e5111512571cd93d0fcccb0594c8a9e20bac8 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -23,12 +23,18 @@ export const environment = { }; export const MQTTconfig: IMqttServiceOptions = { - hostname: 'broker.emqx.io', - port: 8084, - protocol: 'wss', + hostname: 'broker.hivemq.com', + port: 8000, path: '/mqtt' }; +// export const SecMQTTconfig: IMqttServiceOptions = { +// hostname: 'broker.emqx.io', +// port: 8084, +// protocol: 'wss', +// path: '/mqtt' +// }; + export const MarkerColorMap: { [key: string]: MarkerColor } = { "ROOT": {"marker": "red", "circle": "#d32f2f"}, "Employee1": {"marker": "green", "circle": "#008632"},