| } from '@angular/core'; | } from '@angular/core'; | ||||
| import { SocketService } from './shared/services/socket.service'; | import { SocketService } from './shared/services/socket.service'; | ||||
| import { AlarmSoundService } from './shared/services/alarm-sound.service'; | import { AlarmSoundService } from './shared/services/alarm-sound.service'; | ||||
| import {MqttClientService} from "./shared/services/mqtt-client.service"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-root', | selector: 'app-root', | ||||
| export class AppComponent implements OnInit { | export class AppComponent implements OnInit { | ||||
| title = 'Iot-web-ui'; | title = 'Iot-web-ui'; | ||||
| constructor(private socketService$: SocketService) {} | |||||
| constructor(private socketService$: SocketService, private mqtt$: MqttClientService) {} | |||||
| ngOnInit() { | ngOnInit() { | ||||
| this.socketService$.connect(); | |||||
| // this.socketService$.connect(); | |||||
| this.mqtt$.createConnection(); | |||||
| } | } | ||||
| } | } |
| <div><strong>Địa điểm:</strong> ${item.detail.position}</div> | <div><strong>Địa điểm:</strong> ${item.detail.position}</div> | ||||
| <div><strong>Tọa độ:</strong> ${item.detail.coordinates.lat}, ${item.detail.coordinates.lng}</div> | <div><strong>Tọa độ:</strong> ${item.detail.coordinates.lat}, ${item.detail.coordinates.lng}</div> | ||||
| <div><strong>Thời gian:</strong> ${item.detail.time}</div> | <div><strong>Thời gian:</strong> ${item.detail.time}</div> | ||||
| <a href="/overview/overall-ground" target="_blank">Xem chi tiết</a> | |||||
| <a href="/overview/security-system-details" target="_blank">Xem chi tiết</a> | |||||
| </div>`; | </div>`; | ||||
| } | } | ||||
| import {Component, OnDestroy, OnInit} from '@angular/core'; | import {Component, OnDestroy, OnInit} from '@angular/core'; | ||||
| import {SocketService} from "../../../shared/services/socket.service"; | import {SocketService} from "../../../shared/services/socket.service"; | ||||
| import {Subscription} from "rxjs"; | |||||
| import {Subscription, Subject} from "rxjs"; | |||||
| import {MqttClientService} from "../../../shared/services/mqtt-client.service"; | |||||
| import {takeUntil} from "rxjs/operators"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-homepage', | selector: 'app-homepage', | ||||
| time: 30, | time: 30, | ||||
| sound: 0, | sound: 0, | ||||
| }; | }; | ||||
| private statusSubscription?: Subscription; | |||||
| isConnected: boolean = false; | |||||
| constructor(private socketService$: SocketService,) { | |||||
| this.statusSubscription = this.socketService$.status$.subscribe( | |||||
| (isConnected) => { | |||||
| isConnected = false; | |||||
| private unsubscribeAll = new Subject(); | |||||
| constructor( | |||||
| private socketService$: SocketService, | |||||
| private mqtt$: MqttClientService | |||||
| ) { | |||||
| this.mqtt$.status$.pipe(takeUntil(this.unsubscribeAll)).subscribe( | |||||
| (isConnected: boolean) => { | |||||
| this.isConnected = isConnected; | this.isConnected = isConnected; | ||||
| this.mqtt$.getLog(); | |||||
| this.mqtt$.sendPublish({ id: '0', type: 'get', whistletime: ''}); | |||||
| this.mqtt$.sendPublish({ id: '0', type: 'get', arlamtime: ''}); | |||||
| this.mqtt$.messages$.pipe(takeUntil(this.unsubscribeAll)).subscribe((message: any) => { | |||||
| console.log(message); | |||||
| if (message.id == '0' && message.whistletime) { | |||||
| this.whistle.time = Number(message.whistletime); | |||||
| } | |||||
| if (message.id == '0' && message.arlamtime) { | |||||
| this.alarm.time = Number(message.arlamtime); | |||||
| } | |||||
| }); | |||||
| }, | }, | ||||
| ); | ); | ||||
| } | } | ||||
| ngOnInit() { | ngOnInit() { | ||||
| this.whistle.time = parseInt(localStorage.getItem('whistletime') ?? '10'); | |||||
| if (!localStorage.getItem('whistletime')) { | |||||
| localStorage.setItem('whistletime', '10'); | |||||
| } | |||||
| this.alarm.time = parseInt(localStorage.getItem('alarmtime') ?? '30'); | |||||
| if (!localStorage.getItem('alarmtime')) { | |||||
| localStorage.setItem('alarmtime', '30'); | |||||
| } | |||||
| } | } | ||||
| emitSetting(type: string, event: any){ | emitSetting(type: string, event: any){ | ||||
| if (this.isConnected) { | if (this.isConnected) { | ||||
| console.log(event); | |||||
| if (type === 'whistle') { | if (type === 'whistle') { | ||||
| this.whistle.time = event; | this.whistle.time = event; | ||||
| localStorage.setItem('whistletime', event); | |||||
| this.socketService$.sendMessage({ id: '0', type: 'set', whistletime: event.toString() }); | |||||
| this.mqtt$.sendPublish({ id: '0', type: 'set', whistletime: event.toString()}); | |||||
| } else if (type === 'alarm') { | } else if (type === 'alarm') { | ||||
| this.alarm.time = event; | this.alarm.time = event; | ||||
| localStorage.setItem('alarmtime', event); | |||||
| this.socketService$.sendMessage({ id: '0', type: 'set', arlamtime: event.toString() }); | |||||
| this.mqtt$.sendPublish({ id: '0', type: 'set', arlamtime: event.toString() }); | |||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ngOnDestroy(): void { | ngOnDestroy(): void { | ||||
| if (this.statusSubscription) { | |||||
| this.statusSubscription.unsubscribe(); | |||||
| } | |||||
| this.unsubscribeAll.next(''); | |||||
| this.unsubscribeAll.complete(); | |||||
| } | } | ||||
| } | } |
| import {Component, OnDestroy, OnInit} from '@angular/core'; | import {Component, OnDestroy, OnInit} from '@angular/core'; | ||||
| 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 {CameraDialogComponent} from "../../../shared/component/camera-dialog/camera-dialog.component"; | import {CameraDialogComponent} from "../../../shared/component/camera-dialog/camera-dialog.component"; | ||||
| import {MatDialog} from "@angular/material/dialog"; | import {MatDialog} from "@angular/material/dialog"; | ||||
| import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service'; | import { ConfirmDialogService } from '../../../shared/services/confirm-dialog.service'; | ||||
| import {AlarmSoundService} from "../../../shared/services/alarm-sound.service"; | |||||
| import { AlarmSoundService } from "../../../shared/services/alarm-sound.service"; | |||||
| import { MqttClientService } from "../../../shared/services/mqtt-client.service"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-security-system-details', | selector: 'app-security-system-details', | ||||
| private dialog: MatDialog, | private dialog: MatDialog, | ||||
| private confirm$: ConfirmDialogService, | private confirm$: ConfirmDialogService, | ||||
| private alarmSoundService$: AlarmSoundService, | private alarmSoundService$: AlarmSoundService, | ||||
| private mqtt$: MqttClientService | |||||
| ) {} | ) {} | ||||
| ngOnInit() { | ngOnInit() { | ||||
| // this.socketService$.connect(); | |||||
| this.statusSubscription = this.socketService$.status$.subscribe(isConnected => { | |||||
| this.statusSubscription = this.mqtt$.status$.subscribe((isConnected) => { | |||||
| this.isConnected = isConnected; | this.isConnected = isConnected; | ||||
| this.getReadings(); | |||||
| if (this.isConnected) { | |||||
| this.intervalId = setInterval(() => this.getReadings(), 5000); | |||||
| this.messageSubscription = this.socketService$.messages$.subscribe(message => { | |||||
| if (isConnected){ | |||||
| this.mqtt$.getLog(); | |||||
| this.messageSubscription = this.mqtt$.messages$.subscribe(message => { | |||||
| console.log('MQTT sup msg: ',message); | |||||
| this.onMessage(message); | this.onMessage(message); | ||||
| }); | }); | ||||
| } | } | ||||
| }); | |||||
| }) | |||||
| } | } | ||||
| ngOnDestroy(): void { | ngOnDestroy(): void { | ||||
| this.alarmSoundService$.stopAlarm(); | this.alarmSoundService$.stopAlarm(); | ||||
| } | } | ||||
| getReadings() { | |||||
| let str = {id: '0', type: 'get'}; | |||||
| this.socketService$.sendMessage(str); | |||||
| } | |||||
| toggleState1() { | toggleState1() { | ||||
| this.switchArm = !this.switchArm; | this.switchArm = !this.switchArm; | ||||
| let str = {id: '0', type: 'cmd', state1: this.switchArm.toString()}; | let str = {id: '0', type: 'cmd', state1: this.switchArm.toString()}; | ||||
| this.socketService$.sendMessage(str); | |||||
| this.mqtt$.sendPublish(str); | |||||
| } | } | ||||
| getImageSource(): string { | getImageSource(): string { | ||||
| } | } | ||||
| onMessage(message: any) { | onMessage(message: any) { | ||||
| if (message.id == '0' && message.type === 'get') { | |||||
| 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.status2 = message.status2 === '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||||
| this.state3 = message.state3 === '1' ? 'ON' : 'OFF'; | |||||
| this.state4 = message.state4 === '1' ? 'ON' : 'OFF'; | |||||
| this.state5 = message.state5 === '1'; // alarm 9h && 6h // 1 ON, 0 OFF | |||||
| this.state6 = message.state6 === '1'; // ? 'ON' : 'OFF'; | |||||
| if (message.id == '0' && message.type == 'get') { | |||||
| 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.status2 = message.status2 == '1'; // 0 not, 1 ready, 2 error, 3 bypass | |||||
| this.state3 = message.state3 == '1' ? 'ON' : 'OFF'; | |||||
| this.state4 = message.state4 == '1' ? 'ON' : 'OFF'; | |||||
| this.state5 = message.state5 == '1'; // alarm 9h && 6h // 1 ON, 0 OFF | |||||
| this.state6 = message.state6 == '1'; // ? 'ON' : 'OFF'; | |||||
| this.switchArm = message.state5 === '1';// alarm 9h && 6h // 1 ON, 0 OFF | |||||
| this.switchWarning = message.state6 === '1';// alarm 9h && 6h // 1 ON, 0 OFF | |||||
| this.switchArm = message.state5 == '1';// alarm 9h && 6h // 1 ON, 0 OFF | |||||
| this.isReady = message.ready === '1'; | |||||
| if ((message.status1 === '0' || message.status2 === '0') && this.state5) { // not ready and ON arm | |||||
| this.isReady = message.ready == '1'; | |||||
| if ((message.status1 == '0' || message.status2 == '0') && this.state5) { // not ready and ON arm | |||||
| const data = []; | const data = []; | ||||
| if (message.status1 === '0'){ | |||||
| if (message.status1 == '0'){ | |||||
| data.push({key: 'status1', value: false}) | data.push({key: 'status1', value: false}) | ||||
| } | } | ||||
| if (message.status2 === '0'){ | |||||
| if (message.status2 == '0'){ | |||||
| data.push({key: 'status2', value: false}) | data.push({key: 'status2', value: false}) | ||||
| } | } | ||||
| this.confirm$.openDialog(data); | this.confirm$.openDialog(data); | ||||
| // this.toastr.warning('System not ready', 'Warning', {timeOut: 5000}); | |||||
| } | } | ||||
| this.alarmSoundService$.startAlarm(this.state5, this.state1,this.status1, this.state2, this.status2); | this.alarmSoundService$.startAlarm(this.state5, this.state1,this.status1, this.state2, this.status2); | ||||
| } | } |
| async ngAfterViewInit() { | async ngAfterViewInit() { | ||||
| const connect = async () => { | const connect = async () => { | ||||
| this.player = await loadPlayer({ | this.player = await loadPlayer({ | ||||
| url: 'ws://localhost:8080/stream', | |||||
| url: 'wss://wss.aztrace.vn/stream', | |||||
| canvas: this.videoPlayer!.nativeElement, | canvas: this.videoPlayer!.nativeElement, | ||||
| onDisconnect: () => { | onDisconnect: () => { | ||||
| setTimeout(connect, 5000); | setTimeout(connect, 5000); |
| <h5 mat-dialog-title >CONFIRM TO IGNORE THE WARNING</h5> | <h5 mat-dialog-title >CONFIRM TO IGNORE THE WARNING</h5> | ||||
| <mat-dialog-content style="padding-bottom: 4px"> | |||||
| <mat-dialog-content style="padding-bottom: 4px" *ngIf="data.length"> | |||||
| <div *ngFor="let item of data"> | <div *ngFor="let item of data"> | ||||
| <mat-checkbox [(ngModel)]="item.value" | <mat-checkbox [(ngModel)]="item.value" | ||||
| (ngModelChange)="submitChange(item)" | (ngModelChange)="submitChange(item)" |
| import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; | import {MAT_DIALOG_DATA, MatDialogRef} from '@angular/material/dialog'; | ||||
| import {SocketService} from "../../services/socket.service"; | import {SocketService} from "../../services/socket.service"; | ||||
| import {Subscription} from "rxjs"; | import {Subscription} from "rxjs"; | ||||
| import {MqttClientService} from "../../services/mqtt-client.service"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-confirm-dialog', | selector: 'app-confirm-dialog', | ||||
| constructor( | constructor( | ||||
| @Inject(MAT_DIALOG_DATA) public data: any[], | @Inject(MAT_DIALOG_DATA) public data: any[], | ||||
| private socketService$: SocketService, | private socketService$: SocketService, | ||||
| private mqtt$: MqttClientService, | |||||
| ) { | ) { | ||||
| this.statusSubscription = this.socketService$.status$.subscribe( | |||||
| this.statusSubscription = this.mqtt$.status$.subscribe( | |||||
| (isConnected) => { | (isConnected) => { | ||||
| this.isConnected = isConnected; | this.isConnected = isConnected; | ||||
| }, | }, | ||||
| submitChange(item: any): void{ | submitChange(item: any): void{ | ||||
| if(this.isConnected) { | if(this.isConnected) { | ||||
| const position = item.key === 'status1' ? 1 : 2; | |||||
| this.socketService$.sendMessage({ id: '0', type: 'bypass', state: position}) | |||||
| const position = item.key === 'status1' ? '1' : '2'; | |||||
| this.mqtt$.sendPublish({ id: '0', type: 'bypass', state: position}) | |||||
| item.value = true; | item.value = true; | ||||
| } | } | ||||
| } | } |
| @Input() value: number = 10; | @Input() value: number = 10; | ||||
| @Input() max: number = 300; | @Input() max: number = 300; | ||||
| @Input() icon: string = ''; | @Input() icon: string = ''; | ||||
| @Input() disable: boolean = false; | |||||
| @Output() valueChange = new EventEmitter<number>(); | @Output() valueChange = new EventEmitter<number>(); | ||||
| @Input() disable: boolean = false; | @Input() disable: boolean = false; | ||||
| onChange = (value: number) => {}; | onChange = (value: number) => {}; |
| IPublishOptions, | IPublishOptions, | ||||
| } from 'ngx-mqtt'; | } from 'ngx-mqtt'; | ||||
| import { IClientSubscribeOptions } from 'mqtt-browser'; | import { IClientSubscribeOptions } from 'mqtt-browser'; | ||||
| import { Subscription } from 'rxjs'; | |||||
| import {BehaviorSubject, Observable, Subject, Subscription} from 'rxjs'; | |||||
| @Injectable({ | @Injectable({ | ||||
| providedIn: 'root' | providedIn: 'root' | ||||
| } | } | ||||
| private curSubscription: Subscription | undefined; | private curSubscription: Subscription | undefined; | ||||
| connection = { | connection = { | ||||
| hostname: 'test.mosquitto.org', | |||||
| clean: true, // 保留会话 | |||||
| hostname: 'broker.hivemq.com', | |||||
| clean: true, | |||||
| path:'/mqtt', | path:'/mqtt', | ||||
| port: 8081, | |||||
| connectTimeout: 4000, // 超时时间 | |||||
| reconnectPeriod: 4000, // 重连时间间隔 | |||||
| // 认证信息 | |||||
| port: 8884, | |||||
| reconnectPeriod: 4000, | |||||
| protocol: 'wss', | protocol: 'wss', | ||||
| } | } | ||||
| subscription = { | |||||
| topic: 'isoft/log10', | |||||
| qos: 0, | |||||
| }; | |||||
| publish = { | |||||
| topic: 'isoft/in10', | |||||
| qos: 0, | |||||
| payload: '{ "msg": "Hello, I am browser." }', | |||||
| }; | |||||
| receiveNews = ''; | receiveNews = ''; | ||||
| qosList = [ | |||||
| { label: 0, value: 0 }, | |||||
| { label: 1, value: 1 }, | |||||
| { label: 2, value: 2 }, | |||||
| ]; | |||||
| isConnection = false; | isConnection = false; | ||||
| subscribeSuccess = false; | |||||
| private statusSubject = new BehaviorSubject<boolean>(this.isConnection); | |||||
| public status$ = this.statusSubject.asObservable(); | |||||
| private messagesSubject$ = new Subject(); | |||||
| public messages$ = this.messagesSubject$.asObservable(); | |||||
| // 创建连接 | // 创建连接 | ||||
| createConnection() { | createConnection() { | ||||
| // 连接字符串, 通过协议指定使用的连接方式 | |||||
| // ws 未加密 WebSocket 连接 | |||||
| // wss 加密 WebSocket 连接 | |||||
| // mqtt 未加密 TCP 连接 | |||||
| // mqtts 加密 TCP 连接 | |||||
| // wxs 微信小程序连接 | |||||
| // alis 支付宝小程序连接 | |||||
| try { | try { | ||||
| this.client?.connect(this.connection as IMqttServiceOptions) | this.client?.connect(this.connection as IMqttServiceOptions) | ||||
| } catch (error) { | } catch (error) { | ||||
| console.log('mqtt.connect error', error); | console.log('mqtt.connect error', error); | ||||
| } | } | ||||
| this.client?.onConnect.subscribe(() => { | this.client?.onConnect.subscribe(() => { | ||||
| this.isConnection = true | |||||
| this.isConnection = true; | |||||
| this.statusSubject.next(this.isConnection); | |||||
| console.log('Connection succeeded!'); | console.log('Connection succeeded!'); | ||||
| }); | }); | ||||
| this.client?.onError.subscribe((error: any) => { | this.client?.onError.subscribe((error: any) => { | ||||
| this.isConnection = false | |||||
| this.isConnection = false; | |||||
| this.statusSubject.next(this.isConnection); | |||||
| console.log('Connection failed', error); | console.log('Connection failed', error); | ||||
| }); | }); | ||||
| this.client?.onMessage.subscribe((packet: any) => { | |||||
| this.receiveNews = this.receiveNews.concat(packet.payload.toString()) | |||||
| console.log(`Received message ${packet.payload.toString()} from topic ${packet.topic}`) | |||||
| }) | |||||
| // this.client?.onMessage.subscribe((packet: any) => { | |||||
| // this.receiveNews = this.receiveNews.concat(packet.payload.toString()) | |||||
| // console.log(`Received message ${packet.payload.toString()} from topic ${packet.topic}`); | |||||
| // this.messagesSubject$.next(packet); | |||||
| // }) | |||||
| } | } | ||||
| // 订阅主题 | // 订阅主题 | ||||
| doSubscribe() { | |||||
| const { topic, qos } = this.subscription | |||||
| this.curSubscription = this.client?.observe(topic, { qos } as IClientSubscribeOptions).subscribe((message: IMqttMessage) => { | |||||
| this.subscribeSuccess = true | |||||
| console.log('Subscribe to topics res', message.payload.toString()) | |||||
| }) | |||||
| getLog() { | |||||
| const { topic, qos } = { | |||||
| topic: 'isoft/node 4/log4', | |||||
| qos: 0, | |||||
| }; | |||||
| this.client?.observe(topic, { qos } as IClientSubscribeOptions).subscribe((message: IMqttMessage) => { | |||||
| try { | |||||
| console.log('Subscribe to topics res', message.payload.toString()); | |||||
| var plainMessage = ""; | |||||
| for (var i = 0; i < message.payload.length; i++) { | |||||
| plainMessage += String.fromCharCode(parseInt(String(message.payload[i]))); | |||||
| } | |||||
| this.messagesSubject$.next(JSON.parse(plainMessage)); | |||||
| }catch (e) { | |||||
| console.log(e); | |||||
| } | |||||
| }); | |||||
| } | } | ||||
| // 取消订阅 | // 取消订阅 | ||||
| doUnSubscribe() { | |||||
| clearLog() { | |||||
| this.curSubscription?.unsubscribe() | this.curSubscription?.unsubscribe() | ||||
| this.subscribeSuccess = false | |||||
| } | } | ||||
| // 发送消息 | // 发送消息 | ||||
| doPublish() { | |||||
| const { topic, qos, payload } = this.publish | |||||
| console.log(this.publish) | |||||
| this.client?.unsafePublish(topic, payload, {qos} as IPublishOptions) | |||||
| doPublish(data: any) { | |||||
| this.client?.unsafePublish("isoft/node 4/in4", JSON.stringify(data), {qos: 0} as IPublishOptions); | |||||
| } | |||||
| // 发送消息 | |||||
| sendPublish(data: any) { | |||||
| this.client?.unsafePublish("isoft/node 4/in4", JSON.stringify(data), {qos: 0} as IPublishOptions); | |||||
| } | } | ||||
| // 断开连接 | // 断开连接 | ||||
| destroyConnection() { | destroyConnection() { |