mirror of
https://github.com/nuttytree/ESPHome-Devices.git
synced 2024-08-30 18:12:19 +00:00
Finalize Scripture of the Day code
This commit is contained in:
parent
a160abeee4
commit
c4ea5150cc
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,5 +5,6 @@
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
/build/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
||||
|
@ -31,8 +31,8 @@
|
||||
> ### [Pool Pumps](./devices/pool_pumps.yaml)
|
||||
> This is a [Shelly 2.5 Double Relay Switch](https://www.amazon.com/gp/product/B07RRD13DJ/ref=ppx_yo_dt_b_search_asin_title?ie=UTF8&psc=1) that is controlling the main pump on my pool and the auxillary pump that runs the pool cleaner. It turns the pump on and off through out the day and off at night (when we are least likely to be using the pool and when you get the most heat/water loss if the pump is running) and turns on the cleaner for a couple of hours in the morning. It also has some modes for Off (during the winter) and Continous when I need extra cleaning.
|
||||
|
||||
> ### [Scripture of the Day](./devices/scripture_of_the_day.yaml)
|
||||
> This is a project I just started working on (and I am still waiting on the hardware to arrive from China). I am planning on building 2 of them as Christmas presents for my wife and son. It will consist of a [ESP8266 e-Paper Panel Driver Board](https://www.waveshare.com/e-paper-esp8266-driver-board.htm) powered by a [lithium battery](https://www.amazon.com/dp/B0867KDMY7/?coliid=IE0LBNACFHG4U&colid=1LOK862UA8LA0&psc=1&ref_=lv_ov_lig_dp_it) and [TP4056 lithium battery charger module](https://www.amazon.com/dp/B06XQRQR3Q/?coliid=I1B2ELKKLLKAK0&colid=1LOK862UA8LA0&psc=1&ref_=lv_ov_lig_dp_it) and driving a [Waveshare 7.5inch 800×480 E-Ink display](https://www.waveshare.com/7.5inch-e-paper.htm) all mounted inside a picture frame. The plan is to have it sit in deep-sleep most of the time but wake up every night, grab a random scripture from the [Our Manna Daily Verses API](http://www.ourmanna.com/verses/api/), update the display with the verse, and go back to sleep.
|
||||
> ### [Scripture of the Day Melissa](./devices/scripture_of_the_day_melissa.yaml)/[Scripture of the Day Mayson](./devices/scripture_of_the_day_mayson.yaml)
|
||||
> This is a project I just started working on recently, the code is complete but the build is not quite done. I am planning on building 2 of them as Christmas presents for my wife and son. It will consist of a [ESP32 e-Paper Panel Driver Board](https://www.waveshare.com/product/displays/e-paper-esp32-driver-board.htm) powered by a [lithium battery](https://www.amazon.com/dp/B0867KDMY7/?coliid=IE0LBNACFHG4U&colid=1LOK862UA8LA0&psc=1&ref_=lv_ov_lig_dp_it) and [TP4056 lithium battery charger module](https://www.amazon.com/dp/B06XQRQR3Q/?coliid=I1B2ELKKLLKAK0&colid=1LOK862UA8LA0&psc=1&ref_=lv_ov_lig_dp_it) and driving a [Waveshare 7.5inch 800×480 E-Ink display](https://www.waveshare.com/7.5inch-e-paper.htm) all mounted inside a wood frame I am building. The plan is to have it sit in deep-sleep most of the time but wake up every night, grab a random scripture from the [Our Manna Daily Verses API](http://www.ourmanna.com/verses/api/), update the display with the verse, and go back to sleep.
|
||||
|
||||
## Switches
|
||||
> I plan to use dimmer switches for anything that is dimmable just for consistency and you never know when you might want to have the ability to dim a light. However there are times when a dimmer isn't an option.
|
||||
|
9
components/wifi/wifi_dhcp.yaml
Normal file
9
components/wifi/wifi_dhcp.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
wifi:
|
||||
ssid: ${wifi_ssid}
|
||||
password: ${wifi_password}
|
||||
fast_connect: true
|
||||
power_save_mode: none
|
||||
ap:
|
||||
ssid: ${device_id}
|
||||
|
||||
captive_portal:
|
146
custom/scripture_of_the_day.h
Normal file
146
custom/scripture_of_the_day.h
Normal file
@ -0,0 +1,146 @@
|
||||
#include "esphome.h"
|
||||
#include <ArduinoJson.h>
|
||||
#include <sstream>
|
||||
|
||||
using namespace esphome;
|
||||
|
||||
#define SCRIPTURE_URL "http://beta.ourmanna.com/api/v1/get/?format=json&order=random"
|
||||
#define MAX_VERSE_LINES 8
|
||||
#define MAX_CHAR_PER_LINE 35
|
||||
#define STARTING_POSITION 40
|
||||
#define SPACE_BETWEEN_LINES 50
|
||||
#define JSON_BUFFER_SIZE (JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(4) + JSON_OBJECT_SIZE(1))
|
||||
|
||||
class ScriptureOfTheDay : public Component {
|
||||
public:
|
||||
float get_setup_priority() const override { return setup_priority::LATE; }
|
||||
void setup() override { update_at_ = millis() + 4000; }
|
||||
void loop() override;
|
||||
|
||||
void set_http_request(http_request::HttpRequestComponent *http_request) { http_request_ = http_request; }
|
||||
void set_display(waveshare_epaper::WaveshareEPaper *display) { display_ = display; }
|
||||
void set_deep_sleep(deep_sleep::DeepSleepComponent *deep_sleep) { deep_sleep_ = deep_sleep; }
|
||||
void set_sntp(sntp::SNTPComponent *sntp) { sntp_ = sntp; }
|
||||
void set_fonts(display::Font *verse_font, display::Font *reference_font) { verse_font_ = verse_font; reference_font_ = reference_font; }
|
||||
|
||||
void display_scripture();
|
||||
|
||||
protected:
|
||||
http_request::HttpRequestComponent *http_request_;
|
||||
waveshare_epaper::WaveshareEPaper *display_;
|
||||
deep_sleep::DeepSleepComponent *deep_sleep_;
|
||||
sntp::SNTPComponent *sntp_;
|
||||
display::Font *verse_font_;
|
||||
display::Font *reference_font_;
|
||||
|
||||
std::vector<std::string> scripture_;
|
||||
uint64_t update_at_;
|
||||
|
||||
std::vector<std::string> get_scripture();
|
||||
std::vector<std::string> split_verse_into_lines(std::string verse);
|
||||
void shutdown(uint32_t sleepSeconds = 0);
|
||||
};
|
||||
|
||||
void ScriptureOfTheDay::loop()
|
||||
{
|
||||
// If we try to make the request to soon it fails so we delay 4 seconds
|
||||
if (millis() > update_at_)
|
||||
{
|
||||
// If we get an especially long verse that won't fit on the display we try again.
|
||||
do
|
||||
{
|
||||
scripture_ = get_scripture();
|
||||
} while (scripture_.size() > MAX_VERSE_LINES + 1);
|
||||
|
||||
display_->update();
|
||||
|
||||
shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptureOfTheDay::display_scripture()
|
||||
{
|
||||
if (scripture_.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int verseLineCount = scripture_.size() - 1;
|
||||
int currentPosition = STARTING_POSITION + (SPACE_BETWEEN_LINES / 2) * (MAX_VERSE_LINES - verseLineCount);
|
||||
for (int i = 0; i < verseLineCount; i++)
|
||||
{
|
||||
ESP_LOGD("Nuttytree", scripture_[i].c_str());
|
||||
display_->print(400, currentPosition, verse_font_, TextAlign::CENTER, scripture_[i].c_str());
|
||||
currentPosition += SPACE_BETWEEN_LINES;
|
||||
}
|
||||
|
||||
display_->print(760, currentPosition, reference_font_, TextAlign::CENTER_RIGHT, scripture_[verseLineCount].c_str());
|
||||
}
|
||||
|
||||
std::vector<std::string> ScriptureOfTheDay::get_scripture()
|
||||
{
|
||||
http_request_->set_url(SCRIPTURE_URL);
|
||||
http_request_->set_method("GET");
|
||||
|
||||
http_request_->send();
|
||||
if (http_request_->status_has_warning())
|
||||
{
|
||||
// If the request failed we shutdown and try again in 15 minutes
|
||||
shutdown(15 * 60);
|
||||
}
|
||||
const char *json = http_request_->get_string();
|
||||
|
||||
DynamicJsonBuffer jsonBuffer(JSON_BUFFER_SIZE);
|
||||
JsonObject& scripture = jsonBuffer.parseObject(json);
|
||||
|
||||
http_request_->close();
|
||||
|
||||
std::vector<std::string> formattedScripture = split_verse_into_lines(std::string(scripture["verse"]["details"]["text"].as<char*>()));
|
||||
formattedScripture.push_back(std::string(scripture["verse"]["details"]["reference"].as<char*>()));
|
||||
|
||||
return formattedScripture;
|
||||
}
|
||||
|
||||
std::vector<std::string> ScriptureOfTheDay::split_verse_into_lines(std::string verse)
|
||||
{
|
||||
std::string word;
|
||||
std::string currentLine;
|
||||
std::vector<std::string> lines;
|
||||
std::istringstream ss(verse);
|
||||
|
||||
while (ss >> word)
|
||||
{
|
||||
if (currentLine.length() == 0)
|
||||
{
|
||||
currentLine = word;
|
||||
}
|
||||
else if (currentLine.length() + word.length() < MAX_CHAR_PER_LINE)
|
||||
{
|
||||
currentLine += " " + word;
|
||||
}
|
||||
else
|
||||
{
|
||||
lines.push_back(currentLine);
|
||||
currentLine = word;
|
||||
}
|
||||
}
|
||||
|
||||
lines.push_back(currentLine);
|
||||
|
||||
return lines;
|
||||
}
|
||||
|
||||
void ScriptureOfTheDay::shutdown(uint32_t sleepSeconds)
|
||||
{
|
||||
if (sleepSeconds == 0)
|
||||
{
|
||||
// Wake back up and update at 3AM
|
||||
time::ESPTime now = sntp_->now();
|
||||
sleepSeconds = 24 * 60 * 60 - (now.hour - 3) * 60 * 60 - now.minute * 60 - now.second;
|
||||
}
|
||||
|
||||
deep_sleep_->set_sleep_duration(sleepSeconds * 1000);
|
||||
deep_sleep_->begin_sleep(true);
|
||||
}
|
||||
|
||||
ScriptureOfTheDay *Scripture;
|
10
devices/.gitignore
vendored
10
devices/.gitignore
vendored
@ -1,10 +0,0 @@
|
||||
# Gitignore settings for ESPHome
|
||||
# This is an example and may include too much for your use-case.
|
||||
# You can modify this file to suit your needs.
|
||||
/.esphome/
|
||||
**/.pioenvs/
|
||||
**/.piolibdeps/
|
||||
**/lib/
|
||||
**/src/
|
||||
**/platformio.ini
|
||||
/secrets.yaml
|
@ -1,33 +0,0 @@
|
||||
substitutions:
|
||||
device_id: scripture_of_the_day_1
|
||||
device_name: Scripture of the Day #1
|
||||
platform: ESP8266
|
||||
board: nodemcuv2
|
||||
ip_address: !secret master_bath_humidity_temp_sensor_ip
|
||||
ota_pwd: !secret master_bath_humidity_temp_sensor_ota_pwd
|
||||
api_pwd: !secret master_bath_humidity_temp_sensor_api_pwd
|
||||
ap_wifi_pwd: !secret master_bath_humidity_temp_sensor_ap_wifi_pwd
|
||||
|
||||
esphome:
|
||||
<<: !include ../core/esphome.yaml
|
||||
on_boot:
|
||||
priority: -100
|
||||
then:
|
||||
- http_request.get:
|
||||
url: "https://beta.ourmanna.com/api/v1/get/?format=json&order=random"
|
||||
verify_ssl: false
|
||||
- lambda: |-
|
||||
auto json = http_request_httprequestcomponent->get_string();
|
||||
|
||||
<<: !include ../components/logger/logger_debug.yaml
|
||||
|
||||
<<: !include ../core/wifi_api_ota.yaml
|
||||
|
||||
http_request:
|
||||
|
||||
text_sensor:
|
||||
- platform: template
|
||||
id: scripture
|
||||
|
||||
- platform: template
|
||||
id: reference
|
7
devices/scripture_of_the_day_mayson.yaml
Normal file
7
devices/scripture_of_the_day_mayson.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
substitutions:
|
||||
device_id: scripture_of_the_day_mayson
|
||||
device_name: Scripture of the Day Mayson
|
||||
log_level: debug
|
||||
|
||||
packages:
|
||||
device_base: !include ../packages/scripture_of_the_day.yaml
|
7
devices/scripture_of_the_day_melissa.yaml
Normal file
7
devices/scripture_of_the_day_melissa.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
substitutions:
|
||||
device_id: scripture_of_the_day_melissa
|
||||
device_name: Scripture of the Day Melissa
|
||||
log_level: debug
|
||||
|
||||
packages:
|
||||
device_base: !include ../packages/scripture_of_the_day.yaml
|
75
packages/scripture_of_the_day.yaml
Normal file
75
packages/scripture_of_the_day.yaml
Normal file
@ -0,0 +1,75 @@
|
||||
substitutions:
|
||||
platform: ESP32
|
||||
board: esp32dev
|
||||
log_level: none
|
||||
wifi_ssid: !secret wifi_ssid
|
||||
wifi_password: !secret wifi_password
|
||||
|
||||
esphome:
|
||||
name: ${device_id}
|
||||
platform: ${platform}
|
||||
board: ${board}
|
||||
arduino_version: latest
|
||||
build_path: ../build/${device_id}
|
||||
includes:
|
||||
- ../custom/scripture_of_the_day.h
|
||||
# on_boot:
|
||||
# priority: -100
|
||||
# then:
|
||||
# - delay: 4s
|
||||
# - lambda: Scripture->update_scripture();
|
||||
|
||||
<<: !include ../components/wifi/wifi_dhcp.yaml
|
||||
|
||||
<<: !include ../components/logger/logger.yaml
|
||||
|
||||
custom_component:
|
||||
- lambda: |-
|
||||
Scripture = new ScriptureOfTheDay();
|
||||
Scripture->set_http_request(http_cmp);
|
||||
Scripture->set_display(the_display);
|
||||
Scripture->set_deep_sleep(deep_sleep_cmp);
|
||||
Scripture->set_sntp(sntp_cmp);
|
||||
Scripture->set_fonts(verse_font, reference_font);
|
||||
return {Scripture};
|
||||
|
||||
# Setting run duration to 15s, if we aren't done by then something went wrong so we restart to save battery
|
||||
# Setting a default sleep time of 15min that will only apply if we forced a shutdown after the 15s run duration
|
||||
deep_sleep:
|
||||
id: deep_sleep_cmp
|
||||
run_duration: 15s
|
||||
sleep_duration: 15min
|
||||
|
||||
display:
|
||||
- platform: waveshare_epaper
|
||||
id: the_display
|
||||
cs_pin: 15
|
||||
dc_pin: 27
|
||||
busy_pin: 25
|
||||
reset_pin: 26
|
||||
update_interval: 600s
|
||||
model: 7.50inV2
|
||||
lambda: |-
|
||||
Scripture->display_scripture();
|
||||
|
||||
font:
|
||||
- file: "c:/windows/fonts/segoeprb.ttf"
|
||||
id: verse_font
|
||||
size: 35
|
||||
glyphs: "~!&-;:\"',.?’—“”0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
|
||||
- file: "c:/windows/fonts/segoeprb.ttf"
|
||||
id: reference_font
|
||||
size: 30
|
||||
glyphs: "-:0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
http_request:
|
||||
id: http_cmp
|
||||
|
||||
spi:
|
||||
clk_pin: 13
|
||||
mosi_pin: 14
|
||||
|
||||
time:
|
||||
- platform: sntp
|
||||
id: sntp_cmp
|
||||
timezone: America/Chicago
|
Loading…
Reference in New Issue
Block a user