| "@asymmetrik/ngx-leaflet-markercluster": "^16.0.0", | "@asymmetrik/ngx-leaflet-markercluster": "^16.0.0", | ||||
| "leaflet": "^1.9.4", | "leaflet": "^1.9.4", | ||||
| "rxjs": "~7.8.0", | "rxjs": "~7.8.0", | ||||
| "rxjs-websockets": "^9.0.0", | |||||
| "tslib": "^2.3.0", | "tslib": "^2.3.0", | ||||
| "zone.js": "~0.13.0" | "zone.js": "~0.13.0" | ||||
| }, | }, |
| </div> | </div> | ||||
| </div> | </div> | ||||
| <div class="topnav"> | |||||
| <h1>Test Socket</h1> | |||||
| </div> | |||||
| <div class="content"> | |||||
| <div class="card-grid"> | |||||
| <div class="card"> | |||||
| <p>Connect</p> | |||||
| <p class="state"><span id="Connect">{{ isConnected ? 'Online' : 'Offline' }}</span></p> | |||||
| </div> | |||||
| <div class="card"> | |||||
| <p class="state" id="State1">{{ State1 == '' ? '%STATE%' : State1}}</p> | |||||
| <p class="state" id="State2">{{ State2 == '' ? '%STATE%' : State2}}</p> | |||||
| <p class="state" id="State3">{{ State3 == '' ? '%STATE%' : State3}}</p> | |||||
| <p class="state" id="State4">{{ State4 == '' ? '%STATE%' : State4}}</p> | |||||
| <p class="state" id="State5">{{ State5 == '' ? '%STATE%' : State5}}</p> | |||||
| <p class="state" id="State6">{{ State6 == '' ? '%STATE%' : State6}}</p> | |||||
| <p><button (click)="toggleState1()" id="SetState1" class="button">Set State 1 On</button></p> | |||||
| <p><button (click)="toggleState2()" id="SetState2" class="button">Set State 2 On</button></p> | |||||
| </div> | |||||
| </div> | |||||
| </div> |
| background-color: green !important; | background-color: green !important; | ||||
| color: white !important; | color: white !important; | ||||
| } | } | ||||
| h1 { | |||||
| font-size: 1.8rem; | |||||
| color: white; | |||||
| } | |||||
| .topnav { | |||||
| overflow: hidden; | |||||
| background-color: #0A1128; | |||||
| } | |||||
| body { | |||||
| margin: 0; | |||||
| } | |||||
| p { | |||||
| text-align: center; | |||||
| } | |||||
| .content { | |||||
| padding: 50px; | |||||
| } | |||||
| .card-grid { | |||||
| max-width: 800px; | |||||
| margin: 0 auto; | |||||
| display: grid; | |||||
| grid-gap: 2rem; | |||||
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |||||
| } | |||||
| .card { | |||||
| background-color: white; | |||||
| box-shadow: 2px 2px 12px 1px rgba(140, 140, 140, .5); | |||||
| } | |||||
| .card-title { | |||||
| font-size: 1.2rem; | |||||
| font-weight: bold; | |||||
| color: #034078 | |||||
| } | |||||
| .reading { | |||||
| font-size: 1.2rem; | |||||
| color: #1282A2; | |||||
| } | |||||
| .button { | |||||
| padding: 15px 50px; | |||||
| font-size: 24px; | |||||
| text-align: center; | |||||
| outline: none; | |||||
| color: #fff; | |||||
| background-color: #0f8b8d; | |||||
| border: none; | |||||
| border-radius: 5px; | |||||
| -webkit-touch-callout: none; | |||||
| -webkit-user-select: none; | |||||
| -khtml-user-select: none; | |||||
| -moz-user-select: none; | |||||
| -ms-user-select: none; | |||||
| user-select: none; | |||||
| -webkit-tap-highlight-color: rgba(0, 0, 0, 0); | |||||
| } | |||||
| /*.button:hover {background-color: #0f8b8d}*/ | |||||
| .button:active { | |||||
| background-color: #0f8b8d; | |||||
| box-shadow: 2 2px #CDCDCD; | |||||
| transform: translateY(2px); | |||||
| } | |||||
| .state { | |||||
| font-size: 1.5rem; | |||||
| color: #8c8c8c; | |||||
| font-weight: bold; | |||||
| text-align: center; | |||||
| } | |||||
| .content { | |||||
| padding: 30px; | |||||
| max-width: 600px; | |||||
| margin: 0 auto; | |||||
| } | |||||
| .card { | |||||
| background-color: #F8F7F9;; | |||||
| box-shadow: 2px 2px 12px 1px rgba(140, 140, 140, .5); | |||||
| padding-top: 10px; | |||||
| padding-bottom: 20px; | |||||
| } |
| import { Component } from '@angular/core'; | |||||
| import {Component, OnDestroy, OnInit} from '@angular/core'; | |||||
| import {SocketService} from "../../../shared/services/socket.service"; | |||||
| @Component({ | @Component({ | ||||
| selector: 'app-overall-ground', | selector: 'app-overall-ground', | ||||
| templateUrl: './overall-ground.component.html', | templateUrl: './overall-ground.component.html', | ||||
| styleUrls: ['./overall-ground.component.scss'] | styleUrls: ['./overall-ground.component.scss'] | ||||
| }) | }) | ||||
| export class OverallGroundComponent { | |||||
| export class OverallGroundComponent implements OnInit, OnDestroy{ | |||||
| isClicked = false; | isClicked = false; | ||||
| isConnected: boolean = false; | |||||
| State1: string = ''; | |||||
| State2: string = ''; | |||||
| State3: string = ''; | |||||
| State4: string = ''; | |||||
| State5: string = ''; | |||||
| State6: string = ''; | |||||
| constructor(private socketService$: SocketService) { | |||||
| } | |||||
| ngOnInit() { | |||||
| this.socketService$.connect(); | |||||
| this.isConnected = this.socketService$.getStatus(); | |||||
| if(this.isConnected){ | |||||
| this.socketService$.messages$.subscribe(message => { | |||||
| this.onMessage(message); | |||||
| }); | |||||
| } | |||||
| } | |||||
| toggleColor(): void { | toggleColor(): void { | ||||
| this.isClicked = !this.isClicked; | this.isClicked = !this.isClicked; | ||||
| } | } | ||||
| ngOnDestroy(): void { | |||||
| this.socketService$.close(); | |||||
| } | |||||
| toggleState1() { | |||||
| this.socketService$.sendMessage({ id: '0', type: 'cmd', state1: !this.State1 }); | |||||
| } | |||||
| toggleState2() { | |||||
| this.socketService$.sendMessage({ id: '0', type: 'cmd', state2: !this.State2 }); | |||||
| } | |||||
| onMessage(message: any) { | |||||
| if (message.id === '0' && message.type === 'get') { | |||||
| this.State1 = message.state1 === '1' ? 'ON' : 'OFF'; | |||||
| this.State2 = message.state2 === '1' ? 'ON' : 'OFF'; | |||||
| this.State3 = message.state3 === '1' ? 'ON' : 'OFF'; | |||||
| this.State4 = message.state4 === '1' ? 'ON' : 'OFF'; | |||||
| this.State5 = message.state5 === '1' ? 'ON' : 'OFF'; | |||||
| this.State6 = message.state6 === '1' ? 'ON' : 'OFF'; | |||||
| } | |||||
| } | |||||
| } | } |
| import { Injectable } from '@angular/core'; | |||||
| import { webSocket, WebSocketSubject } from 'rxjs/webSocket'; | |||||
| import {catchError, delayWhen, Observable, retryWhen, Subject, tap, timer} from "rxjs"; | |||||
| @Injectable({ | |||||
| providedIn: 'root' | |||||
| }) | |||||
| export class SocketService { | |||||
| gateway = 'ws://192.168.2.45/ws'; | |||||
| websocket$!: WebSocketSubject<any> ; | |||||
| private isConnected: boolean = false; | |||||
| private messagesSubject$ = new Subject(); | |||||
| public messages$ = this.messagesSubject$.asObservable(); | |||||
| constructor() { | |||||
| } | |||||
| public connect(cfg: { reconnect: boolean } = {reconnect: false}): void { | |||||
| if (!this.websocket$ || this.websocket$.closed) { | |||||
| console.log('Trying to open a WebSocket connection…'); | |||||
| this.websocket$ = this.getNewWebSocket(); | |||||
| this.websocket$.subscribe((messages) => { | |||||
| this.messagesSubject$.next(messages); | |||||
| }); | |||||
| } | |||||
| } | |||||
| getStatus(): boolean { | |||||
| return this.isConnected; | |||||
| } | |||||
| close() { | |||||
| this.websocket$.complete(); | |||||
| } | |||||
| sendMessage(msg: any) { | |||||
| this.websocket$.next(msg); | |||||
| } | |||||
| private getNewWebSocket() { | |||||
| return webSocket({ | |||||
| url: this.gateway, | |||||
| openObserver: { | |||||
| next: () => { | |||||
| console.log('Connection ok'); | |||||
| this.isConnected = true; | |||||
| } | |||||
| }, | |||||
| closeObserver: { | |||||
| next: () => { | |||||
| console.log('Connection closed'); | |||||
| this.isConnected = false; | |||||
| this.connect({reconnect: true}); | |||||
| } | |||||
| }, | |||||
| }); | |||||
| } | |||||
| } |
| import { NgModule } from "@angular/core"; | import { NgModule } from "@angular/core"; | ||||
| import { FlexLayoutModule } from "@angular/flex-layout"; | import { FlexLayoutModule } from "@angular/flex-layout"; | ||||
| import {MatButtonModule} from "@angular/material/button"; | |||||
| import { MatButtonModule } from "@angular/material/button"; | |||||
| @NgModule({ | @NgModule({ | ||||
| exports: [ | exports: [ |