Weather station with Firebeetle/ESPHome
A while ago I bought a box full of Firebeetles, an offer I just couldn’t resist. But I didn’t really have time to do something with them. But then I came across Home Assistant - you can run it on a Raspberry Pi - and the addon ESPHome. At some point I have to write dedicated posts about the Firebeetle and Home Assistant…
Anyway, with ESPHome and HA it’s really easy to quickly spin up a little sensor/control/etc project. Something I had in mind for a long time, was a kind of “weather station” to monitor outside temperature, humidity and pressure. A quick Google suggested the BME280 chip. And I also needed a battery for the Firebeetle. You can directly plug in a lithium battery via a PH 2.0 JST connector.
In ESPHome you create a new device, paste in the config, connect your Firebeetle to the PC and flash it, done. Then just add the visualisation of the sensor readings in HA. That easy!
Well, working out the details of the config took me a while. One big problem of the Firebeetle is the high power consumption. It comes with lots of computing power, built-in Bluetooth, built-in Wifi, etc. But that has a price, power usage. So you want the Firebeetle to sleep most time, just wake up quickly, read the sensors, send them to HA, sleep again. And suddenly your config becomes quite a bit more complex (explanations below):
substitutions:
my_ip: 192.168.168.160
my_gw: 192.168.168.1
my_sn: 255.255.255.0
mqtt_host: 192.168.168.100
esphome:
name: weather
friendly_name: Weather
on_boot:
- priority: -300
then:
- script.execute: read_sensors
esp32:
board: firebeetle32
framework:
type: arduino
# Enable logging
#logger:
# Enable Home Assistant API
#api:
# encryption:
# key: "xxx"
#ota:
# password: "xxx"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
fast_connect: true
manual_ip:
static_ip: $my_ip
gateway: $my_gw
subnet: $my_sn
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Weather Fallback Hotspot"
password: "xxx"
mqtt:
broker: $mqtt_host
username: !secret mqtt_user
password: !secret mqtt_password
birth_message:
will_message:
captive_portal:
deep_sleep:
id: sleepy
i2c:
sda: 21
scl: 22
scan: true
id: bus_a
sensor:
- platform: bme280_i2c
id: bme_id
i2c_id: bus_a
address: 0x76
temperature:
name: "W Temperature"
on_value:
- then:
- lambda: |-
id(updates)++;
pressure:
name: "W Pressure"
on_value:
- then:
- lambda: |-
id(updates)++;
humidity:
name: "W Humidity"
on_value:
- then:
- lambda: |-
id(updates)++;
update_interval: 60s
- platform: adc
id: battvcc_id
name: "W Battery Vcc"
pin:
number: GPIO34 # A2
allow_other_uses: true
accuracy_decimals: 2
attenuation: 11dB
filters:
- multiply: 2.0
update_interval: never
on_value:
- then:
- lambda: |-
id(updates)++;
- platform: adc
id: batt_id
name: "W Battery"
pin:
number: GPIO34 # A2
allow_other_uses: true
accuracy_decimals: 0
attenuation: 11dB
filters:
- multiply: 2.0
- calibrate_linear:
- 4.20 -> 100
- 4.06 -> 90
- 3.98 -> 80
- 3.92 -> 70
- 3.87 -> 60
- 3.82 -> 50
- 3.79 -> 40
- 3.77 -> 30
- 3.74 -> 20
- 3.68 -> 10
- 3.45 -> 5
- 3.00 -> 0
- clamp:
min_value: 0
max_value: 100
unit_of_measurement: '%'
update_interval: never
on_value:
- then:
- lambda: |-
id(updates)++;
globals:
- id: updates
type: int
restore_value: no
initial_value: '0'
script:
- id: read_sensors
then:
- lambda: |-
id(updates) = 0;
- component.update: battvcc_id
- component.update: batt_id
- component.update: bme_id
- wait_until:
lambda: |-
return (id(updates) >= 5);
- deep_sleep.enter:
id: sleepy
sleep_duration: 60min
The main points:
- Use fixed IP addresses, not DHCP (I just fished out an old Wifi router and set up a dedicated LAN for HA).
- Disable logging.
- Disable the HA API. That means you cannot update your Firebeetle ‘over-the-air’, and HA can’t read your sensor values. But we won’t need that.
- The sensors are read by a ‘script’ - in above example that happens once every 60min - then sleep.
- The consequence of this is, that your Firebeetle will show up as ‘not available’ and it’s sensor readings as ‘None’ (except the 2 or 3 sec out of the 3600 sec when it actually is active).
- For that reason, use MQTT. Get the HA MQTT integration and see the
mqtt
bit in the config.
Some notes about the script:
It has an internal counter, which increments for each sensor value read (these are triggered
byt component.update
). After all 5 values are read (temperature, humidity and pressure from
BME280 chip, and as little bonus the battery voltage and charge via adc
(internally from pin A2))
it will send the Firebeetle into deep sleep for another 60min.
One thing which really tripped me, was this: I set up a few more Firebeetles with DHT22 sensors in the house to get temperature and humidity of different rooms. So I had a few sensors with name “Temperature” on different Firebeetles. Oh, the MQTT integration doesn’t like that! The sensor name needs to be unique! I don’t know why. On the MQTT level this is not a problem at all, but the HA MQTT integration can’t handle it. Hence note the ‘W’ in:
temperature:
name: "W Temperature"