Hi, I need a bit of help. I have a bmc680 connected on the ESP8266, and it works great, There is a platform: template with the code bellow, that takes the iaq_range values and display different messages depends on its values, this is all great.
I would create a script or a new template sensor, instead of stuffing the functionality into the text_sensor.
Anyway, you could convert the light.turn_on action to lambda code.
You have to put it in before the return command though.
if ( id(iaq_range).state <= 50.0 )
{
auto call = id(led_presence).turn_on();
call.set_brightness(0.2);
call.set_rgb(1.0, 0, 0);
call.perform();
return {"Very good"};
}
Notice that it’s using floats (0 to 1) instead of percentages.
Edit: I’ve created a script that you can try out. I haven’t tested it a lot but it seems to work. It sets the color of the LED from Green to Purple according to the IAQ level. It’s using HSV instead of RGB to get those fluent gradients. I’m using a version of the script in my Power Meter config to indicate current power level using a single WS2818 LED
You could try it out to see if it works for you.
light:
- platform: neopixelbus
type: GRB
variant: WS2812x
pin: D8
num_leds: 1
name: "Air Quality"
id: quality
sensor:
- platform: bme680_bsec
temperature:
name: "BME680 Temperature"
pressure:
name: "BME680 Pressure"
humidity:
name: "BME680 Humidity"
iaq:
name: "BME680 IAQ"
id: iaq_range
on_value:
then:
- lambda: |-
id(set_iaq_led)->execute( x * 100 / 500);
co2_equivalent:
name: "BME680 CO2 Equivalent"
breath_voc_equivalent:
name: "BME680 Breath VOC Equivalent"
script:
- id: set_iaq_led
parameters:
pct: float
mode: restart
then:
lambda: |-
const float s = 1.0; // saturation (purity). [0-1]
const float v = 0.5; // brightness. [0-1]
int i;
float r, g, b, f, h, p, q, t;
f = pct;
if (f < 100) {
h = 130 - f; // orange to green
} else {
f -= 100;
if (f == 0) {
h = 0; // red
} else if (f > 120) {
h = 300; // purple
} else {
h = 360 - ceil(f / 2.0); // red to purple
}
}
h /= 60; // sector 0 to 5
i = floor(h);
f = h - i;
p = v * ( 1 - s );
q = v * ( 1 - s * f );
t = v * ( 1 - s * ( 1 - f ) );
switch( i ) {
case 0:
r = v;
g = t;
b = p;
break;
case 1:
r = q;
g = v;
b = p;
break;
case 2:
r = p;
g = v;
b = t;
break;
case 3:
r = p;
g = q;
b = v;
break;
case 4:
r = t;
g = p;
b = v;
break;
default:
r = v;
g = p;
b = q;
break;
}
auto call = id(quality).turn_on();
call.set_rgb(r, g, b);
call.perform();
The first script basically just uses the set_rgb function to set the light to red. If it shows up white, I suspect there could something with the wiring or maybe try another pin?
wait
your first script work beautifully. The problem was that I changed it only to the return {“Very good”}, and the sensor was now on Good. Perfect what I wanted. 1000000 thanks… a question, how do I set the colour? I seen that 1.0,0,0 is red, 0,1.0,0 is green and 0,0,1.0 is blue, can I get more colours?
Edit: I’ve edited the second script in the post above. You should be able to use it like shown. This will make it easier to get the whole range of colours.
With the colours I got it, is basically the combination like on the page I found that show 0 to 100% but decided by 100.
I will try the script, I the first method works fine, but I don’t know what is the best value to use for the light is the AQI or is the 2.5 ppm value. Because I noticed that sometime the 2.5 ppm is low say 2 that would be a green but the AQI is 150 that is already yellow or orange.
I seen most of the comercia air quality meter show the 2.5 ppm. For example the Ikea one nd most use the same values have:
Not quite sure what you mean with 2.5 ppm value. Do you mean CO2 or VOC?
The BME680 is not a PM2.5 sensor - those type of sensors measure dust particles in the air, usually with a laser.