/**
 * Minified by jsDelivr using Terser v5.39.0.
 * Original file: /npm/iobroker.iot@6.0.1/build/main.js
 *
 * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
 */
"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:!0});const aws_iot_device_sdk_1=require("aws-iot-device-sdk"),adapter_core_1=require("@iobroker/adapter-core"),node_fs_1=require("node:fs"),axios_1=__importDefault(require("axios")),node_zlib_1=require("node:zlib"),alexaSmartHomeV3_1=__importDefault(require("./lib/alexaSmartHomeV3")),alexaCustom_1=__importDefault(require("./lib/alexaCustom")),googleHome_1=__importDefault(require("./lib/googleHome")),alisa_1=__importDefault(require("./lib/alisa")),remote_1=__importDefault(require("./lib/remote")),visuApp_1=require("./lib/visuApp"),notifications_1=require("./lib/notifications"),NONE="___none___",MAX_IOT_MESSAGE_LENGTH=130048,SPECIAL_ADAPTERS=["netatmo"],ALLOWED_SERVICES=SPECIAL_ADAPTERS.concat(["text2command"]),RETRY_DELAYS_MS=[1e4,15e3,2e4,3e4,45e3],MAX_RETRY_DELAY_MS=6e4;class IotAdapter extends adapter_core_1.Adapter{recalcTimeout=null;lang="de";translate=!1;alexaSH3=null;googleHome=null;alexaCustom=null;yandexAlisa=null;remote=null;device=null;urlKey=null;connectedOwn=!1;secret="";connectStarted=0;caCert=null;validTill=null;validTillLastQuery=0;alertReported=!1;constructor(e={}){super({...e,name:"iot",objectChange:(e,t)=>{if("system.config"===e&&t&&!this.translate){const e=t;this.lang=e.common.language,"en"!==this.lang&&"de"!==this.lang&&"ru"!==this.lang&&(this.lang="en"),this.alexaSH3?.setLanguage(this.lang),this.yandexAlisa?.setLanguage(this.lang),this.alexaCustom?.setLanguage(this.lang),this.googleHome?.setLanguage(this.lang),this.remote?.setLanguage(this.lang)}if(e.startsWith("system.adapter.")){const t=SPECIAL_ADAPTERS.find((t=>e.startsWith(`system.adapter.${t}.`)));t&&e.match(/\.\d+$/)&&setTimeout((async()=>await this.createStateForAdapter(t)),1e3)}else this.alexaSH3?.handleObjectChange(e,t),e&&this.remote?.updateObject(e,t)},stateChange:async(e,t)=>{if(e===`${this.namespace}.app.message`&&t&&!t.ack)try{await this.sendMessageToApp(t.val)}catch(e){this.log.error(`Cannot send message to app: ${e}`)}t&&(this.googleHome?.updateState(e,t),this.alexaSH3?.handleStateUpdate(e,t),this.yandexAlisa?.updateState?.(e,t)),e&&this.remote?.updateState(e,t),e===`${this.namespace}.smart.lastResponse`&&t&&!t.ack&&this.alexaCustom?.setResponse(t.val)},unload:async e=>{try{this.device&&(this.device.end(),this.device=null),this.remote&&(this.remote.destroy(),this.remote=null),this.alexaSH3&&await this.alexaSH3.destroy()}catch{}e()},message:async e=>{if(e)switch(e.command){case"update":this.recalcTimeout&&clearTimeout(this.recalcTimeout),this.recalcTimeout=setTimeout((async()=>{this.recalcTimeout=null,this.alexaSH3&&(await this.alexaSH3.updateDevices(),await this.setStateAsync("smart.updates3",1,!0)),this.googleHome?.updateDevices((async e=>{await this.setStateAsync("smart.updatesResult",e||"",!0),this.log.debug("GH Devices updated!"),await this.setStateAsync("smart.updatesGH",!0,!0)}))}),1e3);break;case"browse3":if(e.callback)if(this.log.info(`Request V3 devices: ${e.message}`),this.alexaSH3){const t=await this.alexaSH3.getDevices("objects"===e.message);this.sendTo(e.from,e.command,t,e.callback),await this.setStateAsync("smart.updates3",0,!0)}else this.sendTo(e.from,e.command,{error:"not activated"},e.callback);break;case"browseGH":e.callback&&(this.log.info("Request google home devices"),this.googleHome?this.googleHome.updateDevices((()=>{this.sendTo(e.from,e.command,this.googleHome.getDevices(),e.callback),this.setStateAsync("smart.updatesGH",!1,!0)})):this.sendTo(e.from,e.command,{error:"not activated"},e.callback));break;case"browseAlisa":e.callback&&(this.log.info("Request Yandex Alice devices"),this.yandexAlisa?this.yandexAlisa.updateDevices((()=>{this.sendTo(e.from,e.command,this.yandexAlisa.getDevices(),e.callback),this.setStateAsync("smart.updatesYA",!1,!0)})):this.sendTo(e.from,e.command,{error:"not activated"},e.callback));break;case"alexaCustomKnownDevices":e.callback&&(this.log.info("Request Alexa Custom known devices"),this.sendTo(e.from,e.command,this.alexaCustom?this.alexaCustom.getKnownDevices():{error:"not activated"},e.callback));break;case"alexaCustomKnownUsers":e.callback&&(this.log.info("Request Alexa Custom known users"),this.sendTo(e.from,e.command,this.alexaCustom?this.alexaCustom.getKnownUsers():{error:"not activated"},e.callback));break;case"private":{if("object"!=typeof e.message)try{e.message=JSON.parse(e.message)}catch(t){return this.log.error(`Cannot parse object: ${t}`),void(e.callback&&this.sendTo(e.from,e.command,{error:"Invalid message format: cannot parse object"},e.callback))}const t=await this.processMessage(e.message.type,e.message.request);e.callback&&this.sendTo(e.from,e.command,t,e.callback);break}case"ifttt":this.sendDataToIFTTT(e.message);break;case"alexaCustomResponse":this.alexaCustom?.setResponse(e.message);break;case"updateValidTill":await this.readValidTill(!0),this.sendTo(e.from,e.command,this.validTill,e.callback);break;case"getServiceEndpoint":if(e.callback){if(!this.urlKey)try{this.urlKey=await this.readUrlKey()}catch{try{this.urlKey=await this.createUrlKey(this.config.login,this.config.pass)}catch(t){return void(e.callback&&this.sendTo(e.from,e.command,{error:`Cannot get urlKey: ${t.toString()}`},e.callback))}}const t={url:`https://service.iobroker.in/v1/iotService?key=${this.urlKey.key}&user=${encodeURIComponent(this.config.login)}`},s="string"==typeof e.message?e.message:e.message?.serviceName;s&&(t.url+=`&service=${encodeURIComponent(s)}`,t.stateID=`${this.namespace}.services.${s}`),e.message?.data&&(t.data+=`&data=${"object"==typeof e.message.data?JSON.stringify(e.message.data):e.message.data}`),!s||"*"===this.config.allowedServices[0]||this.config.allowedServices.includes(s.replace(/^custom_/,""))||ALLOWED_SERVICES.includes(s)||(t.warning="Service name is not in white list",this.log.warn(`Service "${s}" is not in allowed services list`)),e.callback&&this.sendTo(e.from,e.command,t,e.callback)}break;case"sendNotification":try{const{message:t,title:s}=(0,notifications_1.buildMessageFromNotification)(e.message);await this.sendMessageToApp(JSON.stringify({message:t,title:s})),e.callback&&this.sendTo(e.from,"sendNotification",{sent:!0},e.callback)}catch{e.callback&&this.sendTo(e.from,"sendNotification",{sent:!1},e.callback)}break;default:this.log.warn(`Unknown command: ${e.command}`)}},ready:()=>this.main().then((()=>{})).catch((e=>{this.log.error(`Error in main: ${e.toString()}`)}))}),this.on("log",(e=>this.remote?.onLog(e)))}sendDataToIFTTT(e){if(!e)return void this.log.warn("No data to send to IFTTT");if(!(this.config.iftttKey||"object"==typeof e&&e.key))return void this.log.warn("No IFTTT key is defined");let t,s;if("object"!=typeof e)t=`https://maker.ifttt.com/trigger/state/with/key/${this.config.iftttKey}`,s={value1:`${this.namespace}.services.ifttt`,value2:e};else if(e.event){const i=e.event,a=e.key;delete e.event,delete e.key,t=`https://maker.ifttt.com/trigger/${i}/with/key/${a||this.config.iftttKey}`,s=e}else{if(void 0===e.val)return this.log.warn("No value is defined");e.id=e.id||`${this.namespace}.services.ifttt`,t=`https://maker.ifttt.com/trigger/state/with/key/${this.config.iftttKey}`,s={value1:e.id,value2:e.val,value3:e.ack}}t?axios_1.default.post(t,s,{timeout:15e3,validateStatus:e=>e<400}).then((e=>this.log.debug(`Response from IFTTT: ${JSON.stringify(e.data)}`))).catch((e=>{e.response?this.log.warn(`Response from IFTTT: ${e.response.data?JSON.stringify(e.response.data):e.response.status}`):this.log.warn(`Response from IFTTT: ${e.code}`)})):this.log.warn(`Invalid request to IFTTT: ${JSON.stringify(e)}`)}async sendMessageToApp(e){if(!e)throw new Error("Empty message");const t=e.toString().trim();let s;if(t.startsWith("{")&&t.endsWith("}"))try{s=JSON.parse(t)}catch{this.log.warn(`Cannot parse message: ${t}`),s=null}else s=null;if(s)s.expire&&(s.ttlSeconds=s.expire,delete s.expire);else{const t=await this.getStateAsync(`${this.namespace}.app.expire`),i=await this.getStateAsync(`${this.namespace}.app.priority`),a=await this.getStateAsync(`${this.namespace}.app.title`),o=i?.val;s={message:e.toString(),priority:"1"===o||"high"===o||!0===o?"high":void 0,ttlSeconds:parseInt(t?.val,0)||void 0,title:(a?.val||"ioBroker").toString()}}if(s.ttlSeconds=parseInt(s.ttlSeconds,0)||void 0,s.ttlSeconds&&s.ttlSeconds>172800&&(s.ttlSeconds=172800),!s.message)throw new Error("Empty message");const i=await axios_1.default.post("https://app-message.iobroker.in/",s,{headers:{"Content-Type":"application/json",Authorization:`Bearer ${Buffer.from(`${this.config.login}:${this.config.pass}`).toString("base64")}`},timeout:5e3,validateStatus:e=>e<400});await this.setState("app.message",e,!0),this.log.debug(`Message sent: ${JSON.stringify(i.data)}`)}async controlState(e,t){if(e||="services.ifttt","object"==typeof t)if(t.id){if(t.id===`${this.namespace}.services.ifttt`&&(t.ack=!0),void 0===t.val)throw new Error("No value set");const e=await this.getForeignObjectAsync(t.id);if(!e||!e.common)throw new Error(`Unknown ID: ${t.id}`);"string"==typeof t.val&&(t.val=t.val.replace(/^@ifttt\s?/,"")),"boolean"===e.common.type?t.val=!0===t.val||"true"===t.val||"on"===t.val||"ON"===t.val||1===t.val||"1"===t.val:"number"===e.common.type&&(t.val=parseFloat(t.val)),await this.setForeignStateAsync(t.id,t.val,t.ack)}else void 0!==t.val?("string"==typeof t.val&&(t.val=t.val.replace(/^@ifttt\s?/,"")),await this.setStateAsync(e,t.val,void 0===t.ack||t.ack)):await this.setStateAsync(e,JSON.stringify(t),!0);else"string"==typeof t&&(t=t.replace(/^@ifttt\s?/,"")),await this.setStateAsync(e,t,!0)}async processIfttt(e){let t;this.log.debug(`Received IFTTT object: ${JSON.stringify(e)}`);let s=null;if("object"==typeof e&&e.id&&void 0!==e.data)if(t=e.id,"string"==typeof e.data&&"{"===e.data[0])try{s=JSON.parse(e.data)}catch{this.log.debug(`Cannot parse: ${e.data}`),s=e}else s=e.data;else if("string"==typeof e&&"{"===e[0])try{s=JSON.parse(e),"string"==typeof s.id&&(t=s.id,s.data&&(s=s.data))}catch{this.log.debug(`Cannot parse: ${JSON.stringify(e)}`)}else s=e;if(t){let e=await this.getForeignObjectAsync(t);if(!e){const s=`${this.namespace}.services.${t}`;e=await this.getForeignObjectAsync(s),e||(await this.setObjectNotExistsAsync(`services.${t}`,{type:"state",common:{name:"IFTTT value",write:!1,role:"state",read:!0,type:"mixed",desc:"Custom state"},native:{}}),t=s)}}await this.controlState(t||null,s||e)}onDisconnect(e){Date.now()-this.connectStarted<500&&this.log.warn("Looks like your connection certificates are invalid. Please renew them via configuration dialog."),"string"==typeof e?(e.toLowerCase().includes("duplicate")&&(this.log.error("Two devices are trying to connect with the same iot account. This is not allowed. Stopping"),this.getForeignObjectAsync(`system.adapter.${this.namespace}`).then((e=>{if(e)return e.common.enabled=!1,this.setForeignObjectAsync(e._id,e)}))),this.log.info(`Connection changed: ${e}`)):this.log.info("Connection changed: disconnect"),this.connectedOwn&&(this.log.info("Connection lost"),this.connectedOwn=!1,this.setState("info.connection",!1,!0)),this.remote?.onCloudDisconnect()}onConnect(e){if(this.connectedOwn)this.log.info("Connection not changed: was connected");else{const t=e.split("_"),s=[];if(t.length>2){for(let e=0;e<t.length-1;e++)s.push(`${t[e][0]}***${t[e][t[e].length-1]}`);s.push(t[t.length-1])}else s.push(`${e[0]}***${e[e.length-1]}`);this.log.info(`Connection changed: connect "${s.join("_")}"`),this.connectedOwn=!0,this.setState("info.connection",this.connectedOwn,!0)}}encryptOwn(e,t){let s="";for(let i=0;i<t.length;i++)s+=String.fromCharCode(e[i%e.length].charCodeAt(0)^t.charCodeAt(i));return`base64:${Buffer.from(s).toString("base64")}`}decryptOwn(e,t){if(t.startsWith("base64:"))try{t=Buffer.from(t.substring(7),"base64").toString("ascii")}catch(e){this.log.error(`Cannot decrypt key: ${e}`)}let s="";for(let i=0;i<t.length;i++)s+=String.fromCharCode(e[i%e.length].charCodeAt(0)^t.charCodeAt(i));return s}async readUrlKey(){const e=await this.getStateAsync("certs.urlKey");if(e?.val)return{key:e.val};throw new Error("Not exists")}async createUrlKey(e,t){let s;this.log.debug("Fetching URL key...");try{s=await axios_1.default.get(`https://generate-key.iobroker.in/v1/generateUrlKey?user=${encodeURIComponent(e)}&pass=${encodeURIComponent(t)}&version=${this.version}`,{timeout:15e3,validateStatus:e=>e<400})}catch(e){throw e.response?(401===e.response.status&&this.log.error("Cannot create URL key because of invalid user or password"),new Error(e.response.data)):e}if(s.data?.error)throw this.log.error(`Cannot fetch URL key: ${JSON.stringify(s.data.error)}`),new Error(s.data);if(s.data?.key)return await this.setStateAsync("certs.urlKey",s.data.key,!0),{key:s.data.key};throw this.log.error(`Cannot fetch URL key: ${JSON.stringify(s.data)}`),new Error(s.data)}async readCertificates(){let e,t;try{e=await this.getStateAsync("certs.private"),t=await this.getStateAsync("certs.certificate")}catch{throw new Error("Not exists")}if(t?.val&&e?.val)return{private:this.decryptOwn(this.secret,e.val),certificate:this.decryptOwn(this.secret,t.val)};throw new Error("Not exists")}async writeKeys(e){await this.setStateAsync("certs.private",this.encryptOwn(this.secret,e.keyPair.PrivateKey),!0),await this.setStateAsync("certs.public",this.encryptOwn(this.secret,e.keyPair.PublicKey),!0),await this.setStateAsync("certs.certificate",this.encryptOwn(this.secret,e.certificatePem),!0),await this.setStateAsync("certs.id",e.certificateId,!0)}async fetchCertificates(e,t,s){const i=await this.getStateAsync("certs.forceUserCreate"),a=i?.val;let o;a&&await this.setStateAsync("certs.forceUserCreate",!1,!0),this.log.debug("Fetching certificates...");try{o=await axios_1.default.get(`https://create-user.iobroker.in/v1/createUser?user=${encodeURIComponent(e)}&pass=${encodeURIComponent(t)}&forceRecreate=${a}&version=${this.version}`,{timeout:15e3,validateStatus:e=>e<400})}catch(e){throw e.response?(401===e.response.status?this.log.error("Cannot fetch connection certificates because of invalid user or password"):this.log.error(`Cannot fetch connection certificates: ${JSON.stringify(e.response.data)}`),new Error(e.response.data)):(this.log.error(`Cannot fetch connection certificates: ${JSON.stringify(e.code)}`),e)}if(o?.data?.certificates){const e=o.data.certificates;return await this.writeKeys(e),{private:e.keyPair.PrivateKey,certificate:e.certificatePem}}throw this.log.error(`Cannot fetch connection certificates: ${JSON.stringify(o.data)}`),new Error(o.data)}async processMessage(e,t){if(t instanceof Buffer&&(t=t.toString()),!t||!e)return this.log.debug(`Invalid request: ${JSON.stringify(t)}`),{error:"invalid request"};if(e.startsWith("remote")){const s=Date.now();if(this.log.debug(`Remote request: ${JSON.stringify(t)}`),this.remote)return this.remote.process(t,e).then((e=>(e!==NONE&&this.log.debug(`[REMOTE] Response in: ${Date.now()-s}ms (Length: ${Array.isArray(e)?`A ${e.length}`:JSON.stringify(e).length}) for ${t}`),e))).catch((e=>(this.log.error(`Error in processing of remote request: ${e.toString()}`),NONE)));this.log.error("Received command, but remote already closed.")}else{if(e.startsWith("nightscout")){if(this.log.debug(`Nightscout request: ${JSON.stringify(t)}`),this.config.nightscout){const e=await this.getForeignStateAsync(`system.adapter.nightscout.${this.config.nightscout}.alive`);return e?.val?this.sendToAsync(`nightscout.${this.config.nightscout}`,"send",t):{error:`nightscout.${this.config.nightscout} is offline`}}return{error:"Service is disabled"}}if(e.startsWith("alexa")){if("string"==typeof t)try{t=JSON.parse(t)}catch{return this.log.error(`Cannot parse request: ${JSON.stringify(t)}`),{error:"Cannot parse request"}}const e=JSON.parse(JSON.stringify(t));if(e.directive?.header?.correlationToken&&(e.directive.header.correlationToken="***"),e.directive?.endpoint?.scope?.token&&(e.directive.endpoint.scope.token="***"),this.log.debug(`${Date.now()} ALEXA: ${JSON.stringify(e)}`),t?.directive){if(this.alexaSH3)try{const e=await this.alexaSH3.process(t);if(t.directive.header.messageId!==e.event.header.messageId)throw new Error("Incoming and outgoing header message IDs are not equal!");return e}catch{this.log.error(`Cannot parse request: ${t}`)}return{error:"Service is disabled"}}if(!t?.error)return t&&!t.header&&this.alexaCustom?this.alexaCustom.process(t,this.config.amazonCustom):{error:"Service is disabled"};t.error.includes("You have no iobroker.iot license")&&this.alexaSH3?.pauseEvents(),this.log.error(`Error from Alexa events cloud: ${t.error}`)}else{if(e.startsWith("ifttt")){try{t="object"==typeof t?JSON.stringify(t):t.toString()}catch{return this.log.error(`Cannot parse request: ${t}`),{error:"Cannot parse request"}}return this.log.debug(`IFTTT request: ${JSON.stringify(t)}`),await this.processIfttt(t),NONE}if(e.startsWith("ghome")){if("string"==typeof t)try{t=JSON.parse(t)}catch{return this.log.error(`Cannot parse request: ${t}`),{error:"Cannot parse request"}}return this.log.debug(`[GHOME] request: ${JSON.stringify(t)}`),this.googleHome?this.googleHome.process(t,this.config.googleHome):{error:"Service is disabled"}}if(e.startsWith("alisa")){if("string"==typeof t)try{t=JSON.parse(t)}catch{return this.log.error(`Cannot parse request: ${t}`),{error:"Cannot parse request"}}return this.log.debug(`[ALISA] request: ${JSON.stringify(t)}`),this.log.debug(`${Date.now()} ALISA: ${JSON.stringify(t)}`),this.yandexAlisa?this.yandexAlisa.process(t,this.config.yandexAlisa):{error:"Service is disabled"}}{let s=!1,i=e;if(i.startsWith("custom_")&&(i=i.substring(7),s=!0),"visu"===i){this.log.debug(`Received visu command: ${JSON.stringify(t)}`),t="object"==typeof t?JSON.stringify(t):t.toString();try{const e=JSON.parse(t);if(e.presence&&await(0,visuApp_1.handleGeofenceData)(e,this),e.devices&&await(0,visuApp_1.handleDevicesData)(e,this),"getInstances"===e.command){return{result:"Ok",...await(0,visuApp_1.handleGetInstances)(e,this)}}if("sendToAdapter"===e.command)return await(0,visuApp_1.handleSendToAdapter)(e,this)}catch(e){return this.log.error(`Could not handle data "${t}" by Visu App: ${e.message}`),{error:e.message}}return{result:"Ok"}}if("*"!==this.config.allowedServices[0]&&!this.config.allowedServices.includes(i)&&!ALLOWED_SERVICES.includes(i))return this.log.warn(`Received service "${e}", but it is not found in whitelist`),{error:"Unknown service"};if(t="object"==typeof t?JSON.stringify(t):t.toString(),this.log.debug(`Custom request: ${JSON.stringify(t)}`),SPECIAL_ADAPTERS.includes(i)){try{await this.setStateAsync(`services.${i}`,t,!0)}catch(e){return{result:e}}return{result:"Ok"}}if(e.startsWith("text2command")){if(void 0!==this.config.text2command&&""!==this.config.text2command){try{await this.setForeignStateAsync(`text2command.${this.config.text2command}.text`,t)}catch(e){return{result:e}}return{result:"Ok"}}return this.log.warn("Received service text2command, but instance is not defined"),{result:"but instance is not defined"}}if(e.startsWith("simpleApi"))return{result:"not implemented"};if(!s)return this.log.warn(`Received service "${e}", but it is not allowed`),{error:"not allowed"};{let e;try{e=await this.getObjectAsync(`services.custom_${i}`)}catch(e){this.log.error(`Cannot get object services.custom_${i}: ${e}`)}if(e)return await this.setStateAsync(`services.custom_${i}`,t,!0),{result:"Ok"};try{await this.setObjectNotExistsAsync(`services.custom_${i}`,{_id:`${this.namespace}.services.custom_${i}`,type:"state",common:{name:`Service for ${i}`,write:!1,read:!0,type:"mixed",role:"value"},native:{}}),await this.setStateAsync(`services.custom_${i}`,t,!0)}catch(e){return this.log.error(`Cannot control .services.custom_${i}: ${JSON.stringify(e)}`),{error:e}}}}}}return this.log.warn(`Received message of unknown type: ${e}`),{error:"Unknown message type"}}closeDevice(){return new Promise((e=>{if(this.device)try{this.device.end(!0,(()=>{this.device=null,e()}))}catch{this.device=null,e()}else e()}))}getRetryDelay(e){return e<RETRY_DELAYS_MS.length?RETRY_DELAYS_MS[e]:6e4}logRetryAttempt(e,t,s=!0){const i=e/1e3,a=s?this.log.error.bind(this.log):this.log.info.bind(this.log);a(0===e?`${t}: retrying immediately.`:`${t}: retrying in ${i} seconds.`)}async readValidTill(e){if(!e&&this.validTill&&this.validTillLastQuery&&Date.now()-this.validTillLastQuery<864e5){if("--"!==this.validTill){const e=new Date(this.validTill),t=new Date;if(t.setDate(t.getDate()+1),e>t)return}}else try{const e=await fetch("https://iobroker.pro:3001/api/v1/validTill",{method:"GET",headers:{Authorization:`Bearer ${Buffer.from(`${this.config.login}:${this.config.pass}`).toString("base64")}`}});if(e.ok){this.validTillLastQuery=Date.now();const t=await e.json();if(this.validTill=t.validTill,Math.abs(Date.now()-new Date(t.validTill).getTime())<12e4)this.log.debug("You do not have any licenses."),this.validTill="--";else{const e=new Date(t.validTill),s=new Date,i=e.getTime()-s.getTime(),a=Math.ceil(i/864e5);a<=7&&!this.alertReported&&(this.alertReported=!0,await this.registerNotification("iot","subscription",e.toLocaleString()),this.log.warn(`Your ioBroker IoT license will expire in ${a} day(s) on ${e.toDateString()}. Please renew your license to continue using all features without interruption.`))}await this.setStateAsync("info.validTill",this.validTill,!0)}else this.log.error(`Cannot fetch validTill: ${e.status} ${e.statusText}`)}catch(e){this.log.error(`Cannot fetch validTill: ${e}`)}}async startDevice(e,t,s,i){let a;i||=0;try{a=await this.readCertificates()}catch(e){if("Not exists"!==e.message)throw e;try{a=await this.fetchCertificates(t,s)}catch{}}if(await this.readValidTill(),this.alexaSH3?.setValidTill(Date.now()-1e3),await this.closeDevice(),!a)return this.log.error("Cannot read connection certificates");this.caCert||=(0,node_fs_1.readFileSync)(`${__dirname}/../keys/root-CA.crt`);try{this.connectStarted=Date.now(),this.device=new aws_iot_device_sdk_1.device({privateKey:Buffer.from(a.private),clientCert:Buffer.from(a.certificate),caCert:this.caCert,clientId:e,username:"ioBroker",host:this.config.cloudUrl,debug:!!this.config.debug,baseReconnectTimeMs:5e3,keepalive:60}),this.remote?.registerDevice(this.device),this.device.subscribe(`command/${e}/#`),this.device.on("connect",(()=>this.onConnect(e))),this.device.on("close",(()=>this.onDisconnect())),this.device.on("reconnect",(()=>this.log.debug("reconnect"))),this.device.on("offline",(()=>this.log.debug("offline"))),this.device.on("error",(a=>{const o=a?.message&&JSON.stringify(a.message)||JSON.stringify(a);if(this.log.error(`Error by device connection: ${o}`),o.includes("EAI_AGAIN")){const a=this.getRetryDelay(i);this.logRetryAttempt(a,`DNS name of ${this.config.cloudUrl} cannot be resolved`,!0),setTimeout((()=>this.startDevice(e,t,s,i+1)),a)}})),this.device.on("message",(async(t,s)=>{if(this.log.debug(`Request ${t}`),t.startsWith(`command/${e}/`)){const i=t.substring(e.length+9);try{const t=await this.processMessage(i,s);if("debug"!==this.common.loglevel||i.startsWith("remote")||this.log.debug(`Response: ${JSON.stringify(t)}`),this.device&&t!==NONE)if(Array.isArray(t))try{for(let s=0;s<t.length;s++){const a=t[s];await new Promise(((t,s)=>this.device.publish(`response/${e}/${i}`,"string"!=typeof a?JSON.stringify(a):a,{qos:1},(e=>{e?s(e):t()}))))}}catch(e){this.log.error(`[REMOTE] Cannot send packet: ${e}`)}else{const s=JSON.parse(JSON.stringify(t));s?.event?.header?.correlationToken&&(s.event.header.correlationToken="***"),s?.event?.endpoint?.scope?.token&&(s.event.endpoint.scope.token="***"),this.log.debug(`[REMOTE] Response to 'response/${e}/${i}: ${JSON.stringify(s)}`);const a=JSON.stringify(t);if(a&&a.length>130048){const t=(0,node_zlib_1.deflateSync)(a).toString("base64");this.log.debug(`[REMOTE] Content was packed from ${a.length} bytes to ${t.length} bytes`),t.length>130048&&this.log.warn(`[REMOTE] Content was packed to ${t.length} bytes which is still near/over the message limit!`),this.device.publish(`response/${e}/${i}`,t)}else this.device.publish(`response/${e}/${i}`,a)}}catch(e){this.log.debug(`Error processing request ${t}`),this.log.debug(`${e}`)}}}))}catch(o){if((o instanceof Error?o.message:JSON.stringify(o)).includes("PEM routines"))return this.log.error(`Cannot start IoT communication because of invalid certificates: ${o.message}`),void this.log.error(`Certs: ${JSON.stringify(a)}`);if(o&&"object"==typeof o&&o.message?this.log.error(`Cannot start IoT communication: ${o.message}`):this.log.error(`Cannot start IoT communication: ${JSON.stringify(o)} / ${o?.toString()}`),("timeout"===o||o.message?.includes("timeout"))&&i<10){const a=this.getRetryDelay(i);this.logRetryAttempt(a,"Connection timeout",!1),setTimeout((()=>this.startDevice(e,t,s,i+1)),a)}}}async updateNightscoutSecret(){if(!this.config.nightscout)return;const e=this.config.login.replace(/[^\w\d-_]/g,"_"),t=this.config.nightscoutPass,s=e+(t?`-${t}`:""),i=`https://generate-key.iobroker.in/v1/generateUrlKey?user=${encodeURIComponent(this.config.login)}&pass=${encodeURIComponent(this.config.pass)}&apisecret=${encodeURIComponent(s)}`;let a;try{a=await axios_1.default.get(i,{timeout:15e3,validateStatus:e=>e<400}),a.data.error?this.log.error(`Api-Secret cannot be updated: ${a.data.error}`):this.log.debug(`Api-Secret updated: ${JSON.stringify(a.data)}`)}catch(e){e.response?this.log.warn(`Cannot update api-secret: ${e.response.data?JSON.stringify(e.response.data):e.response.status}`):this.log.warn(`Cannot update api-secret: ${e.code}`)}}async createStateForAdapter(e){const t=await this.getObjectViewAsync("system","instance",{startkey:`system.adapter.${e}.`,endkey:`system.adapter.${e}.香`});if(t?.rows?.length){let t;try{t=await this.getObjectAsync(`service.${e}`)}catch{}if(!t)try{await this.setForeignObjectAsync(`${this.namespace}.services.${e}`,{type:"state",common:{name:`Service for ${e}`,write:!1,read:!0,type:"mixed",role:"value"},native:{}})}catch{}}else try{await this.getObjectAsync(`service.${e}`)&&await this.delObjectAsync(`service.${e}`)}catch{}}async syncServiceStates(){const e=await this.getObjectViewAsync("system","state",{startkey:`${this.namespace}.services.`,endkey:`${this.namespace}.services.香`});for(let t=0;t<this.config.allowedServices.length;t++){const s=this.config.allowedServices[t];"*"===s||e.rows.find((e=>e.id===`${this.namespace}.services.custom_${s}`))||await this.setObjectNotExistsAsync(`services.custom_${s}`,{_id:`${this.namespace}.services.custom_${s}`,type:"state",common:{name:`Service for ${s}`,write:!1,read:!0,type:"mixed",role:"value"},native:{}})}for(let t=0;t<(e?.rows?.length||0);t++){const s=e.rows[t].id;if(s.startsWith(`${this.namespace}.services.custom_`)){const e=s.substring(`${this.namespace}.services.custom_`.length);this.config.allowedServices.includes(e)||await this.delStateAsync(s)}}}async main(){if(void 0===this.config.googleHome&&(this.config.googleHome=!1),void 0===this.config.amazonAlexa&&(this.config.amazonAlexa=!0),void 0===this.config.yandexAlisa&&(this.config.yandexAlisa=!1),void 0===this.config.amazonCustom){const e=await this.getForeignObjectAsync(`system.adapter.${this.namespace}`);if(e)return this.log.info(`Migrating amazonCustom configuration to ${this.config.amazonAlexa||this.config.amazonAlexaV3}`),e.native.amazonCustom=!(!this.config.amazonAlexa&&!this.config.amazonAlexaV3),void await this.setForeignObjectAsync(`system.adapter.${this.namespace}`,e)}if(this.config.pingTimeout=parseInt(this.config.pingTimeout,10)||5e3,this.config.pingTimeout<3e3&&(this.config.pingTimeout=3e3),void 0===this.config.deviceOffLevel&&(this.config.deviceOffLevel=30),this.config.login!==(this.config.login||"").trim().toLowerCase()&&this.log.error("Please write your login only in lowercase!"),!this.config.login||!this.config.pass)return this.log.error("No cloud credentials found. Please get one on https://iobroker.pro");let e=await this.getForeignObjectAsync("system.config");e||(this.log.warn("Object system.config not found. Please check your installation!"),e={common:{}});for(let e=0;e<SPECIAL_ADAPTERS.length;e++)await this.createStateForAdapter(SPECIAL_ADAPTERS[e]);if(this.secret=e?.native?.secret||"Zgfr56gFe87jJOM",this.config.pass=this.decryptOwn(this.secret,this.config.pass),this.config.deviceOffLevel=parseFloat(this.config.deviceOffLevel)||0,this.config.concatWord=(this.config.concatWord||"").toString().trim(),this.config.apikey=(this.config.apikey||"").trim(),this.config.replaces=this.config.replaces?this.config.replaces.split(","):null,this.config.cloudUrl=(this.config.cloudUrl||"").toString(),this.config.nightscout=this.config.nightscout||"",this.config.replaces){const e=[];for(let t=0;t<this.config.replaces.length;t++)e.push(`"${this.config.replaces[t]}"`);this.log.debug(`Following strings will be replaced in names: ${e.join(", ")}`)}if(this.config.yandexAlisa&&(this.yandexAlisa=new alisa_1.default(this)),this.remote=new remote_1.default(this,this.config.login.replace(/[^-_:a-zA-Z1-9]/g,"_")),this.config.allowedServices=(this.config.allowedServices||"").split(/[,\s]+/).map((e=>e.trim())).filter((e=>e)),await this.syncServiceStates(),await this.setStateAsync("info.connection",!1,!0),this.config.cloudUrl=this.config.cloudUrl||"a18wym7vjdl22g.iot.eu-west-1.amazonaws.com",!this.config.login||!this.config.pass)return this.log.error("No cloud credentials found. Please get one on https://iobroker.pro");if(this.config.iftttKey){await this.subscribeStatesAsync("services.ifttt");await this.getObjectAsync(".services.ifttt")||await this.setObjectNotExistsAsync("services.ifttt",{_id:`${this.namespace}.services.ifttt`,type:"state",common:{name:"IFTTT value",write:!0,role:"state",read:!0,type:"mixed",desc:"All written data will be sent to IFTTT. If no state specified all requests from IFTTT will be saved here"},native:{}})}await this.subscribeForeignObjectsAsync("system.adapter.*"),await this.subscribeStatesAsync("smart.*"),this.log.info(`Connecting with ${this.config.cloudUrl}`),this.config.language?(this.translate=!0,this.lang=this.config.language):this.lang=e.common.language,"en"!==this.lang&&"de"!==this.lang&&"ru"!==this.lang&&(this.lang="en");const t=await this.getStateAsync("smart.updatesResult");if(t?.val&&await this.setStateAsync("smart.updatesResult","",!0),this.remote?.setLanguage(this.lang),this.config.pass.length<8||!this.config.pass.match(/[a-z]/)||!this.config.pass.match(/[A-Z]/)||!this.config.pass.match(/\d/))return this.log.error("The password must be at least 8 characters long and have numbers, upper and lower case letters. Please change the password in the profile https://iobroker.pro/accountProfile.");await this.updateNightscoutSecret();const s=this.config.login.replace(/[^-_:a-zA-Z1-9]/g,"_");await this.startDevice(s,this.config.login,this.config.pass);try{this.urlKey=await this.readUrlKey()}catch{if(this.config.googleHome||this.config.yandexAlisa||this.config.allowedServices.length||this.config.iftttKey)try{this.urlKey=await this.createUrlKey(this.config.login,this.config.pass)}catch(e){return this.log.error(`Cannot read URL key: ${"object"==typeof e?JSON.stringify(e):e}`)}}if(this.config.amazonAlexaV3){const e=await this.getObjectAsync("smart.updates3");e&&"number"!==e.common.type&&(this.log.info('Upgrading smart.updates3 state to type "number"'),e.common.type="number",e.common.states={0:"No update",1:"objects",2:"states"},await this.setObjectAsync("smart.updates3",e)),this.alexaSH3=new alexaSmartHomeV3_1.default({adapter:this,iotClientId:s,iotDevice:this.device}),this.alexaSH3.setLanguage(this.lang),this.alexaSH3.setValidTill(Date.now()-1e3),await this.alexaSH3.updateDevices()}else{const e=await this.getStateAsync("smart.updates3");e?.val&&await this.setStateAsync("smart.updates3",0,!0)}if(this.config.amazonCustom&&(this.alexaCustom=new alexaCustom_1.default(this),this.alexaCustom.setLanguage(this.lang)),this.config.googleHome)this.googleHome=new googleHome_1.default(this,this.urlKey);else{const e=await this.getStateAsync("smart.updatesGH");e?.val&&await this.setStateAsync("smart.updatesGH","",!0)}if(this.config.yandexAlisa)this.yandexAlisa=new alisa_1.default(this,this.urlKey);else{const e=await this.getStateAsync("smart.updatesYA");e?.val&&await this.setStateAsync("smart.updatesYA","",!0)}this.googleHome?.setLanguage(this.lang),this.googleHome?.updateDevices(),this.yandexAlisa?.setLanguage(this.lang),this.yandexAlisa?.updateDevices(),await this.subscribeStatesAsync("app.message")}}exports.default=IotAdapter,require.main!==module?module.exports=e=>new IotAdapter(e):new IotAdapter;
//# sourceMappingURL=/sm/61f2ededde0f4952b7ee2e01d8997166c426be51d18d3d0a4bb83fa6f19effc8.map