Environmental monitor
Flashing ESPHome
The first step in using my ESP 8266 as a monitoring device is to get ESPHome installed.
- Can use the web flasher: https://web.esphome.io/
- Have to use Chrome
- Chrome couldn’t connect
- I had to manually give permission to the serial port to my user
sudo chmod a+rw /dev/ttyUSB0
Configuring ESP Home
My sensor is plugged into i2c and my config looks like this:
substitutions:
name: esphome-web-58aefb
friendly_name: Studio Environmental Monitor
esphome:
name: ${name}
friendly_name: ${friendly_name}
min_version: 2024.6.0
name_add_mac_suffix: false
project:
name: esphome.web
version: dev
esp8266:
board: esp01_1m
# Enable logging
logger:
# Enable Home Assistant API
api:
# Allow Over-The-Air updates
ota:
- platform: esphome
# Allow provisioning Wi-Fi via serial
improv_serial:
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
ap:
ssid: "fallback"
password: "12345678"
# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
captive_portal:
dashboard_import:
package_import_url: github://esphome/example-configs/esphome-web/esp8266.yaml@main
import_full_config: true
# To have a "next url" for improv serial
web_server:
i2c:
sda: GPIO4
scl: GPIO5
scan: true
sensor:
- platform: bme680
temperature:
name: "BME680 Temperature"
oversampling: 16x
pressure:
name: "BME680 Pressure"
humidity:
id: "humidity"
name: "BME680 Humidity"
gas_resistance:
id: "gas_resistance"
name: "BME680 Gas Resistance"
address: 0x77
update_interval: 60s
- platform: template
name: "BME680 Indoor Air Quality"
id: iaq
icon: "mdi:gauge"
# calculation: comp_gas = log(R_gas[ohm]) + 0.04 log(Ohm)/%rh * hum[%rh]
lambda: |-
return log(id(gas_resistance).state) + 0.04 * id(humidity).state;
state_class: "measurement"
text_sensor:
- platform: template
name: "BME680 IAQ Classification"
icon: "mdi:checkbox-marked-circle-outline"
lambda: |-
if (int(id(iaq).state) <= 50) {
return {"Excellent"};
}
else if (int(id(iaq).state) <= 100) {
return {"Good"};
}
else if (int(id(iaq).state) <= 150) {
return {"Lightly polluted"};
}
else if (int(id(iaq).state) <= 200) {
return {"Moderately polluted"};
}
else if (int(id(iaq).state) <= 250) {
return {"Heavily polluted"};
}
else if (int(id(iaq).state) <= 350) {
return {"Severely polluted"};
}
else if (int(id(iaq).state) <= 500) {
return {"Extremely polluted"};
}
else {
return {"unknown"};
}
Result
Lion clicker
Web Sockets
- WSCat exists for playing with websocket from the terminal:
npm install -g wscat
End of day
Colorado got snow last night. I woke up to the world covered a dusty white. I spent my day working in my studio and drinking green tea. I notice I feel like I got a less done today even though it was, objectively, a very busy and good day. I think it’s an adjustment out of the social space and into a quiet place where I’m thinking.
notebook page: https://notes.nicole.computer/daily/2024-11-25
Worked on Today
- I built an environmental monitor today. It’s an ESP8266 (microprocessor with wifi) with a BME680 (temperature, air quality, humidity sensor) running ESPHome and connected to Home Assistant. Eeek! There’s a lot of domain words in that. Basically it’s a little arduino-like friend that collects data and ships it off to a server that runs my home.
- I got to do some soldering. It was just headers but it was nice!
- I have it hooked up to power-over-ethernet that’s splitting out a 5v USB jack so it can run all the time in the studio (mostly everything gets turned off when I leave)
- I 3D printed a case. It fits everything fine but it isn’t elegant. If I’m feed design-y I’d love to take a run at making something that looks nicer
- I worked on Lion Clicker. The very very basics work- You can click and the clicks count and it keeps track of global clicks
- Websockets. I fought with websockets SO much all day. Websockets are like an escape hatch from HTTP to “you’re on your own”. You are responsible for encoding/decoding messages and deciding what they mean. Also what if things get disconnected? What then?
- I am a HUGE redux fan-girl. Welllll not the specific technology more the idea that state changes in atomic and predictable ways. I’ve done a lot of reducer work over the last decade. For this project I tried out zustand (neat ideas but it removes being able to serialize objects easily) and I’m playing with
reduxjs/toolkit
and I hate it. I’m giving it a chance, though. Maybe it’ll be fine. I’m weird but I like seeing an event written out as an object. - I spent a lot of time thinking about buttons and buttons that feel satisfying to click. I have a button that I’m liking for now
- Right now the total clicks for everybody gets blown away every deploy. For now that’s fine. It’s just a variable in memory. Eventually I’ll be persisting to a datastore (I think mongodb but we’ll see)
- Right now the total clicks in the world don’t get updated until you start clicking
I thought a whole bunch about “the game” of Lion Clicker today. I think it’ll work like you click on the button to give Lion clicks, occasionally Lion will give you a Lion Coin, you can use Lion Coin to buy things that click more often (autoclickers!) or make your clicks more efficient or give Lion upgrades (like hats!). All of that still feels far off and honestly just getting the client and server talking still feels shaky.
I try to have everything I make exist in the world, even when it’s broken and not-there. So source code for the curious: https://github.com/nicolecomputer/lion-clicker and also Lion clicker: https://clicker.lion.computer/
Tomorrow
I think still heads down?
I want to get state persisting. I need to think about identifying each player and how to handle login (which I’m not excited about. I kind of want it to be you show up and click and then later if you want you can persist your part of the clicker). I also want to start issuing Lion Coins for clicks. I think the server does that. And If It’s a really good day I guess I’ll have the first level of autoclickers. Maybe?