node-red-contrib-home-assistant-websocket
Version:
Node-RED integration with Home Assistant through websocket and REST API
2 lines (1 loc) • 3.67 kB
JavaScript
"use strict";const g=require("slugify"),l=require("../EntityNode"),c={config:{state:{},stateType:{},attributes:u=>u.attributes||[],resend:{},outputLocation:{},outputLocationType:{},inputOverride:{}},input:{state:{messageProp:"payload.state",configProp:"state",default:"payload"},stateType:{messageProp:"payload.stateType",configProp:"stateType",default:"msg"},attributes:{messageProp:"payload.attributes",configProp:"attributes",default:[]}}};class y extends l{constructor({node:e,config:t,RED:i,status:s}){super({node:e,config:t,RED:i,status:s,nodeOptions:c})}async registerEntity(){if(!this.isIntegrationLoaded){this.error(this.integrationErrorMessage),this.status.setFailed("Error");return}if(this.registered)return;const e={};this.nodeConfig.config.filter(i=>i.value.length).forEach(i=>e[i.property]=i.value);const t={type:"nodered/discovery",server_id:this.nodeConfig.server.id,node_id:this.node.id,component:this.nodeConfig.entityType,config:e};this.nodeConfig.resend&&this.lastPayload&&(t.state=this.lastPayload.state,t.attributes=this.lastPayload.attributes),this.debugToClient(t),this.node.debug(`Registering ${this.nodeConfig.entityType} with HA`);try{await this.homeAssistant.send(t),this.status.setSuccess("Registered"),this.registered=!0}catch(i){this.status.setFailed("Error registering"),this.node.error(`Error registering entity. ${i.message?` Error Message: ${i.message}`:""}`)}}onClose(e){if(super.onClose(e),this.registered&&this.isIntegrationLoaded&&e){const t={type:"nodered/discovery",server_id:this.nodeConfig.server.id,node_id:this.node.id,component:this.nodeConfig.entityType,remove:!0};this.node.debug(`Unregistering ${this.nodeConfig.entityType} from HA`),this.homeAssistant.send(t)}}onInput({parsedMessage:e,message:t,send:i,done:s}){if(!this.isConnected){this.status.setFailed("No Connection"),s("Sensor update attempted without connection to server.");return}if(!this.isIntegrationLoaded){this.status.setFailed("Error"),s(this.integrationErrorMessage);return}let r=e.state.value,n=e.stateType.value;this.nodeConfig.inputOverride==="block"?(r=this.nodeConfig.state,n=this.nodeConfig.stateType):e.state.source==="message"&&n!=="message"&&(n="str");try{r=this.getTypedInputValue(r,n,{message:t})}catch(o){this.status.setFailed("Error"),s(`State: ${o.message}`);return}if(r===void 0){this.status.setFailed("Error"),s("State must be defined.");return}const h=this.getAttributes(e),a={};try{h.forEach(o=>{const p=g(o.property,{replacement:"_",remove:/[^A-Za-z0-9-_~ ]/,lower:!0});a[p]=this.getTypedInputValue(o.value,o.valueType,{message:t})})}catch(o){this.status.setFailed("Error"),s(`Attribute: ${o.message}`);return}const d={type:"nodered/entity",server_id:this.nodeConfig.server.id,node_id:this.node.id,state:r,attributes:a};this.nodeConfig.resend&&(this.lastPayload={state:r,attributes:a},this.state.setLastPayload(this.lastPayload)),this.debugToClient(d),this.homeAssistant.send(d).then(()=>{this.status.setSuccess(r),this.nodeConfig.outputLocationType!=="none"&&this.setContextValue(d,this.nodeConfig.outputLocationType||"msg",this.nodeConfig.outputLocation||"payload",t),i(t),s()}).catch(o=>{this.status.setFailed("API Error"),s(`Entity API error. ${o.message?` Error Message: ${o.message}`:""}`)})}getAttributes(e){let t=[];if(e.attributes.source!=="message"||this.nodeConfig.inputOverride==="block")t=this.nodeConfig.attributes;else{if(this.nodeConfig.inputOverride==="merge"){const i=Object.keys(e.attributes.value).map(s=>s.toLowerCase());this.nodeConfig.attributes.forEach(s=>{i.includes(s.property.toLowerCase())||t.push(s)})}for(const[i,s]of Object.entries(e.attributes.value))t.push({property:i,value:s})}return t}}module.exports=y;