Convert to Platform.io

This commit is contained in:
2021-01-22 10:20:00 +00:00
commit cde367c928
8 changed files with 351 additions and 0 deletions

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Andrew Williams
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

25
README.md Normal file
View File

@@ -0,0 +1,25 @@
ESP8266 Busylight
=================
A simple ESP8266 Busylight.
Configuration
-------------
Edit `config.h`, and adjust the following values as needed:
* `LED_TYPE` - 0/1 for Anode/Cathode
* LED Pin numbers
* SSID, and Key
Usage
-----
The ESP8266 runs a simple webserver, and statuses can be changed with simple `GET` calls to `/<status name>`. E.g. `/away`.
The index shows a list of links to the available statuses.
Acknowledgements
----------------
This project is heavily inspired by [David Sword's Busylight](https://davidsword.ca/esp8266-busy-server/) using a NodeMCU ESP8266.

39
include/README Normal file
View File

@@ -0,0 +1,39 @@
This directory is intended for project header files.
A header file is a file containing C declarations and macro definitions
to be shared between several project source files. You request the use of a
header file in your project source file (C, C++, etc) located in `src` folder
by including it, with the C preprocessing directive `#include'.
```src/main.c
#include "header.h"
int main (void)
{
...
}
```
Including a header file produces the same results as copying the header file
into each source file that needs it. Such copying would be time-consuming
and error-prone. With a header file, the related declarations appear
in only one place. If they need to be changed, they can be changed in one
place, and programs that include the header file will automatically use the
new version when next recompiled. The header file eliminates the labor of
finding and changing all the copies as well as the risk that a failure to
find one copy will result in inconsistencies within a program.
In C, the usual convention is to give header files names that end with `.h'.
It is most portable to use only letters, digits, dashes, and underscores in
header file names, and at most one dot.
Read more about using header files in official GCC documentation:
* Include Syntax
* Include Operation
* Once-Only Headers
* Computed Includes
https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html

21
include/config.h Normal file
View File

@@ -0,0 +1,21 @@
// Type of RGB LED, adjusts the brightness calculations.
#define LED_TYPE 0 // 0 = Anode, 1 = Cathode
// GPIO pins for each colour
#define RED_LED_PIN 4
#define GREEN_LED_PIN 0
#define BLUE_LED_PIN 2
// Enables the webserver
#define WEBSERVER
// Enable MQTT connection (not complete)
//#define MQTT
// WIFI connection details
#define WIFI_SSID "ssid"
#define WIFI_PASS "s3cur3"
// MQTT connection details
#define MQTT_SERVER "mqtt.local"
#define MQTT_PORT 1883

46
lib/README Normal file
View File

@@ -0,0 +1,46 @@
This directory is intended for project specific (private) libraries.
PlatformIO will compile them to static libraries and link into executable file.
The source code of each library should be placed in a an own separate directory
("lib/your_library_name/[here are source files]").
For example, see a structure of the following two libraries `Foo` and `Bar`:
|--lib
| |
| |--Bar
| | |--docs
| | |--examples
| | |--src
| | |- Bar.c
| | |- Bar.h
| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html
| |
| |--Foo
| | |- Foo.c
| | |- Foo.h
| |
| |- README --> THIS FILE
|
|- platformio.ini
|--src
|- main.c
and a contents of `src/main.c`:
```
#include <Foo.h>
#include <Bar.h>
int main (void)
{
...
}
```
PlatformIO Library Dependency Finder will find automatically dependent
libraries scanning project source files.
More information about PlatformIO Library Dependency Finder
- https://docs.platformio.org/page/librarymanager/ldf.html

14
platformio.ini Normal file
View File

@@ -0,0 +1,14 @@
; PlatformIO Project Configuration File
;
; Build options: build flags, source filter
; Upload options: custom upload port, speed and extra flags
; Library options: dependencies, extra library storages
; Advanced options: extra scripting
;
; Please visit documentation for the other options and examples
; https://docs.platformio.org/page/projectconf.html
[env:wemos-d1]
platform = espressif8266
board = d1
framework = arduino

174
src/busylight.cpp Normal file
View File

@@ -0,0 +1,174 @@
// Busylight - A web accessible busylight
// (c) 2021 Andrew Williams <andy@tensixtyone.com>
// This code is licensed under MIT license (see LICENSE.txt for details)
#include <config.h>
#include <Arduino.h>
#include <ESP8266WiFi.h>
#ifdef WEBSERVER
#include <ESP8266WebServer.h>
#endif
#ifdef MQTT
#include <PubSubClient.h>
#endif
#define PWM_MAX_VALUE 1024
struct status
{
char name[20];
int r;
int g;
int b;
int blink;
};
struct status statuses[] = {
{"busy", 255, 0, 0, 0},
{"available", 0, 255, 0, 0},
{"away", 150, 255, 0, 0},
{"ooo", 255, 0, 255, 0},
{"offline", 0, 0, 0, 0},
{"blue", 0, 0, 255, 10}
};
#define STATUSES_COUNT 6
//#####################################
WiFiClient wifi;
#ifdef WEBSERVER
ESP8266WebServer server;
#endif
#ifdef MQTT
PubSubClient pubsub(wifi);
#endif
char current_state[20];
int RGB_calc(int value) {
#if LED_TYPE == 0
return PWM_MAX_VALUE - ((value / 255.f) * PWM_MAX_VALUE);
#else
return (value / 255.f) * PWM_MAX_VALUE;
#endif
}
void RGB_color(int r, int g, int b)
{
analogWrite(RED_LED_PIN, RGB_calc(r));
analogWrite(GREEN_LED_PIN, RGB_calc(g));
analogWrite(BLUE_LED_PIN, RGB_calc(b));
}
void Switch_Status(struct status status) {
if (status.blink > 0) {
bool bstate = false;
for(int j=0; j<status.blink; j++) {
if (bstate) {
RGB_color(status.r, status.g, status.b);
} else {
RGB_color(0, 0, 0);
}
bstate = !bstate;
delay(500);
}
} else {
RGB_color(status.r, status.g, status.b);
}
strcpy(current_state, status.name);
}
bool Switch_Status(String name) {
Serial.println("Switching to " + name);
for(int j=0; j<STATUSES_COUNT; j++) {
if (String(statuses[j].name) == name) {
Switch_Status(statuses[j]);
return true;
}
}
return false;
}
#ifdef WEBSERVER
void IndexPage() {
char buffer[1024] = "<html><head><title>Busylight</title></head><body>";
for(int j=0; j<STATUSES_COUNT; j++) {
strcat(buffer, "<a href=/");
strcat(buffer, statuses[j].name);
strcat(buffer, ">");
strcat(buffer, statuses[j].name);
strcat(buffer, "</a><br/>");
}
strcat(buffer, "</body></html>");
server.send(200, "text/html", buffer);
}
void StatusLookup() {
if (Switch_Status(server.uri().substring(1))) {
server.send(204, "text/plain", "OK");
return;
}
server.send(404, "text/plain", "Missing");
}
#endif
#ifdef MQTT
void Pubsub_Callback(char* topic, byte* payload, unsigned int length) {
}
#endif
void setup()
{
Serial.begin(9600);
Serial.println("");
Serial.println("---");
pinMode(RED_LED_PIN, OUTPUT);
pinMode(GREEN_LED_PIN, OUTPUT);
pinMode(BLUE_LED_PIN, OUTPUT);
Serial.println("Config - Pins: (" + String(RED_LED_PIN) + "," + String(GREEN_LED_PIN) + "," + String(BLUE_LED_PIN) + "), PWM: " + String(PWM_MAX_VALUE));
WiFi.begin(WIFI_SSID, WIFI_PASS);
Serial.print("Connecting to " + String(WIFI_SSID));
while(WiFi.status()!= WL_CONNECTED)
{
Serial.print(".");
delay(500);
}
Serial.println("");
Serial.print("IP Address: ");
Serial.println(WiFi.localIP());
digitalWrite(LED_BUILTIN, LOW);
Switch_Status("offline");
#ifdef MQTT
pubsub.setServer(MQTT_SERVER, MQTT_PORT);
pubsub.setCallback(Pubsub_Callback);
#endif
#ifdef WEBSERVER
server.on("/",IndexPage);
server.on("/health", [](){server.send(200,"text/plain","OK");});
server.on("/state", [](){server.send(200,"text/plain", current_state);});
server.onNotFound(StatusLookup);
server.begin();
#endif
}
void loop()
{
#ifdef MQTT
Serial.print("Connecting to MQTT ");
while (!pubsub.connected()) {
Serial.print(".");
if (pubsub.connect("Client")) {
Serial.println(" done.");
}
delay(500);
}
pubsub.loop();
#endif
#ifdef WEBSERVER
server.handleClient();
#endif
}

11
test/README Normal file
View File

@@ -0,0 +1,11 @@
This directory is intended for PlatformIO Unit Testing and project tests.
Unit Testing is a software testing method by which individual units of
source code, sets of one or more MCU program modules together with associated
control data, usage procedures, and operating procedures, are tested to
determine whether they are fit for use. Unit testing finds problems early
in the development cycle.
More information about PlatformIO Unit Testing:
- https://docs.platformio.org/page/plus/unit-testing.html