UNPKG

@reactsaaskit/hue-node-integration

Version:

A TypeScript package for Philips Hue Bridge Api v2 integration for Node.js. Supports esm and cjs

16 lines 20.5 kB
import K from"axios";import C from"https";import q from"axios";import _ from"https";async function w(a,e){console.log("Press the button on your Hue Bridge to proceed...");let t=30,o=0;for(;o<t;)try{let r=await q.post(`https://${e}/api`,{devicetype:a||"my-hue-app",generateclientkey:!0},{httpsAgent:new _.Agent({rejectUnauthorized:!1})});console.log("\u{1F50D} Full response from Hue Bridge:",r.data);let n=r.data[0];if(n?.success){let{username:s,clientkey:i}=n.success;return console.log(`\u2705 Registered username: ${s}`),console.log(`\u2705 Received clientkey: ${i}`),{username:s,clientkey:i}}if(n?.error?.type===101){console.log(` Waiting for button press... (${o+1}/${t})`),o++,await new Promise(s=>setTimeout(s,2e3));continue}throw new Error(`Unexpected response: ${JSON.stringify(n)}`)}catch(r){throw console.error("Request failed:",r.message),r}throw new Error("\u274C Failed to register after 30 attempts.")}async function v(a){try{let t=(await a.get("/bridge")).data.data[0];if(!t)return console.log(" No bridge information found."),null;let o={bridgeId:t?.bridge_id||"N/A",modelId:t?.model_id||"N/A",apiVersion:t?.apiversion||"N/A"};return console.log(" Successfully connected to Hue Bridge!"),console.log(" Bridge ID:",o.bridgeId),console.log(" Model:",o.modelId),console.log(" Firmware Version:",o.apiVersion),o}catch(e){return console.error(" Failed to retrieve bridge info:",e.message),e.response&&console.error("Response Data:",e.response.data),null}}import J from"https";var d=(a,e,t,o)=>{let r="/eventstream/clip/v2";console.log(`Connecting to EventStream at https://${a}${r}...`);let n=!1,s="",i={hostname:a,path:r,method:"GET",headers:{"hue-application-key":e,Accept:"text/event-stream","Cache-Control":"no-cache",Connection:"keep-alive"},rejectUnauthorized:!1},l=J.request(i,c=>{console.log("EventStream connected successfully."),c.on("data",u=>{if(n)return;s+=u.toString();let g=s.split(` `),y="unknown",h="unknown";for(let k of g){let p=k.trim();if(p.startsWith("event:")&&(y=p.replace("event:","").trim()),p.startsWith("id:")&&(h=p.replace("id:","").trim()),p.startsWith("data:")){let Q=p.replace("data:","").trim();try{let m=JSON.parse(Q);Array.isArray(m)?m.forEach(H=>{t({eventType:y,eventId:h,event:H})}):t({eventType:y,eventId:h,parsedData:m})}catch(m){console.error("Error parsing event data:",m)}}}s=g[g.length-1]}),c.on("end",()=>{console.log("\u{1F50C} EventStream ended. Reconnecting..."),n||setTimeout(()=>d(a,e,t,o),2e3)}),c.on("error",u=>{console.error(" Error in EventStream:",u),o&&o(u)})});return l.on("error",c=>{console.error("Failed to connect to EventStream:",c),o&&o(c),n||setTimeout(()=>d(a,e,t,o),2e3)}),l.end(),{close:()=>{n=!0,l.destroy(),console.log("\u{1F50C} EventStream connection closed.")}}};async function $(a){try{let t=(await a.get("/device")).data.data,o={};t.forEach(i=>{o[i.id]=i.metadata?.name||"Unnamed Device"});let n=(await a.get("/temperature")).data.data;return!n||n.length===0?(console.log(" No temperature sensors found on the Hue Bridge."),[]):(console.log(` Found ${n.length} temperature sensor(s):`),n.map((i,l)=>{let c=o[i.owner?.rid]||"Unknown Device",u={id:i.id||"N/A",deviceName:c,temperature:i.temperature?.temperature??"N/A"};return console.log(` Sensor ${l+1}:`),console.log("ID:",u.id),console.log("Device Name:",u.deviceName),console.log(" Temperature:",u.temperature,"\xB0C"),console.log("---------------------------------------------------"),u}))}catch(e){return console.error("Failed to retrieve temperature sensors:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function I(a){try{let t=(await a.get("/device")).data.data,o={};t.forEach(i=>{o[i.id]=i.metadata?.name||"Unnamed Device"});let n=(await a.get("/light_level")).data.data;return!n||n.length===0?(console.log("No light level sensors found on the Hue Bridge."),[]):(console.log(`\u{1F506} Found ${n.length} light level sensor(s):`),n.map((i,l)=>{let c=o[i.owner?.rid]||"Unknown Device",u={id:i.id||"N/A",deviceName:c,lightLevel:i.light?.light_level??"N/A"};return console.log(`Sensor ${l+1}:`),console.log("ID:",u.id),console.log("Device Name:",u.deviceName),console.log("Light Level:",u.lightLevel,"lx"),console.log("---------------------------------------------------"),u}))}catch(e){return console.error(" Failed to retrieve light level sensors:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function D(a){try{let t=(await a.get("/light")).data.data;return!t||t.length===0?(console.log("No lights found on the Hue Bridge."),[]):t.map((r,n)=>({id:r.id||"N/A",name:r.metadata?.name||"Unnamed Light",type:r.type||"Unknown Type",isOn:!!r?.on?.on,brightness:r?.dimming?.brightness||"N/A",xyColor:r.color?.xy?{x:r.color.xy.x,y:r.color.xy.y}:null}))}catch(e){return console.error("Failed to retrieve lights:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function P(a,e){try{let o=(await a.get(`/light/${e}`)).data.data;return o?{id:o.id||"N/A",name:o.metadata?.name||"Unnamed Light",type:o.type||"Unknown Type",isOn:!!o?.on?.on,brightness:o?.dimming?.brightness||"N/A",xyColor:o.color?.xy?{x:o.color.xy.x,y:o.color.xy.y}:null}:(console.log(`Light ${e} not found on the Hue Bridge.`),null)}catch(t){return console.error(`Failed to retrieve light ${e}:`,t.message),t.response&&console.error("Response Data:",t.response.data),null}}async function E(a){try{let t=(await a.get("/scene")).data.data;return!t||t.length===0?(console.log(" No scenes found on the Hue Bridge."),[]):(console.log(` Found ${t.length} scene(s) on the Hue Bridge:`),t.map((r,n)=>{let s={id:r.id||"N/A",name:r.metadata?.name||"Unnamed Scene",type:r.type||"Unknown Type",group:r.group?.rid||"N/A"};return console.log(`Scene ${n+1}:`),console.log(" ID:",s.id),console.log(" Name:",s.name),console.log(" Type:",s.type),console.log(" Group ID:",s.group),console.log("---------------------------------------------------"),s}))}catch(e){return console.error(" Failed to retrieve scenes:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function N(a,e){try{console.log(` Attempting to activate Scene: ${e}`),console.log(" Checking if Scene exists...");let o=(await a.get("/scene")).data.data;if(!o||o.length===0)return console.error("\u274C No scenes found on the Hue Bridge."),!1;let r=o.find(s=>s.id===e);if(!r)return console.error(` Scene ID ${e} not found.`),console.log(" Available Scenes:"),o.forEach(s=>console.log(` - ${s.id}: ${s.metadata?.name}`)),!1;console.log(` Scene Found: ${r.metadata?.name}`),console.log(` Sending request to activate Scene: ${e} using PUT /scene/{sceneId}...`);let n=await a.put(`/scene/${e}`,{recall:{action:"active"}});return n.status===200?(console.log(` Scene Activated: ${e} `),!0):(console.warn(` Unexpected response status: ${n.status}`),!1)}catch(t){return console.error(` Failed to activate scene (${e}):`,t.message),t.response&&console.error("\u{1F4DC} Response Data:",JSON.stringify(t.response.data,null,2)),!1}}async function R(a,e,t,o,r,n){try{let s={};if(o!==void 0?(s.on={on:o},o&&(r!==void 0&&(s.dimming={brightness:r}),t&&(s.color={xy:{x:t.x,y:t.y}}),n&&n>0&&(s.dynamics={duration:n}))):(r!==void 0&&(s.dimming={brightness:r}),t&&(s.color={xy:{x:t.x,y:t.y}}),n&&n>0&&(s.dynamics={duration:n})),Object.keys(s).length===0)return console.error("No values provided for update!"),!1;let i=await a.put(`/light/${e}`,s);return i.status===200?!0:(console.warn(`Unexpected response status: ${i.status}`),!1)}catch(s){return console.error(`Failed to update light (${e}):`,s.message),s.response&&console.error("Response Data:",JSON.stringify(s.response.data,null,2)),!1}}async function L(a,e,t){try{let o={on:{on:t}},r=await a.put(`/light/${e}`,o);return r.status===200?!0:(console.warn(`Unexpected response status: ${r.status}`),!1)}catch(o){return console.error(`Failed to update light power (${e}):`,o.message),o.response&&console.error("Response Data:",JSON.stringify(o.response.data,null,2)),!1}}async function S(a,e,t,o,r){try{let n={};if(o!==void 0&&(n.dimming={brightness:o}),t&&(n.color={xy:{x:t.x,y:t.y}}),r&&r>0&&(n.dynamics={duration:r}),Object.keys(n).length===0)return console.error("No color values provided for update!"),!1;let s=await a.put(`/light/${e}`,n);return s.status===200?!0:(console.warn(`Unexpected response status: ${s.status}`),!1)}catch(n){return console.error(`Failed to update light color (${e}):`,n.message),n.response&&console.error("Response Data:",JSON.stringify(n.response.data,null,2)),!1}}async function B(a,e,t,o,r,n){try{if(!t||t.length<2||t.length>7)return console.error("Gradient requires between 2 and 7 color points."),!1;t.forEach((c,u)=>{console.log(`\u{1F3A8} Point ${u+1}: (${c.x}, ${c.y})`)});let s;n&&n>0&&(s=n);let i={gradient:{points:t.map(c=>({color:{xy:c}}))},on:{on:o},dimming:{brightness:r},dynamics:s?{duration:s}:{}},l=await a.put(`/light/${e}`,i);return l.status===200?(console.log(`Gradient Applied to Light: ${e}`),!0):(console.warn(`Unexpected response status: ${l.status}`),!1)}catch(s){return console.error(`Failed to set gradient on light (${e}):`,s.message),s.response&&console.error("Response Data:",JSON.stringify(s.response.data,null,2)),!1}}async function F(a,e,t,o,r){try{if(!t||t.length<2||t.length>5)return console.error("Gradient requires between 2 and 5 color points."),!1;t.forEach((l,c)=>{console.log(`\u{1F3A8} Point ${c+1}: (${l.x}, ${l.y})`)});let n;r&&r>0&&(n=r);let s={gradient:{points:t.map(l=>({color:{xy:l}}))},dimming:{brightness:o},dynamics:n?{duration:n}:{}},i=await a.put(`/light/${e}`,s);return i.status===200?(console.log(`Gradient Applied to Light: ${e}`),!0):(console.warn(`Unexpected response status: ${i.status}`),!1)}catch(n){return console.error(`Failed to set gradient on light (${e}):`,n.message),n.response&&console.error("Response Data:",JSON.stringify(n.response.data,null,2)),!1}}async function G(a){try{console.log(" Fetching all `grouped_light` groups...");let t=(await a.get("/grouped_light")).data.data;if(!t||t.length===0)return console.log(" No groups (`grouped_light`) found on the Hue Bridge."),[];console.log("\u{1F50E} Fetching all rooms...");let r=(await a.get("/room")).data.data,n={};return r.forEach(i=>{let l=i.services.find(c=>c.rtype==="grouped_light");l&&(n[l.rid]=i.metadata?.name||"Unnamed Room")}),console.log(`Found ${t.length} \`grouped_light\` group(s):`),t.map((i,l)=>{let c=n[i.id]||"No Linked Room",u={id:i.id||"N/A",name:i.metadata?.name||c||"Unnamed Group",type:i.type||"Unknown Type",services:i.services?.map(g=>g.rtype).join(", ")||"N/A",linkedRoom:c};return console.log(`Group ${l+1}:`),console.log(" ID:",u.id),console.log("Name:",u.name),console.log("Type:",u.type),console.log(" Linked Room:",u.linkedRoom),console.log(" Services:",u.services),console.log("---------------------------------------------------"),u})}catch(e){return console.error(" Failed to retrieve groups:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function f(a,e,t,o,r){try{console.log(`Setting Grouped Light: ${e}`);let n={};if(t!==void 0&&(n.dimming={brightness:t},console.log(`Brightness: ${t}%`)),o&&(n.color={xy:{x:o.x,y:o.y}},console.log(`Color XY: (${o.x}, ${o.y})`)),r!==void 0&&(n.on={on:r},console.log(`Group Light State: ${r?"ON":"OFF"}`)),Object.keys(n).length===0)return console.error(" No values provided for update!"),!1;console.log("Sending request to update grouped light...");let s=await a.put(`/grouped_light/${e}`,n);return s.status===200?(console.log(`Grouped Light Updated: ${e}`),!0):(console.warn(` Unexpected response status: ${s.status}`),!1)}catch(n){return console.error(`Failed to update grouped light (${e}):`,n.message),n.response&&console.error("Response Data:",JSON.stringify(n.response.data,null,2)),!1}}async function U(a,e,t,o,r){try{console.log(`Setting multiple groups (${e.length} groups)...`);let n=await Promise.all(e.map(async s=>{console.log(`\u{1F527} Updating Group: ${s}`);let i=await f(a,s,t,o,r);return{groupId:s,success:i}}));return n.forEach(({groupId:s,success:i})=>{console.log(i?`Group ${s} updated successfully!`:`\u274C Failed to update Group ${s}.`)}),n.every(s=>s.success)}catch(n){return console.error("\u274C Failed to update multiple groups:",n.message),n.response&&console.error("Response Data:",JSON.stringify(n.response.data,null,2)),!1}}async function M(a){try{let t=(await a.get("/room")).data.data;return!t||t.length===0?(console.log("\u{1F6AA} No rooms found on the Hue Bridge."),[]):(console.log(`\u{1F6AA} Found ${t.length} room(s) on the Hue Bridge:`),t.map((r,n)=>{let s={id:r.id||"N/A",name:r.metadata?.name||"Unnamed Room",type:r.type||"Unknown Type",services:r.services?.map(i=>i.rtype).join(", ")||"N/A"};return console.log(` Room ${n+1}:`),console.log(" ID:",s.id),console.log(" Name:",s.name),console.log(" Type:",s.type),console.log(" Services:",s.services),console.log("---------------------------------------------------"),s}))}catch(e){return console.error("\u274C Failed to retrieve rooms:",e.message),e.response&&console.error("Response Data:",e.response.data),[]}}async function T(a){try{let t=(await a.get("/grouped_light")).data.data;console.log("Grouped lights:",t);let o=t.find(r=>r.id_v1==="/groups/0");if(o){console.log("Group 0 exists. Turning off all lights using grouped_light endpoint.");let r={on:{on:!1}},n=await a.put(`/grouped_light/${o.id}`,r);return n.status===200?(console.log("All lights turned off successfully using grouped_light group 0."),!0):(console.warn(`Unexpected response status: ${n.status}`),!1)}else return console.log("Group 0 not found. Cannot turn off all lights using this method."),!1}catch(e){return console.error("Error in turning off all lights:",e.message),!1}}async function O(a){try{let e=await a.get("/light"),t=[];if(Array.isArray(e.data.data))t=e.data.data;else if(Array.isArray(e.data))t=e.data;else return console.error("Unexpected lights response structure:",e.data),!1;console.log("Full lights array:",JSON.stringify(t,null,2));let o=[],r=[];if(t.forEach(n=>{(n.metadata?.archetype||"").toLowerCase()==="plug"?r.push(n.id):o.push(n.id)}),!o.length)return!1;for(let n=0;n<o.length;n+=2){let s=o.slice(n,n+2);await Promise.all(s.map(async i=>{let l={on:{on:!1}};try{let c=await a.put(`/light/${i}`,l);c.status===200?console.log(`Light ${i} turned off successfully.`):console.warn(`Failed to turn off light ${i}. Status: ${c.status}`)}catch(c){console.error(`Error turning off light ${i}:`,c.message)}})),n+2<o.length&&await new Promise(i=>setTimeout(i,250))}return!0}catch(e){return console.error("Error turning off lights except plugs:",e.message),!1}}async function j(a){try{return(await a.get("/entertainment_configuration")).data.data}catch(e){return console.error("Failed to retrieve entertainment areas:",e.message),[]}}var V=`-----BEGIN CERTIFICATE----- MIICMjCCAdigAwIBAgIUO7FSLbaxikuXAljzVaurLXWmFw4wCgYIKoZIzj0EAwIw OTELMAkGA1UEBhMCTkwxFDASBgNVBAoMC1BoaWxpcHMgSHVlMRQwEgYDVQQDDAty b290LWJyaWRnZTAiGA8yMDE3MDEwMTAwMDAwMFoYDzIwMzgwMTE5MDMxNDA3WjA5 MQswCQYDVQQGEwJOTDEUMBIGA1UECgwLUGhpbGlwcyBIdWUxFDASBgNVBAMMC3Jv b3QtYnJpZGdlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEjNw2tx2AplOf9x86 aTdvEcL1FU65QDxziKvBpW9XXSIcibAeQiKxegpq8Exbr9v6LBnYbna2VcaK0G22 jOKkTqOBuTCBtjAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjAdBgNV HQ4EFgQUZ2ONTFrDT6o8ItRnKfqWKnHFGmQwdAYDVR0jBG0wa4AUZ2ONTFrDT6o8 ItRnKfqWKnHFGmShPaQ7MDkxCzAJBgNVBAYTAk5MMRQwEgYDVQQKDAtQaGlsaXBz IEh1ZTEUMBIGA1UEAwwLcm9vdC1icmlkZ2WCFDuxUi22sYpLlwJY81Wrqy11phcO MAoGCCqGSM49BAMCA0gAMEUCIEBYYEOsa07TH7E5MJnGw557lVkORgit2Rm1h3B2 sFgDAiEA1Fj/C3AN5psFMjo0//mrQebo0eKd3aWRx+pQY08mk48= -----END CERTIFICATE-----`,x=class{constructor(e,t="192.168.1.105"){this.apiKey=e,this.bridgeIp=t,this.axiosInstance=K.create({baseURL:`https://${this.bridgeIp}/clip/v2/resource`,httpsAgent:new C.Agent({ca:V,rejectUnauthorized:!1}),headers:{"hue-application-key":this.apiKey,"Content-Type":"application/json"}})}connectBridge(e){return w(e,this.bridgeIp)}async getBridgeInfo(){return await v(this.axiosInstance)}async getTemperature(){return await $(this.axiosInstance)}async getMLightLevel(){return await I(this.axiosInstance)}async getLight(e){return await P(this.axiosInstance,e)}async getLights(){return await D(this.axiosInstance)}async getRooms(){return await M(this.axiosInstance)}async getScenes(){return await E(this.axiosInstance)}async setScene(e){return await N(this.axiosInstance,e)}async setLight(e,t,o,r,n){return await R(this.axiosInstance,e,t,o,r,n)}async setGradient(e,t,o,r,n){return await B(this.axiosInstance,e,t,o,r,n)}async setLightPower(e,t){return await L(this.axiosInstance,e,t)}async setLightColorGradient(e,t,o,r){return await F(this.axiosInstance,e,t,o,r)}async setLightColor(e,t,o,r){return await S(this.axiosInstance,e,t,o,r)}async getGroups(){return await G(this.axiosInstance)}async setGroups(e,t,o,r){return await U(this.axiosInstance,e,t,o,r)}async setGroup(e,t,o,r){return await f(this.axiosInstance,e,t,o,r)}async turnOffAllLights(){return await T(this.axiosInstance)}async turnOffAllLightsExceptPlugs(){return await O(this.axiosInstance)}startEventStream(e,t){if(this.eventSource){console.warn("Event stream is already running.");return}this.eventSource=d(this.bridgeIp,this.apiKey,e,t)}stopEventStream(){this.eventSource?(this.eventSource.close(),this.eventSource=void 0,console.log("\u{1F50C} Event stream stopped.")):console.warn("No event stream to stop.")}async getEntertainmentAreas(){return await j(this.axiosInstance)}};import b from"axios";async function Y(a,e,t,o,r,n){try{let s={};if(o!==void 0){if(s.on=o,o){if(r!==void 0){let l=Math.max(1,Math.round(r/100*254));s.bri=l}t&&(s.xy=[t.x,t.y]),n&&n>0&&(s.transitiontime=Math.round(n/100))}}else{if(r!==void 0){let l=Math.max(1,Math.round(r/100*254));s.bri=l}t&&(s.xy=[t.x,t.y]),n&&n>0&&(s.transitiontime=Math.round(n/100))}if(Object.keys(s).length===0)return console.error("No values provided for update!"),!1;let i=await a.put(`/lights/${e}/state`,s);if(i.status===200){let l=i.data;return Array.isArray(l)&&l.every(c=>c.success),!0}else return console.warn(`Unexpected response status: ${i.status}`),!1}catch(s){return console.error(`Failed to update light (${e}):`,s.message),s.response&&console.error("Response Data:",JSON.stringify(s.response.data,null,2)),!1}}async function W(a,e,t,o,r,n){try{if(!t||t.length<2||t.length>5)return console.error("Gradient requires between 2 and 5 color points."),!1;t.forEach((u,g)=>{console.log(`\u{1F3A8} Point ${g+1}: (${u.x}, ${u.y})`)});let s=Math.max(1,Math.round(r/100*254)),i=n&&n>0?Math.round(n/100):void 0,l={on:o,bri:s,gradient:{points:t.map(u=>({xy:[u.x,u.y]}))}};i!==void 0&&(l.transitiontime=i);let c=await a.put(`/lights/${e}/state`,l);if(c.status===200){console.log(`Gradient applied to light: ${e}`);let u=c.data;return Array.isArray(u)&&u.every(g=>g.success),!0}else return console.warn(`Unexpected response status: ${c.status}`),!1}catch(s){return console.error(`Failed to set gradient on light (${e}):`,s.message),s.response&&console.error("Response Data:",JSON.stringify(s.response.data,null,2)),!1}}var A=class{constructor(e,t="192.168.1.105"){this.apiKey=e,this.bridgeIp=t,this.axiosInstance=b.create({baseURL:`http://${this.bridgeIp}/api/${this.apiKey}`,headers:{"Content-Type":"application/json"}})}async connectBridge(e){try{let t=await b.post(`http://${this.bridgeIp}/api`,{devicetype:e});if(t.data&&Array.isArray(t.data)&&t.data[0].success){let o=t.data[0].success.username;return this.apiKey=o,this.axiosInstance=b.create({baseURL:`http://${this.bridgeIp}/api/${this.apiKey}`,headers:{"Content-Type":"application/json"}}),o}else throw new Error("Failed to register with the Hue Bridge.")}catch(t){throw console.error("Error registering with the Hue Bridge:",t.message),t}}async getBridgeInfo(){return await this.axiosInstance.get("/config")}async getLights(){return await this.axiosInstance.get("/lights")}async getLight(e){return await this.axiosInstance.get(`/lights/${e}`)}async setLight(e,t,o,r,n){return await Y(this.axiosInstance,e,t,o,r,n)}async setGradient(e,t,o,r,n){return await W(this.axiosInstance,e,t,o,r,n)}async setLightPower(e,t){try{let o=await this.axiosInstance.put(`/lights/${e}/state`,{on:t});if(o.status===200){let r=o.data;return Array.isArray(r)&&r.every(n=>n.success),!0}else return console.warn(`Unexpected response status: ${o.status}`),!1}catch(o){return console.error(`Failed to update light power (${e}):`,o.message),!1}}};export{x as HueIntegration,A as HueIntegrationV1}; //# sourceMappingURL=index.js.map