# Conflicts: # src/app/shared/services/alarm-sound.service.tspull/14/head
| private dialog: MatDialog, | private dialog: MatDialog, | ||||
| private renderer: Renderer2, | private renderer: Renderer2, | ||||
| private alarmSoundService$: AlarmSoundService, | private alarmSoundService$: AlarmSoundService, | ||||
| private confirmDialogService$: ConfirmDialogService, | |||||
| ) {} | ) {} | ||||
| ngOnInit() { | ngOnInit() { | ||||
| this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h | this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h | ||||
| this.state5 = message.state5 === '1'; // 1 ON, 0 OFF | this.state5 = message.state5 === '1'; // 1 ON, 0 OFF | ||||
| this.isReady = message.ready === '1'; | this.isReady = message.ready === '1'; | ||||
| this.alarmSoundService$.startAlarm( | |||||
| this.state5, | |||||
| this.isReady, | |||||
| this.state1, | |||||
| this.state2, | |||||
| ); | |||||
| this.alarmSoundService$.startAlarm(this.state5, this.isReady, this.state1, this.state2); | |||||
| this.updateIcons(); | this.updateIcons(); | ||||
| } | } | ||||
| } | } | ||||
| addIconsToMap(): void { | addIconsToMap(): void { |
| <div class="card-state"> | <div class="card-state"> | ||||
| <img src="assets/images/ground.png"> | <img src="assets/images/ground.png"> | ||||
| <div class="state t2" id="State2"> | <div class="state t2" id="State2"> | ||||
| <div> | |||||
| <div class="sensor-off" [class.sensor-on]="(state1 && state5 && isReady)"> | |||||
| <img [src]="state5 ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||||
| <div fxLayout="row"> | |||||
| <div class="sensor-off" [class.sensor-on]="(state1 && state5 && status1)"> | |||||
| <img [src]="(state5 && status1) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||||
| </div> | </div> | ||||
| <a href="/overview/camera-stream" target="_blank"> | |||||
| <img style="width: 30px; height: 30px;" src="assets/images/camera.png"> | |||||
| </a> | |||||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||||
| </div> | </div> | ||||
| <div *ngIf="(state1 && state5 && isReady)" class="alarm-text" | |||||
| [ngClass]="{'alarm-text-on': (state1 && state5 && isReady) }">FIRE ALARM</div> | |||||
| <div *ngIf="(state1 && state5 && status1)" class="alarm-text" | |||||
| [ngClass]="{'alarm-text-on': (state1 && state5 && status1) }">FIRE ALARM</div> | |||||
| </div> | </div> | ||||
| <div class="state t3" id="State3"> | <div class="state t3" id="State3"> | ||||
| <div> | |||||
| <div class="sensor-off" [class.sensor-on]="(state2 && state5 && isReady)"> | |||||
| <img [src]="state5 ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||||
| <div fxLayout="row"> | |||||
| <div class="sensor-off" [class.sensor-on]="(state2 && state5 && status2)"> | |||||
| <img [src]="(state5 && status2) ? 'assets/images/sensor-on.png' : 'assets/images/sensor-off.png'" style="width: 30px; height: 30px"> | |||||
| </div> | </div> | ||||
| <a href="/overview/camera-stream" target="_blank"> | |||||
| <img style="width: 30px; height: 30px;" src="assets/images/camera.png"> | |||||
| </a> | |||||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||||
| </div> | </div> | ||||
| <div *ngIf="(state2 && state5 && isReady)" class="alarm-text" | |||||
| [ngClass]="{'alarm-text-on': (state2 && state5 && isReady) }">FENCE ALARM</div> | |||||
| <div *ngIf="(state2 && state5 && status2)" class="alarm-text" | |||||
| [ngClass]="{'alarm-text-on': (state2 && state5 && status2) }">FENCE ALARM</div> | |||||
| </div> | </div> | ||||
| <div class="state t4" id="State4"> | |||||
| <div> | |||||
| <div class="state t4" id="State4" fxLayout="row" > | |||||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | <img [src]="getImageSource()" style="width: 30px; height: 30px"> | ||||
| <a href="/overview/camera-stream" target="_blank"> | |||||
| <img style="width: 30px; height: 30px;" src="assets/images/camera.png"> | |||||
| </a> | |||||
| </div> | |||||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||||
| </div> | </div> | ||||
| <div class="state t5 tooltip" id="State5" > | |||||
| <div class="state t5 tooltip" id="State5" fxLayout="row"> | |||||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | <img [src]="getImageSource()" style="width: 30px; height: 30px"> | ||||
| <a href="/overview/camera-stream" target="_blank"> | |||||
| <img style="width: 30px; height: 30px;" src="assets/images/camera.png"> | |||||
| </a> | |||||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||||
| </div> | </div> | ||||
| <div class="state t6 tooltip" id="State6"> | |||||
| <div class="state t6 tooltip" id="State6" fxLayout="row"> | |||||
| <img [src]="getImageSource()" style="width: 30px; height: 30px"> | <img [src]="getImageSource()" style="width: 30px; height: 30px"> | ||||
| <a href="/overview/camera-stream" target="_blank"> | |||||
| <img style="width: 30px; height: 30px;" src="assets/images/camera.png"> | |||||
| </a> | |||||
| <ng-container [ngTemplateOutlet]="camera"></ng-container> | |||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <button [disabled]="!isConnected" mat-flat-button color="{{switchArm ? 'accent' : 'primary'}}" (click)="toggleState1()">{{ switchArm ? 'DISARM' : 'ARM'}}</button> | <button [disabled]="!isConnected" mat-flat-button color="{{switchArm ? 'accent' : 'primary'}}" (click)="toggleState1()">{{ switchArm ? 'DISARM' : 'ARM'}}</button> | ||||
| </div> | </div> | ||||
| </div> | </div> | ||||
| <ng-template #camera> | |||||
| <div (click)="openDialog()"> | |||||
| <img style="width: 30px; height: 30px; cursor: pointer" src="assets/images/camera.png"> | |||||
| </div> | |||||
| </ng-template> |
| import {Subscription} from "rxjs"; | import {Subscription} from "rxjs"; | ||||
| import {SocketService} from "../../../shared/services/socket.service"; | import {SocketService} from "../../../shared/services/socket.service"; | ||||
| import {ToastrService} from "ngx-toastr"; | import {ToastrService} from "ngx-toastr"; | ||||
| import {CameraDialogComponent} from "../../../shared/component/camera-dialog/camera-dialog.component"; | |||||
| import {MatDialog} from "@angular/material/dialog"; | |||||
| import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service'; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-security-system-details', | selector: 'app-security-system-details', | ||||
| export class SecuritySystemDetailsComponent implements OnInit, OnDestroy { | export class SecuritySystemDetailsComponent implements OnInit, OnDestroy { | ||||
| isConnected = false; | isConnected = false; | ||||
| state1 = false; | state1 = false; | ||||
| status1 = false; | |||||
| state2 = false; | state2 = false; | ||||
| status2 = false; | |||||
| state3 = ''; | state3 = ''; | ||||
| state4 = ''; | state4 = ''; | ||||
| state5 = false; | state5 = false; | ||||
| constructor( | constructor( | ||||
| private socketService$: SocketService, | private socketService$: SocketService, | ||||
| private toastr: ToastrService | |||||
| private toastr: ToastrService, | |||||
| private dialog: MatDialog, | |||||
| private confirm$: ConfirmDialogService | |||||
| ) {} | ) {} | ||||
| ngOnInit() { | ngOnInit() { | ||||
| onMessage(message: any) { | onMessage(message: any) { | ||||
| if (message.id == '0' && message.type === 'get') { | if (message.id == '0' && message.type === 'get') { | ||||
| this.state1 = message.state1 === '0'; // 1 OFF // alarm 12h | this.state1 = message.state1 === '0'; // 1 OFF // alarm 12h | ||||
| this.status1 = message.status1 === '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||||
| this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h | this.state2 = message.state2 === '0'; // 1 OFF // alarm 1h | ||||
| this.status2 = message.status2 === '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||||
| this.state3 = message.state3 === '1' ? 'ON' : 'OFF'; | this.state3 = message.state3 === '1' ? 'ON' : 'OFF'; | ||||
| this.state4 = message.state4 === '1' ? 'ON' : 'OFF'; | this.state4 = message.state4 === '1' ? 'ON' : 'OFF'; | ||||
| this.state5 = message.state5 === '1'; // alarm 9h && 6h // 1 ON, 0 OFF | this.state5 = message.state5 === '1'; // alarm 9h && 6h // 1 ON, 0 OFF | ||||
| this.switchWarning = message.state6 === '1';// alarm 9h && 6h // 1 ON, 0 OFF | this.switchWarning = message.state6 === '1';// alarm 9h && 6h // 1 ON, 0 OFF | ||||
| this.isReady = message.ready === '1'; | this.isReady = message.ready === '1'; | ||||
| if (message.ready === '0' && this.state5) { // not ready and ON arm | |||||
| this.toastr.warning('System not ready', 'Warning', {timeOut: 5000}); | |||||
| if ((message.status1 === '0' || message.status2 === '0') && this.state5) { // not ready and ON arm | |||||
| const data = []; | |||||
| if (message.status1 === '0'){ | |||||
| data.push({key: 'status1', value: false}) | |||||
| } | |||||
| if (message.status2 === '0'){ | |||||
| data.push({key: 'status2', value: false}) | |||||
| } | |||||
| this.confirm$.openDialog(data); | |||||
| // this.toastr.warning('System not ready', 'Warning', {timeOut: 5000}); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| openDialog(): void { | |||||
| this.dialog.open(CameraDialogComponent, { | |||||
| width: '80vw', | |||||
| data: '', | |||||
| }); | |||||
| } | |||||
| } | } |
| <h2 mat-dialog-title style="border-bottom: solid 1px #eeeeee">CONFIRM TO IGNORE THE WARNING</h2> | |||||
| <mat-dialog-content> | |||||
| <section class="example-section"> | |||||
| <span class="example-list-section"> | |||||
| <mat-checkbox class="example-margin" | |||||
| color="primary" | |||||
| [checked]="allComplete" | |||||
| [indeterminate]="someComplete()" | |||||
| (change)="setAll($event.checked)"> | |||||
| {{data.name}} | |||||
| </mat-checkbox> | |||||
| </span> | |||||
| <span class="example-list-section"> | |||||
| <ul> | |||||
| <li *ngFor="let item of data.gateStatus"> | |||||
| <mat-checkbox [(ngModel)]="item.ignore" | |||||
| color="primary" | |||||
| (ngModelChange)="updateAllComplete()"> | |||||
| {{item.name}} | |||||
| <h5 mat-dialog-title >CONFIRM TO IGNORE THE WARNING</h5> | |||||
| <mat-dialog-content style="padding-bottom: 4px"> | |||||
| <div *ngFor="let item of data"> | |||||
| <mat-checkbox [(ngModel)]="item.value" (ngModelChange)="submitChange(item)" name="sensor"> | |||||
| {{ (item.key == 'status1' ? 'Fire' : 'ff')}} | |||||
| </mat-checkbox> | </mat-checkbox> | ||||
| </li> | |||||
| </ul> | |||||
| </span> | |||||
| </section> | |||||
| </div> | |||||
| </mat-dialog-content> | </mat-dialog-content> | ||||
| <mat-dialog-actions align="end"> | <mat-dialog-actions align="end"> | ||||
| <button mat-button mat-dialog-close>Cancel</button> | |||||
| <button mat-button mat-dialog-close style="background: #ff7723; color: #ffffff">Yes</button> | |||||
| <button mat-button mat-dialog-close cdkFocusInitial>Close</button> | |||||
| </mat-dialog-actions> | </mat-dialog-actions> |
| ul { | |||||
| list-style-type: none; | |||||
| margin-top: 4px; | |||||
| .mat-mdc-dialog-title { | |||||
| border-bottom: solid 1px #eeeeee; | |||||
| font-size: 14px; | |||||
| color: #FFFFFF; | |||||
| background: orange; | |||||
| } | |||||
| ::ng-deep.mdc-checkbox .mdc-checkbox__native-control:enabled:checked~.mdc-checkbox__background{ | |||||
| background: orange !important; | |||||
| border: orange !important; | |||||
| } | } |
| }) | }) | ||||
| export class ConfirmDialogComponent { | export class ConfirmDialogComponent { | ||||
| constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) {} | constructor(public dialogRef: MatDialogRef<ConfirmDialogComponent>) {} | ||||
| data = { | |||||
| name: 'All', | |||||
| ignore: false, | |||||
| gateStatus: [ | |||||
| data = [ | |||||
| { | { | ||||
| name: 'GATE A', | |||||
| position: { latitude: 123.456, longitude: 456.789 }, | |||||
| ignore: false, | |||||
| key: 'status1', | |||||
| value: false, | |||||
| }, | }, | ||||
| { | |||||
| name: 'GATE B', | |||||
| position: { latitude: 111.222, longitude: 333.444 }, | |||||
| ignore: false, | |||||
| }, | |||||
| { | |||||
| name: 'GATE C', | |||||
| position: { latitude: 222.333, longitude: 444.555 }, | |||||
| ignore: false, | |||||
| }, | |||||
| ], | |||||
| }; | |||||
| allComplete: boolean = false; | |||||
| updateAllComplete() { | |||||
| this.allComplete = | |||||
| this.data.gateStatus != null && | |||||
| this.data.gateStatus.every((t) => t.ignore); | |||||
| } | |||||
| someComplete(): boolean { | |||||
| if (this.data.gateStatus == null) { | |||||
| return false; | |||||
| } | |||||
| return ( | |||||
| this.data.gateStatus.filter((t) => t.ignore).length > 0 && | |||||
| !this.allComplete | |||||
| ); | |||||
| } | |||||
| setAll(completed: boolean) { | |||||
| this.allComplete = completed; | |||||
| if (this.data.gateStatus == null) { | |||||
| return; | |||||
| } | |||||
| this.data.gateStatus.forEach((t) => (t.ignore = completed)); | |||||
| { | |||||
| name: 'status2', | |||||
| value: false, | |||||
| }, | |||||
| ]; | |||||
| submitChange(item: any): void{ | |||||
| console.log(item); | |||||
| // call socket here | |||||
| } | } | ||||
| } | } |
| import { ElementRef, Injectable } from '@angular/core'; | |||||
| import { Injectable } from '@angular/core'; | |||||
| @Injectable({ | @Injectable({ | ||||
| providedIn: 'root', | providedIn: 'root', | ||||
| private alertInterval: any; | private alertInterval: any; | ||||
| private alertDuration: number = 10000; | private alertDuration: number = 10000; | ||||
| private audio = new Audio(); | private audio = new Audio(); | ||||
| isPlay = false; | |||||
| private isPlaying: boolean = false; | |||||
| constructor() { | constructor() { | ||||
| this.audio.src = 'assets/sound/alarm_5m.mp3'; | this.audio.src = 'assets/sound/alarm_5m.mp3'; | ||||
| this.audio.load(); | this.audio.load(); | ||||
| this.audio.onended = () => { | |||||
| // Khi phát hết âm thanh, đặt biến isPlaying về false | |||||
| this.isPlaying = false; | |||||
| }; | |||||
| } | } | ||||
| playSound(): void { | playSound(): void { | ||||
| this.isPlay = true; | |||||
| this.audio.play().catch((error) => { | |||||
| console.error('Error playing audio:', error); | |||||
| }); | |||||
| if (!this.isPlaying) { | |||||
| this.audio.play().then(() => { | |||||
| this.isPlaying = true; | |||||
| this.alertInterval = setInterval(() => { | |||||
| this.stopAlarm(); | |||||
| }, this.alertDuration); | |||||
| }).catch((error) => { | |||||
| console.error('Error playing audio:', error); | |||||
| }); | |||||
| } | |||||
| } | } | ||||
| stopSound(): void { | stopSound(): void { | ||||
| if (this.audio) { | if (this.audio) { | ||||
| this.audio.pause(); | this.audio.pause(); | ||||
| this.audio.currentTime = 0; | this.audio.currentTime = 0; | ||||
| this.isPlaying = false; | |||||
| } | } | ||||
| } | } | ||||
| startAlarm( | |||||
| state5: boolean, | |||||
| isReady: boolean, | |||||
| state1: boolean, | |||||
| state2: boolean, | |||||
| ): void { | |||||
| if (state5 && isReady && (state1 || state2) && !this.isPlay) { | |||||
| startAlarm( isTurnOn: boolean, isReady: boolean, fireArm: boolean, fenceArm: boolean): void { | |||||
| if (isTurnOn && isReady && (fireArm || fenceArm)) { | |||||
| //this.alertDuration = // setting time | |||||
| this.playSound(); | this.playSound(); | ||||
| this.alertInterval = setInterval(() => { | |||||
| this.stopAlarm(); | |||||
| }, this.alertDuration); | |||||
| }else{ | |||||
| this.stopAlarm(); | |||||
| } | } | ||||
| } | } | ||||
| stopAlarm(): void { | stopAlarm(): void { | ||||
| this.stopSound(); | this.stopSound(); | ||||
| clearInterval(this.alertInterval); | |||||
| this.isPlay = false; | |||||
| if (this.alertInterval){ | |||||
| clearInterval(this.alertInterval); | |||||
| } | |||||
| } | } | ||||
| simulateClick(element: HTMLElement) { | |||||
| element.click(); | |||||
| } | |||||
| } | } |
| constructor(private dialog: MatDialog) {} | constructor(private dialog: MatDialog) {} | ||||
| openDialog(): void { | |||||
| openDialog(data: any[]): void { | |||||
| if (!this.isDialogOpen) { | if (!this.isDialogOpen) { | ||||
| this.isDialogOpen = true; | this.isDialogOpen = true; | ||||
| const dialogRef = this.dialog.open(ConfirmDialogComponent); | const dialogRef = this.dialog.open(ConfirmDialogComponent); |