LiquidTrack IoT¶
LiquidTrack enables ESP8266-based smart scales to automatically log beverage consumption.
Overview¶
LiquidTrack provides:
- Automatic Logging: Weight changes detected and logged
- Macro Tracking: Beverage macros added to daily totals
- Refill Detection: Distinguishes consumption from refills
- Multi-Scale Support: Connect multiple devices
How It Works¶
Scale detects weight change → ESP8266 sends event →
ChefByte API validates → Event stored → Macros updated
Event Types¶
| Event | Detection | Action |
|---|---|---|
| Consumption | Weight decrease | Log consumption, add macros |
| Refill | Weight increase | Update current amount |
| Pickup | Brief weight change | Ignored (noise) |
Hardware Requirements¶
Components¶
- ESP8266 board (NodeMCU, Wemos D1 Mini)
- HX711 load cell amplifier
- Load cell (1-5kg capacity)
- Power supply (5V USB)
Wiring¶
Load Cell → HX711:
E+ → E+
E- → E-
A- → A-
A+ → A+
HX711 → ESP8266:
VCC → 3.3V
GND → GND
DT → D2 (GPIO4)
SCK → D3 (GPIO0)
Firmware Setup¶
1. Install Arduino IDE¶
Download from arduino.cc
2. Add ESP8266 Board¶
- File → Preferences
- Add to Additional Board URLs:
- Tools → Board → Boards Manager
- Search "esp8266" and install
3. Install Libraries¶
Sketch → Include Library → Manage Libraries:
- HX711 by Rob Tillaart
- ESP8266WiFi (included with board)
- ESP8266HTTPClient (included)
- ArduinoJson
4. Configure Firmware¶
// config.h
#define WIFI_SSID "YourWiFi"
#define WIFI_PASSWORD "YourPassword"
#define API_URL "https://chefbyte.app/api/liquidtrack"
#define API_KEY "lt_your_key_here"
#define SCALE_ID "kitchen-coffee"
5. Upload¶
- Connect ESP8266 via USB
- Select board: NodeMCU 1.0
- Select correct COM port
- Click Upload
ChefByte Configuration¶
Generate Device Key¶
- Go to Settings → LiquidTrack
- Click "Generate Device Key"
- Copy the key immediately (only shown once!)
- Enter key in firmware config
Key Security¶
- Keys are hashed before storage
- Cannot be retrieved after generation
- Delete key to revoke access
- Generate new key anytime
Product Configuration¶
Link beverages to scales:
- Create product (e.g., "Cold Brew Coffee")
- Set nutrition per serving
- Note the scale_id used in firmware
- Events will auto-match by scale_id
Event Log¶
View consumption history:
| Field | Description |
|---|---|
| Timestamp | When event occurred |
| Scale ID | Which device |
| Weight Before | Starting weight (g) |
| Weight After | Ending weight (g) |
| Consumed | Calculated amount (ml) |
| Is Refill | Whether it was a refill |
| Product | Linked product name |
| Macros | Calculated nutrition |
API Endpoints¶
POST /api/liquidtrack¶
Log consumption events.
Headers:
Body:
{
"scale_id": "kitchen-coffee",
"events": [
{
"timestamp": "2024-01-15T08:30:00Z",
"weight_before": 500,
"weight_after": 350,
"is_refill": false
}
]
}
Response:
Troubleshooting¶
No Events Appearing¶
- Check WiFi connection on ESP8266
- Verify API key is correct
- Check API URL in firmware
- Review serial monitor for errors
Incorrect Weights¶
- Recalibrate scale with known weight
- Check HX711 connections
- Ensure stable surface
- Avoid vibrations
Events Not Counting Macros¶
- Verify product is linked to scale_id
- Check product has nutrition data
- Ensure event is not marked as refill
Advanced Configuration¶
Calibration¶
Calibration steps:
- Remove all weight, note reading
- Add known weight (e.g., 500g)
- Calculate factor: (reading_with_weight - reading_empty) / actual_weight
- Set factor in code
Multiple Scales¶
Each scale needs:
- Unique scale_id
- Can share API key
- Products linked by scale_id
Battery Operation¶
For battery-powered scales:
- Use deep sleep between readings
- Wake on weight change
- Send batched events
- Optimize for low power
Example Firmware¶
Complete example available in the GitHub repository:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <HX711.h>
#include <ArduinoJson.h>
// Configuration
const char* WIFI_SSID = "YourWiFi";
const char* WIFI_PASS = "YourPassword";
const char* API_URL = "https://chefbyte.app/api/liquidtrack";
const char* API_KEY = "lt_your_key";
const char* SCALE_ID = "kitchen-scale";
HX711 scale;
float lastWeight = 0;
void setup() {
Serial.begin(115200);
// Initialize scale
scale.begin(D2, D3);
scale.set_scale(2280.f);
scale.tare();
// Connect WiFi
WiFi.begin(WIFI_SSID, WIFI_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
lastWeight = scale.get_units(10);
}
void loop() {
float currentWeight = scale.get_units(10);
float diff = lastWeight - currentWeight;
// Detect significant change
if (abs(diff) > 20) {
sendEvent(lastWeight, currentWeight, diff < 0);
lastWeight = currentWeight;
}
delay(1000);
}
void sendEvent(float before, float after, bool isRefill) {
HTTPClient http;
http.begin(API_URL);
http.addHeader("Content-Type", "application/json");
http.addHeader("x-api-key", API_KEY);
StaticJsonDocument<256> doc;
doc["scale_id"] = SCALE_ID;
JsonArray events = doc.createNestedArray("events");
JsonObject event = events.createNestedObject();
event["weight_before"] = before;
event["weight_after"] = after;
event["is_refill"] = isRefill;
String json;
serializeJson(doc, json);
int code = http.POST(json);
http.end();
}