// A lamp that shows a colour or a white: Alexa.ColorController and Alexa.ColorTemperatureController, with power // and brightness. It reports the colour or the colour temperature, whichever it shows. // // ALEX2MQTT_USERNAME=... ALEX2MQTT_PASSWORD=... ALEX2MQTT_ROOT_TOPIC=... node examples/color-lamp.js // // "alex2node" is the installed package; inside this checkout it resolves to the built dist/. const { Alex2MQTT, AlexaErrors, PowerController, BrightnessController, ColorController, ColorTemperatureController } = require("alex2node"); const missing = ["ALEX2MQTT_USERNAME", "ALEX2MQTT_PASSWORD", "ALEX2MQTT_ROOT_TOPIC"].filter((name) => !process.env[name]); if (missing.length > 0) { console.error(`${missing.join(", ")} not set. Set the MQTT user name, the password and the root topic of your Alex2MQTT account.`); process.exit(1); } const { ALEX2MQTT_USERNAME, ALEX2MQTT_PASSWORD, ALEX2MQTT_ROOT_TOPIC } = process.env; const bridge = new Alex2MQTT(ALEX2MQTT_USERNAME, ALEX2MQTT_PASSWORD, ALEX2MQTT_ROOT_TOPIC); bridge.on("connect", () => console.log("connected, discover the devices in the Alexa app")); bridge.on("error", (err) => console.error("bridge:", err.message)); // The whites Alexa asks for by name: warm, soft, white, daylight, cool const WHITES = [2200, 2700, 4000, 5500, 7000]; // color is null while the lamp shows a white const lamp = { on: false, brightness: 100, color: null, kelvin: 2700 }; const device = bridge.addDevice({ endpointId: "floor-lamp", name: "Floor Lamp", categories: ["LIGHT"] }); const power = device.add(PowerController); const brightness = device.add(BrightnessController); const color = device.add(ColorController); const white = device.add(ColorTemperatureController); device.state((s) => { s.set(power, "powerState", lamp.on ? "ON" : "OFF").set(brightness, "brightness", lamp.brightness); if (lamp.color) s.set(color, "color", { ...lamp.color, brightness: lamp.brightness / 100 }); else s.set(white, "colorTemperatureInKelvin", lamp.kelvin); s.health("OK"); }); power.on("TurnOn", (ctx) => { lamp.on = true; return ctx.respond(); }); power.on("TurnOff", (ctx) => { lamp.on = false; return ctx.respond(); }); brightness.on("SetBrightness", (ctx) => { lamp.brightness = ctx.payload.brightness; lamp.on = true; return ctx.respond(); }); // SetColor comes with brightness 1 whatever the lamp shows: the lamp takes hue and saturation and keeps its brightness color.on("SetColor", (ctx) => { const { hue, saturation } = ctx.payload.color; lamp.color = { hue, saturation }; lamp.on = true; return ctx.respond(); }); white.on("SetColorTemperature", (ctx) => { lamp.kelvin = Math.min(7000, Math.max(2200, ctx.payload.colorTemperatureInKelvin)); lamp.color = null; lamp.on = true; return ctx.respond(); }); // "Warmer" and "cooler" have no meaning while the lamp shows a colour. A handler that throws answers with the error. function step(by) { return (ctx) => { if (lamp.color) throw AlexaErrors.notSupportedInCurrentMode("The lamp shows a colour", "COLOR"); const next = WHITES.indexOf(WHITES.find((kelvin) => kelvin >= lamp.kelvin) ?? 7000) + by; lamp.kelvin = WHITES[Math.min(WHITES.length - 1, Math.max(0, next))]; return ctx.respond(); }; } white.on("IncreaseColorTemperature", step(1)); white.on("DecreaseColorTemperature", step(-1)); bridge.connect();