Calories Monitoring Tool — Prototype for colourful calorie counting with conversional assistant and web user interface

Kay Wiegand
8 min readJan 11, 2021

--

This project documentation should serve as INSPIRATION for similar projects and show how easily such a Smart Home or IoT project can be implemented with Google Dialogflow, Google Actions/Assistant, Adafruit IO and some custom PHP code.

Table of Content
_____

  1. Introduction
    _ Solution
    _ Requirements
    _ Preconditions
  2. Components and Use Cases
  3. Making of Voice Control
  4. Making of Web UI Control
  5. Making of Hardware Response
    _ ESP6288 NodeMCU
    _ WS2812B LED
    _ Adafruit IO services
    _ Casing
Prototype with Google Home Mini
Demonstration of use via voice control with Google Home / Assistant as conversational assistant
Use of web user interface and hardware response of prototype

1. Introduction
_____

Everyone knows that — A few pounds off would be good. But no matter how you go about it, it’s not an easy way to lose weight permanently. Whoever wants to take it seriously can use simple tools.

The simple rule is to eat less calories than your body uses. And of course for a permanently and sustainably lose of weight it must be to a reasonable extent. Otherwise, you know — yo-yo effect. It should also be clear to everyone that diet and exercise are the most influencing factors.
Many helpers, apps, training courses and subscriptions are quickly too complex, confusing and often want to sell something.

1.1 | Solution

What helps is a simple tool that focuses on the essentials. Track and monitor calories. To keep an overview a simple coloured signal to visualize the calorie increase and the calorie consumption. You determine your daily consumption by adding and subtracting your daily calories. The difference between the daily total and consumption is displayed in number and color and saved for a later overview.

1.2 | Requirements

  • A calorie tracking tool. As easy and fast as possible so that it doesn’t annoy and slow me down
  • A coloured indicator for the daily calorie intake in relation to the defined daily basic consumption (from green to red)
  • An overview to see the results of the last days, weeks or months
  • The tool should be accessible anytime and anywhere
  • A visual reminder, preferably directly on the refrigerator

1.3 | Preconditions

Two requirements should be met so that the tool can be used effectively:

1 | Determination your daily total energy requirements with suitable table (basic metabolic rate and active metabolic rate)

2 | Determination of the values of calorie intake and / or calorie consumption, e.g. with the voice assistant, app

2. Components and Use Cases
_____

The tool is easy to access with a mobile phone. At home, the tool should also be usable with a speech assistant. The project can be divided into the two areas Smart Home and Web / Cloud Services.

Following the results of three simplified use cases.

Components overview and Use Cases

2.1 | Voice Control

Data transmission and response via voice assistant. The dialog for voice control is set up with Google Dialogflow and made available on Google Assistant and Google Home Devices with the help of Google Actions. The logic process extracts the following intents and returns a response with the current calorie status.

Default fallback | Default welcome | Set basal metabolic rate | Add calories | Subtract calories | Display calories

If the intents are recognized, PHP webhooks for the Dialogflow logic regulate the data processing and generate a response for the language assistant.

To use webhook with Google Dialogflow you can insert the URL of your webhook endpoint under the point “Fulfilment” in your Dialogflow Agent.

Your endpoint target can get the transmitted date as POST data and extract the values e. g. of message, intent or custom number-integers for example with a simple PHP snippet.

/* 
* *************************
* WEBHOOK ENDPOINT
* *************************
*/
$method = $_SERVER['REQUEST_METHOD'];if($method == "POST")
{
/* Get Dialogflow request */
$requestBody = file_get_contents( 'php://input');
$jsonArr = json_decode($requestBody, true);
/* Get values from Dialogflow request */ $message = (string) $jsonArr["queryResult"]["fulfillmentText"];
$intent = (string) $jsonArr["queryResult"]["intent"]["displayName"];
$calories = (int) $jsonArr["queryResult"]["parameters"]["number-integer"];
}

You should provide a json “text” response for Dialogflow. In our case we want to provide also a response for Google Assistant “text-to-speech

/* 
* *************************
* WEBHOOK RESPONSE
* *************************
*/
$response = '{ ***** TEXT RESPONSE ***** "fulfillmentMessages": [
{
"text": {
"text": [
"Text response from webhook"
]
}
}
]
***** ASSISTANT RESPONSE ***** "payload": {
"google": {
"expectUserResponse": true,
"richResponse": {
"items": [
{
"simpleResponse": {
"textToSpeech": "this is a simple response"
}
}
]
}
}
}
}';
echo json_encode( $response );

To use Google Assistant as integration in Google Dialogflow you can simply follow the instructions under the point “Integrations / Google Assistant” in your Dialogflow Agent. The integration settings will provide you the possibility to adapt your Dialogflow logic with Google Actions Builder for Google Assistant.

With the Google Actions Builder you can setup all features for your Google Assistant app, test the actions in the simulator and manage deployments for production, beta and alpha releases.

So you can use your Dialogflow logic with the Google Assistant and also with Google Home.

Example for prototype use with Google Assistant

2.2 | Web UI Control

Data transmission and display via web user interface. The UI is kept as reduced as possible and is based on PHP.

  • Display of the current calorie status with number and color
  • Input option for adding or subtracting calories
  • Option to set and display the daily total energy requirements
  • Daily calendar view with the final calorie status in number and color
Views of web user interface, example view green, example view red, calories input view, calendar view

5. Hardware Response
____

Color display via a hardware component. For the hardware component, Adafruit IO has a dashboard and feed with a color thicker as a data block. The Adafruit webhooks can read and / or set this after data processing. The status of the feed on a microcontroller is called up via the Adafruit MQTT API.

The ESP6288 NodeMCU is used as the microcontroller in this project. This is not only very compact, but can also communicate via a WLAN access point without additional modules. The color display is done by a WS2812B LED with an integrated controller, which ideally combines the desired color with its own LED for RGB.

5.1 | ESP6288 NodeMCU

I used the Arduino IDE with a special setting to address the ESP8266 NodeMCU. To select the ESP8266 NodeMCU in Tools › Board, you have to add the following reference in to the settings:
Settings › Additional Boards Manager URLs: “http://arduino.esp8266.com/stable/package_esp8266com_index.json

All mentioned libraries can be added in the Arduino IDE under Tools › Libraries Manager.

Very simple circuit with ESP6288 NodeMCU resistor and WS2812B LED

Level shifter.
The ESP8266 NodeMCU only comes with a max. 3.3 V and the WS2812B require 5 V on the data-in according to the data sheet. Apparently older models rely on the 5 V. Newer models seem to run on the 3.3 V as well. For reliable long-term operation, a level shifter of 3.3 to 5.0 volts should be used between the data pin and data-in. In my case the LED strips works also with the 3.3 V, so there is no level shifter in the diagram.

5.2 | WS2812B LED

To control the LED I used the FastLED library, which is also supported by good documentation, especially for adjustments for the ESP8266 NodeMCU and more complex animation examples.

Important adjustments for the ESP8266 were necessary in my setup before including the library.

Example for FastLED on ESP8266 NodeMCU:

/* 
* *************************
* SETTINGS LED
* *************************
*/
// Rearange digital pin order on baord ESP8266
// https://github.com/FastLED/FastLED/wiki/ESP8266-notes
#define FASTLED_ESP8266_RAW_PIN_ORDER
// Avoid flicker on 3-wire led chipsets (WS2812)
// https://github.com/FastLED/FastLED/wiki/Interrupt-problems
#define FASTLED_ALLOW_INTERRUPTS 0
//Include FastLED Library
#include <FastLED.h>
#define DATA_PIN D3
#define ITEMS 1
#define TYPE WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS 32
#define CORRECTION HighNoonSun
CRGB leds[1];/*
* *************************
* SETUP
* *************************
*/
void led_setup()
{
FastLED.addLeds<TYPE, DATA_PIN, COLOR_ORDER>(leds, ITEMS);
FastLED.setCorrection(CORRECTION);
FastLED.setBrightness(BRIGHTNESS);
}
/*
* *************************
* LOOOP
* *************************
*/
void led_loop(){
leds[0] = CRGB::White; FastLED.show();
delay(30);
leds[0] = CRGB::Black; FastLED.show();
delay(30);
}

5.3 | Adafruit IO services

You will find well commented and helpful examples in the Adafruit IO library. Here is a short example for integrating the library. Connection to the Adafruit service through an existing wifi and querying your data feed.

Example for Adafruit feed subscription and FastLED for color change:

/* 
* *************************
* SETTINGS Adafruit
* *************************
*/
#define IO_USERNAME “YOUR_USERNAME”
#define IO_KEY “YOUR_KEY”
#define WIFI_SSID “YOUR_WIFI_SSID”
#define WIFI_PASS “YOUR_WIFI_PASS”
// Include AdafruitIO Library
#include “AdafruitIO_WiFi.h”
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
AdafruitIO_Feed *feed = io.feed(“YOUR_FEED”);
/*
* *************************
* SETTINGS LED
* *************************
*/
// Rearange digital pin order on baord ESP8266
// https://github.com/FastLED/FastLED/wiki/ESP8266-notes
#define FASTLED_ESP8266_RAW_PIN_ORDER
// Avoid flicker on 3-wire led chipsets (WS2812)
// https://github.com/FastLED/FastLED/wiki/Interrupt-problems
#define FASTLED_ALLOW_INTERRUPTS 0
//Include FastLED Library
#include <FastLED.h>
#define DATA_PIN D3
#define ITEMS 1
#define TYPE WS2812B
#define COLOR_ORDER GRB
#define BRIGHTNESS 32
#define CORRECTION HighNoonSun
CRGB leds[1];/*
* *************************
* SETUP
* *************************
*/
void led_setup()
{
// Connect Adafruit service
while (! Serial);

Serial.println(“AdafruitIO: Connecting to service”);

io.connect();

while (io.mqttStatus() < AIO_CONNECTED) {
Serial.print(“.”);
delay(100);
}
Serial.println(io.statusText()); // Listen on feed messages
feed->onMessage(adafruit_handleMessageOnFeed);
// Get feed data
feed->get();
// Setup FastLED and clear buffer
FastLED.addLeds<TYPE, DATA_PIN, COLOR_ORDER>(leds, ITEMS);
FastLED.setCorrection(CORRECTION);
FastLED.setBrightness(BRIGHTNESS);
FastLED.clear();
FastLED.show(CRGB::Black);
}
/*
* *************************
* LOOOP
* *************************
*/
void led_loop()
{
// Execute Adafruit service
io.run();
}
/*
* *************************
* SERVICE HANDLER
* *************************
*/
void handleMessage(AdafruitIO_Data *data)
{
Serial.print("AdafruitIO: COLOR received <- ");
Serial.println(data->value());
// Process data from Adafruit service
setRGB(data->value(),r,g,b);
}
void setRGB(char* text, byte &r, byte &g, byte &b)
{
// Extract RGB values from HEX format
long l=strtol(text+1,NULL,16);
r=l>>16;
g=l>>8;
b=l;

Serial.print("R: ");Serial.println(r);
Serial.print("G: ");Serial.println(g);
Serial.print("B: ");Serial.println(b);
// Set LED with RGB values
leds[0].r = r;
leds[0].g = g;
leds[0].b = b;
// Show led with FASTLED
FastLED.show();
}

5.3 | Casing

Because we planned to placed the prototype in the kitchen it should looks like a kitchen decoration. Also the housing should be simple as possible.

An old and white painted salt packaging made of cardboard was used to hide the small microcontroller. The lid made of cork was very practical, making it easy to open and close the housing.

So that the led light comes out more blurred, we used an old plastic cap from a hairspray and insert it into the front of the can.

Finished.

Test of housing of the microcontroller and LED
Close up of microcontroller and WS2812B LED
Testing of color calculation of PHP web service to Adafruit IO platform to ESP6288 NodeMCU with WS2812B LED

--

--

Kay Wiegand
Kay Wiegand

Written by Kay Wiegand

Freelance Digital Consultant. Creative Developer. Technical Manager. Photographer.

No responses yet