UNPKG

lavva.exalushome

Version:

Library implementing communication and abstraction layers for ExalusHome system

1,034 lines 56.6 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 { Api } from "../../Api"; import { DataFrame, Method, Status } from "../../DataFrame"; import { DependencyContainer } from "../../DependencyContainer"; import { Guid } from "../../Guid"; import { Helpers } from "../../Helpers"; import { ControllerConfigurationService } from "../Controller/ControllerConfigurationService"; import { GeolocationService } from "../Controller/GeolocationService"; import { Coordinates, CoordinatesWithSourceInfo } from "../Controller/IGeolocationService"; import { DevicesService } from "../Devices/DevicesService"; import { DeviceResponseType, DeviceTaskType } from "../Devices/IDevice"; import { DeviceState, EnergyMeasurementParameter, StateReliability } from "../Devices/IDeviceState"; import { DeviceControlFeature } from "../Devices/IDeviceTask"; import { DeviceTaskExecutionResult } from "../Devices/TaskExecutionResult"; import { DeviceTask } from "../Devices/Tasks/DeviceTask"; import { ChangeGatePositionPulse, ChangeGatewayPositionPulse, FacadeActionEnum, GetDeviceState, GetFacadeType, IdentifyDevice, LightRGBW, SetBlindMicroventilation, SetBlindOpenCloseTime, SetBlindPosition, SetBlindPositionSimple, SetFacadePosition, SetGatePositionPrecise, SetLightBrightness, SetLightBrightnessDynamicly, SetLightColor, SetLightTemperature, SetTemperature, ToggleState, TurnOff, TurnOn, TurnOnWithTime } from "../Devices/Tasks/Tasks"; import { ExalusConnectionService } from "../ExalusConnectionService"; import { ResponseResult } from "../FieldChangeResult"; import { UpdatesProvider } from "../Updates/UpdatesProvider"; import { ScenesServiceErrorCode } from "./IScenesService"; import { DeviceStateArgument, DeviceStateComparisonMethod, DeviceStateComparisonParams, NumberParam, TimeSpanParam } from "./LeftArgumentTypes"; import { ArgumentType, ConditionsTypes, HandledType, UnsupportedScenesDeviceState, DeviceStateType, SceneTaskTypeNum, SceneTaskType, SupportedTaskTypes } from "./Scenes"; import { SequenceBuilder, SequenceRequestData } from "./ScenesBuilder"; /** * @type Class */ export class ScenesService { constructor() { this._connection = Api.Get(ExalusConnectionService.ServiceName); this._configurationService = Api.Get(ControllerConfigurationService.ServiceName); } GetServiceName() { return ScenesService.ServiceName; } GetSequencesListAsync() { return __awaiter(this, void 0, void 0, function* () { var _a, _b; const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new GetSequencesListRequest(), 12000, false)); (_b = DependencyContainer.Log) === null || _b === void 0 ? void 0 : _b.Debug(`GetSequencesListAsync result:\n ${JSON.stringify(result)}}`); if (result == null) return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot get sequences list - response is null.`); if (result.Status != Status.OK) return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot get sequences list - controller responded with response code ${result.Status}.`); if (result.Data == null) return new ResponseResult(ScenesServiceErrorCode.NoData, `Cannot get sequences list - controller responded with status OK, but response does not contain data!`); return result.Data; }); } GetSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a; let sequenceGuid = ""; if (typeof sequence == 'string') { sequenceGuid = sequence; } else { sequenceGuid = sequence.Guid; } const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new GetSequenceDetailsRequest(sequenceGuid), 12000, false)); if (result == null) return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot get sequence - response is null.`); if (result.Status != Status.OK) return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot get sequence - controller responded with response code ${result.Status}.`); if (result.Data == null) return new ResponseResult(ScenesServiceErrorCode.NoData, `Cannot get sequence - controller responded with status OK, but response does not contain data!`); const raw = result.Data; let tmp = this.MapSequence(raw); if (typeof sequence == 'string') { let sl = yield this.GetSequencesListAsync(); if (sl instanceof ResponseResult) { let dat = sl; console.warn(`Cannot get sequence - response is null. Error: ${dat.Data} ${dat.Type}`); } else { const seq = sl.find(s => s.Guid == sequenceGuid); if (!seq) return new ResponseResult(ScenesServiceErrorCode.NoData, `Cannot get sequence - controller responded with status OK, but response does not contain data!`); else { tmp.IsDisabled = seq.IsDisabled; } } } else { const sequenceInfo = raw; tmp.IsDisabled = sequenceInfo.IsDisabled; } return tmp; }); } GetSequenceBuilder(newSequenceName, newSequenceIcon) { return new SequenceBuilder(newSequenceName, newSequenceIcon); } CreateSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a, _b, _c, _d; try { yield this._configurationService.EnterConfigurationModeAsync(); (_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Debug(`Creating sequence ${sequence.Name} json: \n${JSON.stringify(sequence)}`); const result = yield ((_b = this._connection) === null || _b === void 0 ? void 0 : _b.SendAndWaitForResponseAsync(new CreateSequenceRequest(sequence), 20000, false)); if (result == null || result.Status == null) return Status.Error; return result.Status; } catch (error) { (_c = DependencyContainer.Log) === null || _c === void 0 ? void 0 : _c.Error(`Creating sequence ${sequence.Name} error: ${error}`); return Status.FatalError; } finally { (_d = DependencyContainer.Log) === null || _d === void 0 ? void 0 : _d.Error(ScenesService.ServiceName, `EXIT CONFIGURATION MODE WILL BE FIRED! CreateSequenceAsync()`); yield this._configurationService.ExitConfigurationModeAsync(); yield Api.Get(DevicesService.ServiceName).GetDevicesAsync(true); } }); } CheckIfSequenceIsUsedInAnotherSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a; try { let sequenceGuid = ""; if (typeof sequence == 'string') { sequenceGuid = sequence; } else { sequenceGuid = sequence.Guid; } const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new GetSequenceUsedInRequest(sequenceGuid), 12000, false)); if (result == null) return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot get sequence - response is null.`); switch (result.Status) { case Status.WrongData: return new ResponseResult(ScenesServiceErrorCode.InvalidSceneGuid, `Cannot check if sequence is used in another sequence! Sequence not found, invalid sequence guid!`); case Status.OK: if (result.Data == null) return new ResponseResult(ScenesServiceErrorCode.NoData, `Cannot get sequence - controller responded with status OK, but response does not contain data!`); else return result.Data; default: return new ResponseResult(ScenesServiceErrorCode.OtherError, `Cannot check if sequence is used in another sequence! Controller responded with code: ${result.Status}`); } } catch (error) { return new ResponseResult(ScenesServiceErrorCode.FatalError, `Cannot check if sequence is used in another sequence! Fatal error! ${error}`); } }); } DeleteSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a; try { let sequenceGuid = ""; if (typeof sequence == 'string') { sequenceGuid = sequence; } else { sequenceGuid = sequence.Guid; } yield this._configurationService.EnterConfigurationModeAsync(); const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new DeleteSequenceRequest(sequenceGuid), 12000, false)); if (result == null || result.Status == null) return Status.Error; return result.Status; } catch (error) { return Status.FatalError; } finally { yield this._configurationService.ExitConfigurationModeAsync(); yield Api.Get(DevicesService.ServiceName).GetDevicesAsync(true); } }); } EditSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a, _b; try { const request = { Guid: sequence.Guid, Icon: sequence.Icon, Name: sequence.Name, Condition: sequence }; // fix for a bug var tmp = request.Condition.IsDisabled; request.Condition.IsDisabled = false; // / yield this._configurationService.EnterConfigurationModeAsync(); const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new EditSequenceRequest(request), 20000, false)); // fix for a bug request.Condition.IsDisabled = tmp; // / if (result == null || result.Status == null) return Status.Error; return result.Status; } catch (error) { (_b = DependencyContainer.Log) === null || _b === void 0 ? void 0 : _b.Error(`Editing sequence ${sequence.Name} error: ${error}`); return Status.FatalError; } finally { yield this._configurationService.ExitConfigurationModeAsync(); yield Api.Get(DevicesService.ServiceName).GetDevicesAsync(true); } }); } EnableSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a; let sequenceGuid = ""; if (typeof sequence == 'string') { sequenceGuid = sequence; } else { sequenceGuid = sequence.Guid; } const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new EnableSequenceRequest(sequenceGuid), 12000, false)); yield this._configurationService.ExitConfigurationModeAsync(); if (result == null || result.Status == null) return Status.Error; return result.Status; }); } DisableSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { var _a; let sequenceGuid = ""; if (typeof sequence == 'string') { sequenceGuid = sequence; } else { sequenceGuid = sequence.Guid; } const result = yield ((_a = this._connection) === null || _a === void 0 ? void 0 : _a.SendAndWaitForResponseAsync(new DisableSequenceRequest(sequenceGuid), 12000, false)); yield this._configurationService.ExitConfigurationModeAsync(); if (result == null || result.Status == null) return Status.Error; return result.Status; }); } RunSequenceAsync(sequence) { return __awaiter(this, void 0, void 0, function* () { let sequenceDeviceGuid = ""; if (typeof sequence == 'string') { const res = yield this.GetSequencesListAsync(); if (res.Type != null) return Status.Error; else { const seq = res.find(s => s.Guid == sequence); if (!seq) return Status.Error; sequenceDeviceGuid = seq.DeviceGuid; } } else { sequenceDeviceGuid = sequence.DeviceGuid; } const tsk = new TurnOn(); tsk.Channel = 1; tsk.DeviceGuid = sequenceDeviceGuid; const result = yield Api.Get(DevicesService.ServiceName).ExecuteDeviceTaskAsync({ Guid: sequenceDeviceGuid }, tsk); switch (result) { case DeviceTaskExecutionResult.Executed: return Status.OK; case DeviceTaskExecutionResult.DeviceNotFound: return Status.WrongData; default: return Status.Error; } }); } GetUtilsAsync() { return __awaiter(this, void 0, void 0, function* () { const astronomicalClockSunCalc = yield this.SunCalculatorAsync(); return { GetSunRiseTime: astronomicalClockSunCalc.GetSunRiseTime, GetSunSetTime: astronomicalClockSunCalc.GetSunSetTime, ParseLinearScaleToLux: this._parseLinearScaleToLux, ParseLuxToLinearScale: this._parseLuxToLinearScale, }; }); } _parseLinearScaleToLux(linearScaleVal) { if (linearScaleVal < 0.0 || linearScaleVal > 1.0) return undefined; return Math.round(Math.pow(10, (linearScaleVal * 5))); } _parseLuxToLinearScale(lux) { if (lux <= 0) return 0; const res = (Math.log10(lux) / 5.0); return res > 1.0 ? 1 : res; } SunCalculatorAsync() { return __awaiter(this, void 0, void 0, function* () { var _a; const srv = Api.Get(GeolocationService.ServiceName); const cords = new Coordinates(); let recalculationDone = false; cords.Latitude = 49.9958888026741; cords.Longitude = 18.9172596008914; try { if (yield srv.IsControllerGeolocationSetAsync()) { const controlerCords = yield srv.GetControlllerGeolocationAsync(); if (controlerCords instanceof CoordinatesWithSourceInfo) { cords.Latitude = controlerCords.Latitude; cords.Longitude = controlerCords.Longitude; } } } catch (error) { (_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Warning(`Cannot get localization data, using default values: 49.9958888026741, 18.9172596008914. Error: ${error}`); } const hasDST = (date = new Date()) => { const january = new Date(date.getFullYear(), 0, 1).getTimezoneOffset(); const july = new Date(date.getFullYear(), 6, 1).getTimezoneOffset(); return Math.max(january, july) !== date.getTimezoneOffset(); }; const calculateDifferenceSunAndLocalTime = (dayNumberOfDateTime) => { const ellipticalOrbitPart1 = 7.95204 * Math.sin((0.01768 * dayNumberOfDateTime) + 3.03217); const ellipticalOrbitPart2 = 9.98906 * Math.sin((0.03383 * dayNumberOfDateTime) + 3.46870); let differenceSunAndLocalTime = ellipticalOrbitPart1 + ellipticalOrbitPart2 + (cords.Longitude - Math.round(cords.Longitude / 15) * 15) * 4; if (hasDST()) differenceSunAndLocalTime -= 60; return differenceSunAndLocalTime; }; const calculateDeclination = (numberOfDaysSinceFirstOfJanuary) => { return Math.asin(-0.39795 * Math.cos(2.0 * Math.PI * (numberOfDaysSinceFirstOfJanuary + 10.0) / 365.0)); }; const calculateTanSunPosition = (declanationOfTheSun) => { const limitTanSunPosition = (tanSunPosition) => { if (tanSunPosition < -1) tanSunPosition = -1.0; if (tanSunPosition > 1) tanSunPosition = 1.0; return tanSunPosition; }; const latitudeRadians = cords.Latitude * Math.PI / 180; const sinSunPosition = Math.sin(latitudeRadians) * Math.sin(declanationOfTheSun); const cosSunPosition = Math.cos(latitudeRadians) * Math.cos(declanationOfTheSun); let tanSunPosition = sinSunPosition / cosSunPosition; tanSunPosition = limitTanSunPosition(tanSunPosition); return tanSunPosition; }; const calculateSunRiseInternal = (tanSunPosition, differenceSunAndLocalTime) => { let sunRise = (720.0 - 720.0 / Math.PI * Math.acos(-tanSunPosition) - differenceSunAndLocalTime); if (sunRise < 0) sunRise += 1440; return sunRise; }; const calculateSunSetInternal = (tanSunPosition, differenceSunAndLocalTime) => { let sunSet = (720.0 + 720.0 / Math.PI * Math.acos(-tanSunPosition) - differenceSunAndLocalTime); if (sunSet > 1439) sunSet -= 1439; return sunSet; }; const createDateTime = (timeInMinutes) => { const hour = Math.ceil(timeInMinutes / 60); const minute = timeInMinutes - (hour * 60); const now = new Date(); return new Date(now.getFullYear(), now.getMonth(), now.getDate(), hour, minute); }; const calclateSunRise = (offset) => { const dat = new Date(); dat.setDate(dat.getDate() + offset); const calculateDayOfYear = (date) => Math.floor((date.valueOf() - new Date(date.getFullYear(), 0, 0).valueOf()) / 1000 / 60 / 60 / 24); const dayNumberOfDateTime = calculateDayOfYear(dat); const differenceSunAndLocalTime = calculateDifferenceSunAndLocalTime(dayNumberOfDateTime); const declanationOfTheSun = calculateDeclination(dayNumberOfDateTime); const tanSunPosition = calculateTanSunPosition(declanationOfTheSun); const sunRiseInMinutes = calculateSunRiseInternal(tanSunPosition, differenceSunAndLocalTime); const result = createDateTime(sunRiseInMinutes); if (new Date() > result && !recalculationDone) { recalculationDone = true; return calclateSunRise(1); } else { recalculationDone = false; return new Date(dat.getFullYear(), dat.getMonth(), dat.getDate(), result.getHours(), result.getMinutes()); } }; const calculateSunSet = (offset) => { const dat = new Date(); dat.setDate(dat.getDate() + offset); const calculateDayOfYear = (date) => Math.floor((date.valueOf() - new Date(date.getFullYear(), 0, 0).valueOf()) / 1000 / 60 / 60 / 24); const dayNumberOfDateTime = calculateDayOfYear(dat); const differenceSunAndLocalTime = calculateDifferenceSunAndLocalTime(dayNumberOfDateTime); const declanationOfTheSun = calculateDeclination(dayNumberOfDateTime); const tanSunPosition = calculateTanSunPosition(declanationOfTheSun); const sunRiseInMinutes = Math.floor(calculateSunSetInternal(tanSunPosition, differenceSunAndLocalTime)); const result = createDateTime(sunRiseInMinutes); if (new Date() > result && !recalculationDone) { recalculationDone = true; return calculateSunSet(1); } else { recalculationDone = false; return new Date(dat.getFullYear(), dat.getMonth(), dat.getDate(), result.getHours(), result.getMinutes()); } }; return { GetSunRiseTime: () => calclateSunRise(0), GetSunSetTime: () => calculateSunSet(0) }; }); } MapSequence(rawSequenceResponse, ignoreRightArgument = false) { //Copy all values that are unchanged between raw and typed Sequence object const data = Object.assign({}, rawSequenceResponse); //Create temporary task guid - it allows to remove single task in builder, task guids are not supported by backend so it exists only in library //Here we also here handle task backward compatibility issue - remap DeviceTasks to ControllerTasks const findLastRightArgumentAndRefactorTasks = (rawSequence) => { //Last arg if (rawSequence.RightArgumentType == ArgumentTypeNum.Null) { //Remap DeviceTasks to ControllerTasks - this code coud be removed in future if (!Object.hasOwn(rawSequence.Tasks, "ControllerTasks") && Object.hasOwn(rawSequence.Tasks, "DevicesTasks")) { delete Object.assign(rawSequence.Tasks, { ["ControllerTasks"]: rawSequence.Tasks["DevicesTasks"] })["DevicesTasks"]; rawSequence.Tasks.ControllerTasks.map((t) => { t.TaskType = SceneTaskTypeNum.DeviceTask; t.RunParallel = false; }); } //Generate task guids if not exists //Task guids are implemented from software 2.9.6.5 so we need to generate them for older SW. if (rawSequence.Tasks.ControllerTasks != undefined) { rawSequence.Tasks.ControllerTasks.map((t) => { if ((t === null || t === void 0 ? void 0 : t.Guid) == null) { t.Guid = Guid.NewGuid(); } }); } } else { if (!Object.hasOwn(rawSequence.Tasks, "ControllerTasks") && Object.hasOwn(rawSequence.Tasks, "DevicesTasks")) { delete Object.assign(rawSequence.Tasks, { ["ControllerTasks"]: rawSequence.Tasks["DevicesTasks"] })["DevicesTasks"]; } return findLastRightArgumentAndRefactorTasks(rawSequence.RightArgument); } }; findLastRightArgumentAndRefactorTasks(rawSequenceResponse); data._rawRequestData = JSON.parse(JSON.stringify(rawSequenceResponse)); //Preform mappings for correct types if (!ignoreRightArgument) { data.RightArgumentType = this.MapArgumentType(rawSequenceResponse.RightArgumentType); data.RightArgument = this.MapRightArgument(rawSequenceResponse.RightArgument, data.RightArgumentType); } else { data.RightArgument = null; data.RightArgumentType = ArgumentType.Null; } data.LeftArgumentType = this.MapArgumentType(rawSequenceResponse.LeftArgumentType); data.LeftArgument = this.MapLeftArgument(rawSequenceResponse.LeftArgument, data.LeftArgumentType); data.Tasks.ControllerTasks = this.MapControllerTasks(rawSequenceResponse.Tasks.ControllerTasks); if (data.DoesHaveTriggers === undefined) { data.DoesHaveTriggers = data.LeftArgumentType == ArgumentType.Null; } return data; } /** * Functions map all nested right arguments recursively * @param arg * @returns */ MapRightArgument(arg, argType) { if (arg.HandledType == 0) return arg; arg.LeftArgumentType = this.MapArgumentType(arg.LeftArgumentType); arg.LeftArgument = this.MapLeftArgument(arg.LeftArgument, arg.LeftArgumentType); arg.Tasks.ControllerTasks = this.MapControllerTasks(arg.Tasks.ControllerTasks); //Remove old taks if exists if (Object.hasOwn(arg.Tasks, "DevicesTasks")) delete arg.Tasks["DevicesTasks"]; switch (argType) { case ArgumentType.Condition: arg.RightArgumentType = this.MapArgumentType(arg.RightArgumentType); arg.RightArgument = this.MapRightArgument(arg.RightArgument, arg.RightArgumentType); } return arg; } /** * Function maps raw LeftArgument JSON to object-key typed parameters property * @param arg * @returns */ MapLeftArgument(arg, argType) { let result = new LeftArgument(); result.HandledType = arg.HandledType; switch (argType) { case ArgumentType.ArgumentAsAstronomicalClock: { result.Argument.ArgumentAsAstronomicalClock = { Position: arg.Argument }; break; } case ArgumentType.ArgumentAsAstronomicalClockWithOffset: { result.Argument.ArgumentAsAstronomicalClockWithOffset = { Offset: arg.Argument.Offset, Position: arg.Argument.Position }; break; } case ArgumentType.ArgumentAsBoolean: { result.Argument.ArgumentAsBoolean = arg.Argument; break; } case ArgumentType.ArgumentAsDayOfWeek: { result.Argument.ArgumentAsDayOfWeek = arg.Argument; break; } case ArgumentType.ArgumentAsDaysOfWeek: { result.Argument.ArgumentAsDaysOfWeek = arg.Argument; break; } case ArgumentType.ArgumentAsInt: { result.Argument.ArgumentAsInt = arg.Argument; break; } case ArgumentType.ArgumentAsTimeout: { result.Argument.ArgumentAsTimeout = arg.Argument; break; } case ArgumentType.ArgumentAsTimeSpan: { result.Argument.ArgumentAsTimeSpan = { days: arg.Argument.days, hours: arg.Argument.hours, minutes: arg.Argument.minutes, seconds: arg.Argument.seconds }; break; } case ArgumentType.ArgumentAsTime: { result.Argument.ArgumentAsTime = { Hour: arg.Argument.Hour, Minute: arg.Argument.Minute, Second: arg.Argument.Second }; break; } case ArgumentType.ArgumentAsDeviceState: { const devStateArg = new DeviceStateArgument(); devStateArg.Type = this.MapDeviceStateTypeToResponseType(arg.Argument.DeviceStateType); devStateArg.SetCheckDeviceState(this.CreateDeviceState(arg.Argument.CheckedDeviceState, arg.Argument.Channel, devStateArg.Type)); devStateArg.DeviceGuid = arg.Argument.DeviceGuid; devStateArg.ComparisonMethod = arg.Argument.ComparisonMethod == undefined ? DeviceStateComparisonMethod.Default : arg.Argument.ComparisonMethod; if (arg.Argument.ComparisonParams != null) { Object.entries(arg.Argument.ComparisonParams).forEach(k => { switch (k[0]) { case "DeltaValue": case "StateRepeatCount": devStateArg.SetComparisonParam(DeviceStateComparisonParams[k[0]], new NumberParam(k[1])); break; case "DeltaCalculationTimeRange": case "StateRepeatTimeRange": devStateArg.SetComparisonParam(DeviceStateComparisonParams[k[0]], new TimeSpanParam(k[1])); break; } }); } result.Argument.ArgumentAsDeviceState = devStateArg; break; } case ArgumentType.ArgumentAsConditionInfo: { result.Argument.ArgumentAsConditionInfo = { DeviceGuid: arg.Argument.DeviceGuid }; break; } } return result; } /** * Function changes numeric based enum to string based enum, string enum is more user frienldy and is used for key of left argument typed property * @param argumentType * @returns */ MapArgumentType(argumentType) { return ArgumentType[ArgumentTypeNum[argumentType]]; } /** * Maps types of device state from Scenes extension state enum to general device states enum in library * @param stateType * @returns */ MapDeviceStateTypeToResponseType(stateType) { switch (stateType) { case DeviceStateType.BatteryState: return DeviceResponseType.BatteryState; case DeviceStateType.BinarySensor: return DeviceResponseType.BinarySensorState; case DeviceStateType.BlindPosition: return DeviceResponseType.BlindPosition; case DeviceStateType.Brightness: return DeviceResponseType.MeasuredBrightness; case DeviceStateType.ButtonState: return DeviceResponseType.RemoteButtonState; case DeviceStateType.ChannelOnOff: return DeviceResponseType.ChannelOnOffState; case DeviceStateType.DoorBell: return DeviceResponseType.DoorBellState; case DeviceStateType.Energy: return DeviceResponseType.MeasuredEnergy; case DeviceStateType.FloodSensor: return DeviceResponseType.FloodSensorState; case DeviceStateType.GatePosition: return DeviceResponseType.GatePosition; //case DeviceStateType.HeatSensor: // return DeviceResponseType. case DeviceStateType.LightBrightness: return DeviceResponseType.LightBrightness; case DeviceStateType.LightColor: return DeviceResponseType.LightColor; case DeviceStateType.LightTemperature: return DeviceResponseType.LightWarmth; //case DeviceStateType.MeasuredCurrent: // return DeviceResponseType. //case DeviceStateType.MeasuredPower: // return DeviceResponseType // case DeviceStateType.MeasuredVoltage: // return DeviceResponseType. case DeviceStateType.ReedState: return DeviceResponseType.ReedState; case DeviceStateType.SmokeSensor: return DeviceResponseType.SmokeSensorState; case DeviceStateType.Temperature: return DeviceResponseType.MeasuredTemperature; case DeviceStateType.Humidity: return DeviceResponseType.HumiditySensorState; case DeviceStateType.BlindsControlButton: return DeviceResponseType.BlindRemoteButtonState; case DeviceStateType.FacadeControlButton: return DeviceResponseType.FacadeRemoteButtonState; case DeviceStateType.Movement: return DeviceResponseType.MovementSensorState; case DeviceStateType.AirPressure: return DeviceResponseType.PressureSensorState; case DeviceStateType.WindSpeed: return DeviceResponseType.WindSpeedState; case DeviceStateType.WindThreshold: return DeviceResponseType.CurrentWindThreshold; default: return DeviceResponseType.Unknown; } } /** * Function converts device state from Scenes extension to general device states in library * @param argumentData * @param responseType * @returns */ CreateDeviceState(argumentData, channel, responseType) { switch (responseType) { case DeviceResponseType.BatteryState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Percentage: argumentData.Percentage, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.BinarySensorState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.BlindPosition: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Position: argumentData.Position, RawPosition: argumentData.RawPosition, Time: "", }; return state; } case DeviceResponseType.LightBrightness: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Brightness: argumentData.Brightness, Time: "", }; return state; } case DeviceResponseType.MeasuredBrightness: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Brightness: argumentData.Brightness, Time: "", }; return state; } case DeviceResponseType.RemoteButtonState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.ChannelOnOffState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.DoorBellState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.MeasuredEnergy: { const params = new Map(); for (let [k, v] of Object.entries(argumentData.MeasurementParameters)) params.set(EnergyMeasurementParameter[k], v); const state = { Channel: channel, StateReliability: StateReliability.Unconfident, MeasurementParameters: params, Time: "", }; return state; } case DeviceResponseType.FloodSensorState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.GatePosition: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Position: argumentData.Position, PositionType: argumentData.PositionType, Time: "", }; return state; } case DeviceResponseType.LightColor: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, R: argumentData.R, G: argumentData.G, B: argumentData.B, Time: "", }; return state; } case DeviceResponseType.LightWarmth: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Temperature: argumentData.Temperature, Time: "", }; return state; } case DeviceResponseType.ReedState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.SmokeSensorState: throw new UnsupportedScenesDeviceState("Unsupported device state!"); case DeviceResponseType.MeasuredTemperature: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Temperature: argumentData.Temperature, Time: "", Type: argumentData.Type }; return state; } case DeviceResponseType.HumiditySensorState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, Humidity: argumentData.Humidity, Time: "", Type: argumentData.Type }; return state; } case DeviceResponseType.BlindRemoteButtonState: { const state = { Channel: channel, StateReliability: StateReliability.Unconfident, State: argumentData.State, Time: "", }; return state; } case DeviceResponseType.LightRGBWState: { const state = { StateReliability: StateReliability.Unconfident, Channel: channel, Time: "", Brightness: 100, R: argumentData.R, G: argumentData.G, B: argumentData.B, W: argumentData.W, }; return state; } case DeviceResponseType.FacadeRemoteButtonState: { const state = { Channel: channel, Time: "", StateReliability: StateReliability.Unconfident, State: argumentData.State }; return state; } case DeviceResponseType.MovementSensorState: { const state = { Channel: channel, Time: "", StateReliability: StateReliability.Unconfident, Movement: argumentData.Movement, Intensity: argumentData.Intensity }; return state; } case DeviceResponseType.PressureSensorState: { const state = { Channel: channel, Time: "", StateReliability: StateReliability.Unconfident, Pressure: argumentData.Pressure, PressureType: argumentData.PressureType }; return state; } case DeviceResponseType.WindSpeedState: { const state = { Channel: channel, Time: "", StateReliability: StateReliability.Unconfident, Value: argumentData.Value }; return state; } case DeviceResponseType.CurrentWindThreshold: { const state = { Channel: channel, Time: "", StateReliability: StateReliability.Unconfident, WindThreshold: argumentData.WindThreshold }; return state; } case DeviceResponseType.Unknown: return new DeviceState(); default: throw new UnsupportedScenesDeviceState("Unsupported device state!"); } } MapDeviceTask(rawTasks) { var _a; let result = new DeviceTask(); let tsk = rawTasks; (_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Debug(`[TASK] object: ${JSON.stringify(tsk)}`); switch (tsk.ControlFeature) { case DeviceControlFeature.TurnOn: { result = new TurnOn(); result.TaskType = DeviceTaskType.TurnOn; break; } case DeviceControlFeature.TurnOff: { result = new TurnOff(); result.TaskType = DeviceTaskType.TurnOff; break; } case DeviceControlFeature.ToggleState: { result = new ToggleState(); result.TaskType = DeviceTaskType.TogleState; break; } case DeviceControlFeature.SetBlindPosition: { const dev = Api.Get(DevicesService.ServiceName).GetDevice(tsk.DeviceGuid); if (dev === null || dev === void 0 ? void 0 : dev.AvailableTaskTypes.any(a => a.InterfaceType == "IBlindPositionSimple")) { result = new SetBlindPositionSimple(); result.TaskType = DeviceTaskType.SetBlindPositionSimple; result.Action = tsk.Data.Action; } else { result = new SetBlindPosition(); result.TaskType = DeviceTaskType.SetBlindPosition; result.Action = tsk.Data.Action; result.Position = tsk.Data.Position; } break; } case DeviceControlFeature.SetLightColor: result = new SetLightColor(); result.TaskType = DeviceTaskType.SetLightColor; result.R = tsk.Data.R; result.G = tsk.Data.G; result.B = tsk.Data.B; break; case DeviceControlFeature.SetLightTemperature: result = new SetLightTemperature(); result.TaskType = DeviceTaskType.SetLightTemperature; result.Temperature = tsk.Data.Temperature; break; case DeviceControlFeature.SetLightBrightness: result = new SetLightBrightness(); result.TaskType = DeviceTaskType.SetLightBrightness; result.Brightness = tsk.Data.Brightness; break; case DeviceControlFeature.SetTemperature: result = new SetTemperature(); result.TaskType = DeviceTaskType.SetTemperature; result.Temperature = tsk.Data.Temperature; break; case DeviceControlFeature.GetState: result = new GetDeviceState(); result.TaskType = DeviceTaskType.GetChannelsState; break; case DeviceControlFeature.TurnOnWithTimeout: result = new TurnOnWithTime(); result.TaskType = DeviceTaskType.TurnOnWithTime; result.SwitchOffDelaySeconds = tsk.Data.SwitchOffDelaySeconds; break; case DeviceControlFeature.SetLightBrightnessDynamicly: result = new SetLightBrightnessDynamicly(); result.TaskType = DeviceTaskType.SetLightBrightnessDynamicly; result.Brightness = tsk.Data.Brightness; break; case DeviceControlFeature.IdentifyDevice: result = new IdentifyDevice(); result.TaskType = DeviceTaskType.IdentifyDevice; break; case DeviceControlFeature.SetBlindOpenCloseTime: result = new SetBlindOpenCloseTime(); result.TaskType = DeviceTaskType.SetBlindOpenCloseTime; result.Data.CloseTime = tsk.Data; break; case DeviceControlFeature.SetBlindMicroventilation: result = new SetBlindMicroventilation(); result.TaskType = DeviceTaskType.SetBlindMicroventilation; result.Position = tsk.Data.Position; break; case DeviceControlFeature.GatewayPulse: result = new ChangeGatewayPositionPulse(); result.TaskType = DeviceTaskType.ChangeGatewayPositionPulse; break; case DeviceControlFeature.GatePulse: result = new ChangeGatePositionPulse(); result.TaskType = DeviceTaskType.ChangeGatePositionPulse; break; case DeviceControlFeature.SetFacadePositionAndTilt: result = new SetFacadePosition(); result.TaskType = DeviceTaskType.SetFacadePosition; result.Position = tsk.Data.Position; result.Tilt = tsk.Data.Tilt; result.FacadeAction = FacadeActionEnum.TiltAndPercentage; break; case DeviceControlFeature.GetFacadeType: result = new GetFacadeType(); result.TaskType = DeviceTaskType.GetFacadeType; break; case DeviceControlFeature.LightRGBW: result = new LightRGBW(); result.TaskType = DeviceTaskType.LightRGBW; result.Data = tsk.Data; break; case DeviceControlFeature.SetGatePositionPrecise: result = new SetGatePositionPrecise(); result.TaskType = DeviceTaskType.PreciseGateControl; result.Position = tsk.Data.Position; result.GateControlAction = tsk.Data.GateControlAction; break; default: break; } result.Channel = tsk.Channel; result.DeviceGuid = tsk.DeviceGuid; result.FeatureType = tsk.ControlFeature; result.Guid = Guid.NewGuid(); return result; } MapControllerTasks(rawTasks) { var _a, _b; const result = []; (_a = DependencyContainer.Log) === null || _a === void 0 ? void 0 : _a.Debug(`[TASKS] received tasks object: ${JSON.stringify(rawTasks)}`); for (let tsk of rawTasks) { const task = new ControllerTasks(); task.Guid = tsk.Guid; task.TaskId = Helpers.GenerateMd5(JSON.stringify(tsk)); switch (tsk.TaskType) { case SceneTaskTypeNum.DeviceTask: task.TaskType = SceneTaskType.DeviceTask; task.Task.DeviceTask = this.MapDeviceTask(tsk); break; case SceneTaskTypeNum.DelayTask: task.TaskType = SceneTaskType.DelayTask; task.Task.DelayTask = { Delay: new TimeSpanParam(tsk.Delay) }; break; case SceneTaskTypeNum.NotifyTask: tas