Created
December 2, 2023 09:11
-
-
Save asonas/20d3e9fa1a740e93e7382ee174e65921 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <algorithm> | |
#include <iomanip> | |
#include <sstream> | |
#include <string> | |
#include <vector> | |
#include <M5Stack.h> | |
#include <WiFi.h> | |
#include <WiFiClientSecure.h> | |
#include <NTPClient.h> | |
#include <WiFiUdp.h> | |
#include "encodeURIComponent.h" | |
const char* ssid = ""; | |
const char* password = ""; | |
const char* slackWebhookUrl = "https://hooks.slack.com/***"; | |
unsigned long lastButtonPressTime = 0; | |
void setup() { | |
M5.begin(); | |
Serial.begin(115200); | |
M5.Lcd.fillScreen(0x000000); | |
M5.Lcd.setTextSize(3); | |
M5.Lcd.setTextColor(TFT_WHITE); | |
// WiFi接続 | |
WiFi.begin(ssid, password); | |
while (WiFi.status() != WL_CONNECTED) { | |
delay(1000); | |
Serial.println("Connecting to WiFi..."); | |
} | |
Serial.println("Connected to WiFi"); | |
configTime(9 * 3600, 0, "pool.ntp.org"); | |
while (!time(nullptr)) { | |
Serial.println("Waiting for NTP time sync..."); | |
delay(1000); | |
} | |
lastButtonPressTime = millis(); | |
} | |
void loop() { | |
M5.update(); | |
// ボタンが押されたかどうかの判定 | |
if (M5.BtnA.wasPressed()) { | |
Serial.println("BtnA"); | |
postMessage("排水ネット交換したよ!"); | |
displayMessage("Exchanged!", 2000); | |
lastButtonPressTime = millis(); | |
} | |
if (millis() - lastButtonPressTime >= 7 * 24 * 60 * 60 * 1000UL) { | |
postMessage("排水ネットを交換してから1週間立ったよ"); | |
} | |
M5.Lcd.setTextSize(2); | |
displayElapsedTime(); | |
M5.Lcd.setTextSize(3); | |
displayTime(); | |
delay(1000); | |
} | |
void postMessage(const char* message) { | |
std::ostringstream encoded, payload; | |
encodeURIComponent(message, encoded); | |
payload << R"(payload={"text": ")" << encoded.str() << R"("})"; | |
sendSlackMessage(payload.str()); | |
} | |
void sendSlackMessage(const std::string& payload) { | |
WiFiClientSecure client; | |
client.setInsecure(); | |
if (client.connect("hooks.slack.com", 443)) { | |
Serial.println("Connected to server!"); | |
// HTTP POSTリクエストの構築 | |
std::ostringstream request; | |
request << "POST /services/T0298QA7G/B067UA3QRT9/IodWyfwbRlpYb9dHh5jxspsd HTTP/1.1\r\n" | |
<< "Host: hooks.slack.com\r\n" | |
<< "User-Agent: WiFiClientSecure\r\n" | |
<< "Content-Type: application/x-www-form-urlencoded\r\n" | |
<< "Content-Length: " << payload.length() << "\r\n\r\n" | |
<< payload; | |
Serial.println("Sending Slack message:"); | |
Serial.println(request.str().c_str()); | |
// データの送信 | |
client.print(request.str().c_str()); | |
client.println(); | |
while (client.connected()) { | |
String line = client.readStringUntil('\n'); | |
if (line == "\r") { | |
Serial.println("headers received"); | |
break; | |
} | |
} | |
while (client.available()) { | |
char c = client.read(); | |
Serial.write(c); | |
} | |
// 接続を閉じる | |
client.stop(); | |
} else { | |
Serial.println("Connection failed!"); | |
} | |
} | |
void displayTime() { | |
time_t now; | |
struct tm timeinfo; | |
char formattedDate[16]; | |
char formattedTime[16]; | |
time(&now); | |
localtime_r(&now, &timeinfo); | |
strftime(formattedDate, sizeof(formattedDate), "%Y/%m/%d", &timeinfo); | |
strftime(formattedTime, sizeof(formattedTime), "%H:%M:%S", &timeinfo); | |
int textWidth = M5.Lcd.textWidth(formattedDate); | |
int textX = (M5.Lcd.width() - textWidth) / 2; | |
int textY = M5.Lcd.height() / 2 - 30; | |
M5.Lcd.fillRect(0, textY - 2, M5.Lcd.width(), 55, TFT_BLACK); | |
M5.Lcd.setCursor(textX, textY); | |
M5.Lcd.println(formattedDate); | |
textWidth = M5.Lcd.textWidth(formattedTime); | |
textX = (M5.Lcd.width() - textWidth) / 2; | |
textY += 30; | |
M5.Lcd.setCursor(textX, textY); | |
M5.Lcd.println(formattedTime); | |
} | |
void displayElapsedTime() { | |
// 中央下部に前回交換からの経過時間を2行で表示 | |
unsigned long elapsedTime = (millis() - lastButtonPressTime) / 1000; // ミリ秒から秒に変換 | |
int days = elapsedTime / (24 * 60 * 60); | |
int hours = (elapsedTime % (24 * 60 * 60)) / 3600; | |
int minutes = (elapsedTime % 3600) / 60; | |
int seconds = elapsedTime % 60; | |
char elapsedMessage[64]; | |
char elapsedHours[32]; | |
sprintf(elapsedMessage, "%d days %02d:%02d:%02d", days, hours, minutes, seconds); | |
sprintf(elapsedHours, "since last maintenance."); | |
int textWidth = M5.Lcd.textWidth(elapsedMessage); | |
int textX = (M5.Lcd.width() - textWidth) / 2; | |
int textY = M5.Lcd.height() / 2 + 35; | |
M5.Lcd.fillRect(textX, textY, textWidth, M5.Lcd.fontHeight(), TFT_BLACK); | |
M5.Lcd.setCursor(textX, textY); | |
M5.Lcd.println(elapsedMessage); | |
textWidth = M5.Lcd.textWidth(elapsedHours); | |
textX = (M5.Lcd.width() - textWidth) / 2; | |
textY += 10; | |
M5.Lcd.setCursor(textX, textY); | |
M5.Lcd.println(elapsedHours); | |
} | |
void displayMessage(const char* message, int duration) { | |
// 画面の中央に表示 | |
int textWidth = M5.Lcd.textWidth(message); | |
int textX = (M5.Lcd.width() - textWidth) / 2; | |
int textY = M5.Lcd.height() / 2 - 10; | |
M5.Lcd.fillScreen(TFT_BLACK); | |
M5.Lcd.setCursor(textX, textY); | |
M5.Lcd.println(message); | |
delay(duration); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment