I work from home and have three children who like to wander into my office during conference calls. I found an On Air light up sign on Amazon for £15 to go outside my office. When it arrived I naturally prised it open to have a peek at the electronics and was pleasantly surprised at how simple it all looked. It seems that a dab if glue was used to secure the clips so getting the box open was the most stressful part of the project.
Inside I found that there was a soldered wire for the 5V and Ground coming from the USB connector. I also found two soldered points labelled SWI_1 and SWI_2 which go to a simple push switch. I traced the tracks from the switch and one went to ground and the other went to a pin on the tiny IC that controls the thing.
After reading the instructions and having a play with the button it seems to have three modes - off, on and a sort of pulsating effect. Pressing the button cycles through these modes.
So as I had figured out all I needed to do was pull the pin on the IC to ground in order to cycle through the modes I found an ESP8266 in the drawer which I had been using for an ePaper project that never really worked out and got my soldering iron out. I soldered wires onto the 5V, Ground and the SWI_1 existing solder blobs. I then connected these to VIN, Ground and a GPIO pin on the ESP8266.
The whole lot was then secured into the box with a bit of electrical tape because life's too short right?
I wrote a simple firmware, and by wrote I mean I copied and pasted bits from other projects to get it to work. It connects to my wifi and then pulls a really small bit of json down which tells it which of the three modes/statuses it should go to.
{
"Status": 3
}
By dropping the pin to LOW for half a second it can cycle through the modes/statuses and it keeps track of which one it is at (because there is no feedback unless I solder something to measure the voltage going to the LEDs on another pin).
The code looks something like this:
#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <ArduinoJson.h>
const char* ssid = "xxxxxxxxxxxx";
const char* password = "xxxxxxxxxxxxx";
const String url = "http://xxx.xxxxxxxxxxxxxx.xxx/xxxxx/";
StaticJsonDocument<4096> jsonDoc;
WiFiClient wifiClient;
const int outputPin = 5;
int status = 1;
void setup() {
pinMode(outputPin, OUTPUT);
Serial.begin(115200);
Serial.println("WiFi Starting...");
#ifdef RE_INIT_NEEDED
WiFi.persistent(true);
WiFi.mode(WIFI_STA); // switch off AP
WiFi.setAutoConnect(true);
WiFi.setAutoReconnect(true);
WiFi.disconnect();
#endif
if (!WiFi.getAutoConnect() || ( WiFi.getMode() != WIFI_STA) || ((WiFi.SSID() != ssid) && String(ssid) != "........")) {
Serial.println();
Serial.print("WiFi.getAutoConnect()=");
Serial.println(WiFi.getAutoConnect());
Serial.print("WiFi.SSID()=");
Serial.println(WiFi.SSID());
WiFi.mode(WIFI_STA); // switch off AP
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
}
int ConnectTimeout = 30; // 15 seconds
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
Serial.print(WiFi.status());
if (--ConnectTimeout <= 0) {
Serial.println();
Serial.println("WiFi connect timeout");
return;
}
}
Serial.println();
Serial.println("WiFi connected");
Serial.println(WiFi.localIP());
}
int change() {
digitalWrite(outputPin, LOW);
Serial.println("Pin set to low - waiting");
delay(500);
digitalWrite(outputPin, HIGH);
Serial.println("Pin returned to high");
delay(500);
status += 1;
if (status >3) {
status -=3;
}
return status;
}
void setStatus(int target) {
if (status != target) {
Serial.println("Changing status");
while (status != target) {
change();
}
}
}
// the loop function runs over and over again forever
void loop() {
delay(5000);
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(wifiClient,url);
int httpCode = http.GET();
//Check the returning code
if (httpCode == 200) {
Serial.println("Data received");
String json = http.getString();
Serial.println(json);
deserializeJson(jsonDoc, json);
JsonObject obj = jsonDoc.as<JsonObject>();
setStatus(obj["Status"]);
}
}
}
Once I had got it picking up the necessary json I wrote a little bit of php to generate the json from a simple key/value table in a database on my webserver.
<?php
include "db.php";
$conn = new mysqli($servername, $username, $password);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
mysqli_select_db($conn,$schema);
$sql = "SELECT * from key_value where key_value.key = 'Status'";
$result = $conn->query($sql);
$result_row = $result->fetch_assoc();
$output->Status = (int)$result_row['value'];
header('Content-Type: application/json');
echo(json_encode($output, JSON_PRETTY_PRINT));
mysqli_close($conn);
?>
It would be easy enough to have the unit send a UID along with the request if I wanted more than one of these things running independently but I didn't want to bother as it was late and I needed to go to bed.
Finally I made a small PHP page that can be called to update the database with a status 1 for on or 3 for off (I didn't bother with the flickering pulsating mode because it's annoying). Within IFTTT you can call a webservice as an action so I set this up and connected it to my Alexa account. It's worth noting that I so far haven't implemented any security at all - anyone who can get hold of the (obfuscated) URL of the update page can turn the light on and off.
IFTTT contains a load of triggers so I can do stuff like have it come on automatically when an event in my google calendar starts. I wish there was better MS Teams integration so I could trigger it with my Teams status without having to do a whole load of new code. Anyway, that's it. Took me from the end of dinner until about 1am so there is definitely scope for more to be done when I have the time.
Comments