UNPKG

lavva.exalushome

Version:

Library implementing communication and abstraction layers for ExalusHome system

587 lines 34 kB
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; import * as signalR from "@microsoft/signalr"; import { DataFrame, Method, Status } from "../DataFrame"; import { ConnectionResult, AuthorizationInfo, ConnectionState, StreamError } from "./IExalusConnectionService"; import { TypedEvent } from "../TypedEvent"; import { Api } from '../Api'; import { LoggerService } from "./Logging/LoggerService"; import { Event } from "../Event"; import { ControllerConfigurationService } from "./Controller/ControllerConfigurationService"; import { WebApiCacheService } from './WebApi/WebApiCacheService'; import { SessionService } from "./Session/SessionService"; export class ExalusConnectionService { constructor() { this._logPackets = false; this._pingInterval = 5000; this._disconnectedOnPurpose = false; this._defaultPacketsBrokerAddress = "packets-broker1.tr7.pl"; this._serversBrokerAddress = "https://servers-broker.tr7.pl"; this._serversBrokerAddressList = ["https://servers-broker.tr7.pl", "https://broker.tr7.pl"]; this._allBrokersChecked = false; this._address = "packets-broker1.tr7.pl"; this._isEstabilished = false; this._timeout = 10000; this._dataReceivedEvent = new TypedEvent(); this._pongReceivedEvent = new Event(); this._authorizationReceivedEvent = new TypedEvent(); this._registrationReceivedEvent = new TypedEvent(); this._streamStartedEvent = new TypedEvent(); this._connectionStateChangedEvent = new TypedEvent(); this._errorOccuredEvent = new TypedEvent(); this._log = Api.Get(LoggerService.ServiceName); this._controllerConfiguration = null; this._cache = null; this._session = null; this._packetsBrokerServers = ["packets-broker1.tr7.pl", "br1.tr7.pl", "br1.exala.pl"]; this._lastReceivedPacketTime = Date.now(); this._connectedAtLeastOnce = false; this._pingIntervalId = null; } SubscribeTo(resourceId, handler) { let sub = (frame) => { if (frame.Resource === resourceId) handler(frame); }; this.OnDataReceivedEvent().Subscribe(sub); return () => this.OnDataReceivedEvent().Unsubscribe(sub); } GetControllerSerialNumber() { return this._serialId; } GetControllerPin() { return this._PIN; } GetServiceName() { return ExalusConnectionService.ServiceName; } EnablePacketsLogging() { this._logPackets = true; } DisablePacketsLogging() { this._logPackets = false; } InitializeConnection() { this._controllerConfiguration = Api.Get(ControllerConfigurationService.ServiceName); this._cache = Api.Get(WebApiCacheService.ServiceName); this._session = Api.Get(SessionService.ServiceName); if (this._connection) { try { this._connection.stop(); } catch (ex) { } this._connection = undefined; } if (!this._address) throw new Error("Domain is not set"); if (!this._serialId) throw new Error("SerialId is not set"); if (!this._PIN) throw new Error("PIN is not set"); this._connection = new signalR.HubConnectionBuilder() .configureLogging(signalR.LogLevel.Debug) .withUrl(`https://${this._address}/broker`, { skipNegotiation: true, transport: signalR.HttpTransportType.WebSockets }) .build(); this._dataReceivedEvent.Subscribe((frame) => { this._lastReceivedPacketTime = Date.now(); }); this._pingIntervalId = setInterval(() => __awaiter(this, void 0, void 0, function* () { yield this.PingControllerAsync(); }), this._pingInterval); } GetAuthorizationInfo() { if (this._serialId != null && this._PIN != null) return new AuthorizationInfo(this._serialId, this._PIN); else return null; } SetServersBrokerAddress(address) { this._serversBrokerAddress = address; } SetDefaultPacketsBrokerAddress(address) { this._defaultPacketsBrokerAddress = address; this._address = address; } GetServerAddressAsync() { return __awaiter(this, void 0, void 0, function* () { try { let result = yield fetch(`${this._serversBrokerAddress}/api/connections/broker/whichserver/${this._serialId}`); //OK if (result.status === 200) { let address = yield result.text(); if (!address) { this._log.Error(ExalusConnectionService.ServiceName, `Failed to get server address, status: ${result.status}`); return null; } this._log.Debug(ExalusConnectionService.ServiceName, `Got server address: ${address}`); return address; } //Break reccurency else if (this._allBrokersChecked) { this._allBrokersChecked = false; return null; } //No content else if (result.status === 204) { this.swapBrokersAsync(false); return this.GetServerAddressAsync(); } else { this._log.Error(ExalusConnectionService.ServiceName, `Failed to get server address, status: ${result.status}`); return null; } } catch (ex) { this._log.Error(ExalusConnectionService.ServiceName, ex); return null; } }); } ConnectAsync(address) { return __awaiter(this, void 0, void 0, function* () { this._connectedAtLeastOnce = false; this._address = address; return yield this.connectAsync(); }); } AuthorizeAsync(authorizationInfo) { let timeoutTime = 2000; return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { var _a; let timeoutId = 0; let sub = (result) => { window.clearTimeout(timeoutId); this._log.Debug(ExalusConnectionService.ServiceName, `Got authorization result: ${result}`); this._connectedAtLeastOnce = true; resolve(result); }; let onTimeout = () => { window.clearTimeout(timeoutId); this._authorizationReceivedEvent.Unsubscribe(sub); resolve(false); }; timeoutId = window.setTimeout(onTimeout, timeoutTime); this._log.Debug(ExalusConnectionService.ServiceName, `Authorizing to cloud using: ${authorizationInfo.SerialNumber} PIN: ${authorizationInfo.PIN}`); this._authorizationReceivedEvent.Subscribe(sub); yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.send("AuthorizeTo", authorizationInfo.SerialNumber, authorizationInfo.PIN)); })); } ConnectAndAuthorizeAsync(authorizationInfo) { return __awaiter(this, void 0, void 0, function* () { this._connectedAtLeastOnce = false; Api.WorksInContextOf = authorizationInfo.SerialNumber; this._serialId = authorizationInfo.SerialNumber; this._PIN = authorizationInfo.PIN; var packetsBroker = yield this.GetServerAddressAsync(); if (!packetsBroker || packetsBroker == null || packetsBroker == "") { let result = ConnectionResult.ControllerIsNotConnected; this._log.Warning(ExalusConnectionService.ServiceName, `Server did not return packets broker address, trying to connect to known brokers.`); for (let server of this._packetsBrokerServers) { this._log.Warning(ExalusConnectionService.ServiceName, `Testing connection to ${server}`); this.SetDefaultPacketsBrokerAddress(server); try { if (this.IsConnected()) yield this.DisconnectAsync(); } catch (ex) { } this._log.Warning(ExalusConnectionService.ServiceName, `Connecting to server: ${server}`); let conResult = yield this.connectAsync(); this._log.Warning(ExalusConnectionService.ServiceName, `Connection result: ${conResult}`); if (conResult == ConnectionResult.Connected) if (yield this.AuthorizeAsync(authorizationInfo)) { result = ConnectionResult.Connected; this._connectedAtLeastOnce = true; return result; } else { this._log.Warning(ExalusConnectionService.ServiceName, `Failed to authorize in ${server}`); } } return result; } else { this._log.Debug(ExalusConnectionService.ServiceName, `Got packets broker address: ${packetsBroker}`); this.SetDefaultPacketsBrokerAddress(packetsBroker); let conResult = yield this.connectAsync(); if (conResult != ConnectionResult.Connected) return conResult; var authResult = yield this.AuthorizeAsync(authorizationInfo); if (!authResult) { this._connectedAtLeastOnce = false; yield this.swapBrokersAsync(); if (!this._allBrokersChecked) return this.ConnectAndAuthorizeAsync(authorizationInfo); else this._allBrokersChecked = false; } if (authResult) this._connectedAtLeastOnce = true; return authResult ? ConnectionResult.Connected : ConnectionResult.AuthorizationFailed; } }); } swapBrokersAsync() { return __awaiter(this, arguments, void 0, function* (disconnect = true) { if (disconnect) yield this.DisconnectAsync(); var intexOfLastBroker = this._serversBrokerAddressList.lastIndexOf(this._serversBrokerAddress); if (intexOfLastBroker + 1 < this._serversBrokerAddressList.length) { this._serversBrokerAddress = this._serversBrokerAddressList[intexOfLastBroker + 1]; this._log.Debug(`Changing address of next broker from: ${this._serversBrokerAddressList[intexOfLastBroker]} to: ${this._serversBrokerAddressList[intexOfLastBroker + 1]}`); } else { this._log.Debug(`All brokers checked, changing address to first one: ${this._serversBrokerAddressList[0]}`); this._allBrokersChecked = true; this._serversBrokerAddress = this._serversBrokerAddressList[0]; } }); } connectAsync() { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l; let result = ConnectionResult.FailedToConnect; if (!this._address) return Promise.resolve(ConnectionResult.ControllerIsNotConnected); if (this._disconnectedOnPurpose) { this._disconnectedOnPurpose = false; } const connectionEvent = this._connectionStateChangedEvent; this.InitializeConnection(); (_a = this._connection) === null || _a === void 0 ? void 0 : _a.onclose(() => __awaiter(this, void 0, void 0, function* () { var _a, _b; if (!this._disconnectedOnPurpose) this._log.Error(ExalusConnectionService.ServiceName, `Connection closed`); else this._log.Info(ExalusConnectionService.ServiceName, `Connection closed on demand.`); Api.Get(SessionService.ServiceName).CreateSessionCompletionSourceAsync(); this.FireConnectionStateChanged(); if (((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) !== signalR.HubConnectionState.Disconnected) return; if (this._disconnectedOnPurpose) return; yield ((_b = this._connection) === null || _b === void 0 ? void 0 : _b.start()); if (this._connection != null) { if (yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN))) { this._log.Info(ExalusConnectionService.ServiceName, `Reconnected from onClose`); return this.FireConnectionStateChanged(); } } return ConnectionResult.FailedToConnect; })); (_b = this._connection) === null || _b === void 0 ? void 0 : _b.onreconnected(() => __awaiter(this, void 0, void 0, function* () { if (yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN))) { this._log.Info(ExalusConnectionService.ServiceName, `Reconnected from onreconnected`); return this.FireConnectionStateChanged(); } })); (_c = this._connection) === null || _c === void 0 ? void 0 : _c.onreconnecting(() => { this._log.Warning(ExalusConnectionService.ServiceName, `Reconnecting...`); return this.FireConnectionStateChanged(); }); yield ((_d = this._connection) === null || _d === void 0 ? void 0 : _d.start()); (_e = this._connection) === null || _e === void 0 ? void 0 : _e.on("Pong", () => { this._log.Debug(ExalusConnectionService.ServiceName, "Pong received <-"); this._pongReceivedEvent.Invoke(); }); (_f = this._connection) === null || _f === void 0 ? void 0 : _f.on("Registration", (data) => { var _a; (_a = this._registrationReceivedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(data); }); (_g = this._connection) === null || _g === void 0 ? void 0 : _g.on("Authorization", (data) => { var _a; (_a = this._authorizationReceivedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(data); }); (_h = this._connection) === null || _h === void 0 ? void 0 : _h.on("SendError", (sender, data) => __awaiter(this, void 0, void 0, function* () { if (sender.startsWith("NotAuthorized:")) { this._log.Error(ExalusConnectionService.ServiceName, "Failed to authorize!"); yield this.AuthorizeAsync(new AuthorizationInfo(this._serialId, this._PIN)); } else { this._log.Error(ExalusConnectionService.ServiceName, `Server returned error: ${sender} ${data}`); this._errorOccuredEvent.Invoke([sender, data]); } })); (_j = this._connection) === null || _j === void 0 ? void 0 : _j.on("ControllerDisconnected", (data) => __awaiter(this, void 0, void 0, function* () { if (this._serialId === data) { this._log.Warning(ExalusConnectionService.ServiceName, `Controller disconnected: ${data}`); yield this.DisconnectAsync(); } })); (_k = this._connection) === null || _k === void 0 ? void 0 : _k.on("StreamStarted", (streamTransactionId) => { var _a; (_a = this._streamStartedEvent) === null || _a === void 0 ? void 0 : _a.Invoke(streamTransactionId); }); let dataReceivedEvent = this._dataReceivedEvent; (_l = this._connection) === null || _l === void 0 ? void 0 : _l.on("Data", (sender, data) => { const d = JSON.parse(data); if (this._logPackets || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Received data:\n${JSON.stringify(d, null, 2)}`); dataReceivedEvent.Invoke(d); }); if (this._connection != null) return this.FireConnectionStateChanged(); return ConnectionResult.FailedToConnect; }); } FireConnectionStateChanged() { var _a; const connectionEvent = this._connectionStateChangedEvent; switch ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) { case signalR.HubConnectionState.Connected: connectionEvent.Invoke(ConnectionState.Connected); return ConnectionResult.Connected; case signalR.HubConnectionState.Connecting: connectionEvent.Invoke(ConnectionState.Connecting); return ConnectionResult.Connected; case signalR.HubConnectionState.Disconnected: if (this._connectedAtLeastOnce) { connectionEvent.Invoke(ConnectionState.Disconnected); return ConnectionResult.FailedToConnect; } break; case signalR.HubConnectionState.Disconnecting: if (this._connectedAtLeastOnce) { connectionEvent.Invoke(ConnectionState.Disconnecting); return ConnectionResult.FailedToConnect; } break; case signalR.HubConnectionState.Reconnecting: connectionEvent.Invoke(ConnectionState.Reconnecting); return ConnectionResult.FailedToConnect; } return ConnectionResult.FailedToConnect; } DisconnectAsync() { return __awaiter(this, void 0, void 0, function* () { var _a; this._disconnectedOnPurpose = true; this._log.Debug(ExalusConnectionService.ServiceName, `Disconnecting from the server ${this._address}`); this._connectionStateChangedEvent.Invoke(ConnectionState.Disconnecting); if (this._pingIntervalId !== null) clearInterval(this._pingIntervalId); yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.stop()); }); } IsConnected() { var _a; return ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) === signalR.HubConnectionState.Connected; } SendAndWaitForResponseAsync(dataFrame, timeout, useCache, logTransmission = true) { return this.SendAndWaitForResponseWithRepeatAsync(dataFrame, timeout, useCache, logTransmission); } SendAndWaitForResponseWithRepeatAsync(dataFrame_1, timeout_1, useCache_1) { return __awaiter(this, arguments, void 0, function* (dataFrame, timeout, useCache, repeat = true, logTransmission = true) { var _a, _b, _c; if (dataFrame.Method === Method.Get && useCache) { if (!(yield ((_a = this._controllerConfiguration) === null || _a === void 0 ? void 0 : _a.DidCofigurationChangeAsync()))) { let res = (_b = this._cache) === null || _b === void 0 ? void 0 : _b.GetCache(dataFrame); if (res !== null) { return Promise.resolve(res); } } } let timeoutId = 0; const startTime = Date.now(); if (!this.IsConnected()) throw new Error("Connection is not established"); if (dataFrame.Resource !== "/users/user/login") yield ((_c = this._session) === null || _c === void 0 ? void 0 : _c.WaitForSessionCreationAsync()); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { let onReceivedFrame = (receivedFrame) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d; if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId) == dataFrame.TransactionId) { window.clearTimeout(timeoutId); this._dataReceivedEvent.Unsubscribe(onReceivedFrame); const difference = Date.now() - startTime; if (logTransmission) this._log.Debug(ExalusConnectionService.ServiceName, `Received response for: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Resource} ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Method} id: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId} in ${difference}ms`); if (dataFrame.Method === Method.Get && useCache) (_a = this._cache) === null || _a === void 0 ? void 0 : _a.Cache(receivedFrame); if (!useCache && (receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) === Status.UserIsNotLoggedIn && repeat) { ((_b = this._session) === null || _b === void 0 ? void 0 : _b.OnUserLoggedOutEvent()).Invoke((_c = this._session) === null || _c === void 0 ? void 0 : _c.User); yield ((_d = this._session) === null || _d === void 0 ? void 0 : _d.RestoreSessionAsync()); resolve(yield this.SendAndWaitForResponseWithRepeatAsync(dataFrame, timeout, useCache, false, logTransmission)); } resolve(receivedFrame); } }); this._dataReceivedEvent.Subscribe(onReceivedFrame); timeoutId = window.setTimeout(() => { this._dataReceivedEvent.Unsubscribe(onReceivedFrame); let errorMessage = `Response timeout, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`; this._log.Error(ExalusConnectionService.ServiceName, errorMessage); reject(new signalR.TimeoutError(errorMessage)); }, timeout); if (!(yield this.SendAsync(dataFrame, logTransmission))) { let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`; reject(new Error(errorMessage)); } })); }); } SendAndHandleResponseAsync(dataFrame_1, timeout_1, dataHandler_1) { return __awaiter(this, arguments, void 0, function* (dataFrame, timeout, dataHandler, logTransmission = true) { var _a; let timeoutId = 0; const startTime = Date.now(); if (!this.IsConnected()) throw new Error("Connection is not established"); if (dataFrame.Resource !== "/users/user/login") yield ((_a = this._session) === null || _a === void 0 ? void 0 : _a.WaitForSessionCreationAsync()); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { const enableTimeout = () => window.setTimeout(() => { this._dataReceivedEvent.Unsubscribe(onReceivedFrame); let errorMessage = `Response timeout, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`; this._log.Error(ExalusConnectionService.ServiceName, errorMessage); reject(new signalR.TimeoutError(errorMessage)); }, timeout); let onReceivedFrame = (receivedFrame) => __awaiter(this, void 0, void 0, function* () { var _a, _b, _c; if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId) == dataFrame.TransactionId) { window.clearTimeout(timeoutId); const difference = Date.now() - startTime; if (logTransmission || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Received response for: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Resource} ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Method} id: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.TransactionId} in ${difference}ms`); if ((receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) === Status.UserIsNotLoggedIn) { this._dataReceivedEvent.Unsubscribe(onReceivedFrame); ((_a = this._session) === null || _a === void 0 ? void 0 : _a.OnUserLoggedOutEvent()).Invoke((_b = this._session) === null || _b === void 0 ? void 0 : _b.User); yield ((_c = this._session) === null || _c === void 0 ? void 0 : _c.RestoreSessionAsync()); resolve(yield this.SendAndHandleResponseAsync(dataFrame, timeout, dataHandler, logTransmission)); } switch (receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status) { case Status.MultiDataResponseStart: case Status.MultiDataResponse: dataHandler(receivedFrame); timeoutId = enableTimeout(); break; case Status.MultiDataResponseStop: case Status.FatalError: case Status.Error: dataHandler(receivedFrame); this._dataReceivedEvent.Unsubscribe(onReceivedFrame); resolve(); break; default: let errorMessage = `Failed to process MultiDataResponse - recived incorrect response status: ${receivedFrame === null || receivedFrame === void 0 ? void 0 : receivedFrame.Status} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId} make sure that the requested endpoint uses MultiDataResponse, otherwise use SendAndWaitForResponseAsync<T> method.`; reject(new Error(errorMessage)); break; } } }); this._dataReceivedEvent.Subscribe(onReceivedFrame); timeoutId = enableTimeout(); if (!(yield this.SendAsync(dataFrame, logTransmission))) { let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`; reject(new Error(errorMessage)); } })); }); } SendAndHandleStreamAsync(dataFrame_1, streamHandler_1) { return __awaiter(this, arguments, void 0, function* (dataFrame, streamHandler, logTransmission = true) { var _a; let timeoutId = 0; const startTime = Date.now(); if (!this.IsConnected()) throw new Error("Connection is not established"); if (dataFrame.Resource !== "/users/user/login") yield ((_a = this._session) === null || _a === void 0 ? void 0 : _a.WaitForSessionCreationAsync()); return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { const enableTimeout = () => window.setTimeout(() => { this._streamStartedEvent.Unsubscribe(onStreamStarted); let errorMessage = `Waiting for stream timeout occurs, stream was not registered in 8000ms, make sure that method supports streaming! Resource: ${dataFrame.Resource} method: ${dataFrame.Method} stream/transaction id: ${dataFrame.TransactionId}`; this._log.Error(ExalusConnectionService.ServiceName, errorMessage); reject(new signalR.TimeoutError(errorMessage)); }, 8000); if (!(yield this.SendAsync(dataFrame, logTransmission))) { let errorMessage = `Failed to send request, resource: ${dataFrame.Resource} method: ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`; reject(new Error(errorMessage)); } let onStreamStarted = (streamTransactionId) => __awaiter(this, void 0, void 0, function* () { var _a; if (streamTransactionId == dataFrame.TransactionId) { window.clearTimeout(timeoutId); const difference = Date.now() - startTime; if (logTransmission || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Received stream registration message for stream ${streamTransactionId} in ${difference}ms`); (_a = this._connection) === null || _a === void 0 ? void 0 : _a.stream("WatchStream", dataFrame.TransactionId).subscribe({ next: (item) => { streamHandler.Next(item); if (logTransmission || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Received stream packet for stream ${streamTransactionId}`); }, complete: () => { streamHandler.Complete(); if (logTransmission || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Received stream complete message for stream ${streamTransactionId}`); resolve(); }, error: (err) => { streamHandler.Error(err); const errorMessage = `Failed to subscribe for stream: ${dataFrame.TransactionId}, error: ${err}`; reject(new StreamError(errorMessage)); }, }); } }); this._streamStartedEvent.Subscribe(onStreamStarted); timeoutId = enableTimeout(); })); }); } PingControllerAsync() { return __awaiter(this, void 0, void 0, function* () { var _a; if (((_a = this._connection) === null || _a === void 0 ? void 0 : _a.state) !== signalR.HubConnectionState.Connected) return false; if (this._lastReceivedPacketTime !== null && Date.now() - this._lastReceivedPacketTime < this._pingInterval) return false; let frame = new DataFrame(); frame.Resource = "/system/ping"; frame.Method = Method.Get; let result = yield this.SendAndWaitForResponseAsync(frame, 2000, false, false) .then(() => true) .catch(() => false); return result; }); } SendAsync(dataFrame, logTransmission = false) { if (!this.IsConnected()) throw new Error("Connection is not established"); return new Promise((resolve) => { var _a; if (this._logPackets || window["packets"] === true) this._log.Debug(ExalusConnectionService.ServiceName, `Sent DataFrame ${dataFrame.Resource} ${dataFrame.Method} transaction id: ${dataFrame.TransactionId} data:\n${JSON.stringify(dataFrame, null, 2)}`); else if (logTransmission) this._log.Debug(ExalusConnectionService.ServiceName, `Sent DataFrame ${dataFrame.Resource} ${dataFrame.Method} transaction id: ${dataFrame.TransactionId}`); (_a = this._connection) === null || _a === void 0 ? void 0 : _a.invoke("SendTo", this._serialId, dataFrame).then(() => { resolve(true); }).catch(err => { this._log.Error(ExalusConnectionService.ServiceName, `${err}`); resolve(false); }); }); } OnDataReceivedEvent() { return this._dataReceivedEvent; } OnConnectionStateChangedEvent() { return this._connectionStateChangedEvent; } OnErrorOccuredEvent() { return this._errorOccuredEvent; } } ExalusConnectionService.ServiceName = "ExalusConnectionService"; //# sourceMappingURL=ExalusConnectionService.js.map