This post contains affiliate links. For more information, see my disclosures here.
In 2019, a regulation came into force in Europe by which companies are required to have a daily record of the hours of their employees.
There are many online tools to keep track of this. At Desygner we use Calamari.io.
We use Slack as a communication tool and we have commands for clocking in / out from Calamari.
The problem is that sometimes I forget to write the command in Slack to start or end my working day 🤦🏽♂️
Thinking about solutions to make it easier, and since I like to tinker with electronics, I thought about building a small device with a couple of buttons with which I could start and end my shift and register the lunch break. All I needed was for Calamari to offer an API to communicate with, and they have one! 👏🏽
Now, it was time to choose where to start building this system. Previously, I had used Arduino for electronics projects but now I was going to need WiFi connection and the cheapest option of this brand is the Arduino Nano 33 IoT at around $25 on Amazon. Several people had recommended me to use the ESP32 board that also includes WiFi and Bluetooth and you can find it on Amazon for $10.
This was my first time working with the ESP32 board, so after the first steps to get it working with my computer and Arduino IDE, the next thing I wanted to do was connect it to the WiFi network.
My first idea was to have an app or web with which to connect via Bluetooth to the board, and once there, through an interface, be able to select the network to connect it to and write the password. It sounded great! However, after searching a lot about how to connect the ESP32 board via WiFi I did not find anything similar already done. So I opted for a simpler option: hardcode the name and password of the WiFi network in the code. The downside of this is that every time I want to shift networks I need to change the code and compile it back to the board.
#include "WiFi.h" //ESP32 WiFi library
WiFi.mode(WIFI_STA);
WiFi.begin("Wifi_SSID", "WiFiPassword");
uint8_t i = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
if ((++i % 16) == 0) {
Serial.println(F(" still trying to connect"));
}
}
Serial.print(F("Connected. My IP address is: "));
Serial.println(WiFi.localIP());
This guide was helpful
Once connected to the network, the next important step was to find out how to communicate over the Internet, needed to be able to make calls to Calamari's API.
This, similar to the WiFi connection, is not a complex task since there are libraries that we can use to help us. In this case, I used the library <HTTPClient.h>
.
For this first test of how to make HTTP calls I didn't want to mess with Calamari's API just yet, hence I used a service that offers a mock REST API for testing: JSONPlaceholder.
#include "HTTPClient.h"
HTTPClient http;
http.begin("https://jsonplaceholder.typicode.com/posts/1");
int httpCode = http.GET();
if (httpCode > 0) {
String response = http.getString();
Serial.println(httpCode);
Serial.println(response);
} else {
Serial.println("Error on HTTP request: ");
Serial.println(httpCode);
}
http.end();
I followed this guide
With everything set up, I was ready to make requests to the Calamari.io API.
I created a class to have everything tidier and make the operation easier within the code. I helped myself with this guide to do it. You can see how I built it in the link at the end of the article with the repository on Github.
To use the class you just need to create an instance and pass four arguments, the base URL of the Calamari.io API, the username and password (information that Calamari provides when you activate the API) and the employee's email (in this case my corporate email).
The class has six methods available to use. I think the names are understandable enough:
- Shift:
shiftIsOn()
,startShift()
,stopShift()
- Break:
breakIsOn()
,startLunchBreak()
,stopLunchBreak()
After a bit of trial and error, I got everything working. I was only missing the hardware part: a button to start/end the shift 👨🏽💻 and another button to start/finish the lunch break 🍕
The two buttons have one of the pins connected to ground through a resistor, here you can read a good explanation of why it is necessary to use these resistors (pull-up or pull-down). The pins on the same side but at the bottom are connected to the GPIO inputs on the board: 26
for the first button (the one that starts/ends the shift) and 27
for the second button (the one that starts/ends the break). And the right pins are connected to the 3.3V output.
Finally, I only needed to take care of the code of when the buttons are pressed, so it can perform the necessary action depending on the button pressed.
int pushShiftButton = digitalRead(26);
int pushBreakButton = digitalRead(27);
if(pushShiftButton) {
if(calamari.shiftIsOn()) {
Serial.println("Stop shift");
calamari.stopShift();
} else {
Serial.println("Start shift");
calamari.startShift();
}
delay(1000);
}
if(pushBreakButton) {
if(calamari.breakIsOn()) {
Serial.println("Stop lunch break");
calamari.stopLunchBreak();
} else {
Serial.println("Start lunch break");
calamari.startLunchBreak();
}
delay(1000);
}
When one of the buttons is pressed, for example the lunch break button, it is checked whether the break is currently taking place. If it is, then the method to stop it is called, and if not, the method to start it is called. Then there is a delay of 1 second in the code. This is done because otherwise, the code could be executed multiple times, even if we only pressed the button once since this piece of code is inside a loop that runs faster than it takes to press and remove your finger from the button.
And this is it, here you can see how it actually works 😁:
And this is the complete code on my Github:
jvlobo / esp32-calamari.io-api
Clocking in and out in Calamari.io with the ESP32 development board
Stay tuned for the second part of this project, where I am going to create in 3D and print a box to make this system more compact and portable. I will also install a battery so I don't need to be powering it through the ESP32 USB port.
Update: Second part is published now! ⬇️
Top comments (0)