189 lines
4.8 KiB
C++
189 lines
4.8 KiB
C++
|
#include <Arduino.h>
|
||
|
#include <Adafruit_SSD1306.h>
|
||
|
#include <ESP8266HTTPClient.h>
|
||
|
#include <ArduinoJson.h>
|
||
|
#include "example_config.h"
|
||
|
#include "SmartCube/cubeSound.h"
|
||
|
#include "SmartCube/cubeButtons.h"
|
||
|
#include "SmartCube/cubeWifiManager.h"
|
||
|
|
||
|
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
|
||
|
cubeWifiManager cubeWifiManager(display);
|
||
|
|
||
|
unsigned long lastRefresh = 0;
|
||
|
const unsigned long refreshInterval = 60000; // 60 seconds
|
||
|
unsigned long lastDisplayUpdate = 0;
|
||
|
const unsigned long displayInterval = 100; // 100 ms
|
||
|
|
||
|
String lastEventId = "";
|
||
|
String problems[10];
|
||
|
int problemCount = 0;
|
||
|
int severityCounts[5] = {0};
|
||
|
bool newProblemsDetected = false;
|
||
|
|
||
|
void initSystems() {
|
||
|
pinMode(PIN_BTN_L, INPUT);
|
||
|
pinMode(PIN_BTN_M, INPUT);
|
||
|
pinMode(PIN_BTN_R, INPUT);
|
||
|
pinMode(PIN_BUZZER, OUTPUT);
|
||
|
pinMode(LED_BUILTIN, OUTPUT);
|
||
|
digitalWrite(LED_BUILTIN, HIGH);
|
||
|
Wire.begin(); // Initialize I2C
|
||
|
Wire.setClock(400000L); // Set I2C to Fast Mode (400 kHz)
|
||
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||
|
display.ssd1306_command(200); // Value between 0 and 255
|
||
|
// Initialize the SSD1306 display
|
||
|
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
|
||
|
for(;;); // Don't proceed, loop forever
|
||
|
}
|
||
|
|
||
|
// Rotate the display 180 degrees
|
||
|
display.setRotation(2);
|
||
|
|
||
|
// Clear the display buffer
|
||
|
display.clearDisplay();
|
||
|
display.setTextSize(1);
|
||
|
display.setTextColor(WHITE);
|
||
|
display.setCursor(0, 0);
|
||
|
display.display();
|
||
|
}
|
||
|
|
||
|
void fetchActiveProblems() {
|
||
|
WiFiClient client;
|
||
|
HTTPClient http;
|
||
|
http.begin(client, zabbixServer);
|
||
|
http.addHeader("Content-Type", "application/json");
|
||
|
|
||
|
// JSON payload
|
||
|
DynamicJsonDocument doc(512);
|
||
|
doc["jsonrpc"] = "2.0";
|
||
|
doc["method"] = "problem.get";
|
||
|
doc["id"] = 1;
|
||
|
doc["auth"] = zabbixToken;
|
||
|
JsonObject params = doc["params"].to<JsonObject>();
|
||
|
params["output"] = "extend";
|
||
|
params["recent"] = true;
|
||
|
params["sortfield"] = "eventid";
|
||
|
params["sortorder"] = "DESC";
|
||
|
|
||
|
String requestBody;
|
||
|
serializeJson(doc, requestBody);
|
||
|
|
||
|
// POST request
|
||
|
int httpResponseCode = http.POST(requestBody);
|
||
|
|
||
|
if (httpResponseCode > 0) {
|
||
|
String response = http.getString();
|
||
|
|
||
|
// Parse response
|
||
|
DynamicJsonDocument responseDoc(4096);
|
||
|
deserializeJson(responseDoc, response);
|
||
|
|
||
|
JsonArray result = responseDoc["result"].as<JsonArray>();
|
||
|
int newProblemCount = 0;
|
||
|
memset(severityCounts, 0, sizeof(severityCounts)); // Reset severities
|
||
|
|
||
|
for (JsonObject problem : result) {
|
||
|
String eventId = problem["eventid"].as<String>();
|
||
|
int severity = problem["severity"].as<int>();
|
||
|
String description = problem["name"].as<String>();
|
||
|
|
||
|
// Check for new problems by comparing event IDs as integers
|
||
|
if (eventId.toInt() > lastEventId.toInt()) {
|
||
|
newProblemsDetected = true;
|
||
|
}
|
||
|
|
||
|
// Add new problem descriptions to the array
|
||
|
if (newProblemCount < 10) {
|
||
|
problems[newProblemCount] = description;
|
||
|
}
|
||
|
|
||
|
// Count severities
|
||
|
if (severity >= 0 && severity < 5) {
|
||
|
severityCounts[severity]++;
|
||
|
}
|
||
|
|
||
|
newProblemCount++;
|
||
|
}
|
||
|
|
||
|
problemCount = newProblemCount;
|
||
|
|
||
|
// Update lastEventId after processing the most recent event
|
||
|
if (problemCount > 0) {
|
||
|
lastEventId = result[0]["eventid"].as<String>();
|
||
|
}
|
||
|
} else {
|
||
|
beep(2000);
|
||
|
}
|
||
|
|
||
|
http.end();
|
||
|
}
|
||
|
|
||
|
void displayProblems() {
|
||
|
static int scrollPos = SCREEN_WIDTH;
|
||
|
static unsigned long lastScrollTime = 0;
|
||
|
|
||
|
if (millis() - lastDisplayUpdate < displayInterval) {
|
||
|
return; // Skip rendering if the display interval hasn't elapsed
|
||
|
}
|
||
|
lastDisplayUpdate = millis();
|
||
|
|
||
|
display.clearDisplay();
|
||
|
|
||
|
// Header
|
||
|
display.setTextSize(1);
|
||
|
display.setCursor(0, 0);
|
||
|
display.print("Problems: ");
|
||
|
display.print(problemCount);
|
||
|
|
||
|
// Display severity counts (S0 to S4)
|
||
|
for (int i = 0; i < 5; i++) {
|
||
|
display.setCursor(0, 10 + (i * 10));
|
||
|
display.printf("S%d: %d", i, severityCounts[i]);
|
||
|
}
|
||
|
|
||
|
// Scrolling description of the first problem
|
||
|
if (problemCount > 0) {
|
||
|
String problemText = problems[0];
|
||
|
int16_t x1, y1;
|
||
|
uint16_t textWidth, textHeight;
|
||
|
display.getTextBounds(problemText, 0, 55, &x1, &y1, &textWidth, &textHeight);
|
||
|
|
||
|
if (millis() - lastScrollTime > 100) {
|
||
|
scrollPos -= 2;
|
||
|
if (scrollPos < -textWidth) {
|
||
|
scrollPos = SCREEN_WIDTH;
|
||
|
}
|
||
|
lastScrollTime = millis();
|
||
|
}
|
||
|
|
||
|
display.setTextSize(1);
|
||
|
display.setCursor(scrollPos, 55);
|
||
|
display.print(problemText);
|
||
|
}
|
||
|
|
||
|
display.display();
|
||
|
}
|
||
|
|
||
|
void setup() {
|
||
|
initSystems();
|
||
|
cubeWifiManager.start();
|
||
|
fetchActiveProblems();
|
||
|
}
|
||
|
|
||
|
void loop() {
|
||
|
unsigned long currentMillis = millis();
|
||
|
cubeButtonHandler();
|
||
|
|
||
|
if (currentMillis - lastRefresh >= refreshInterval) {
|
||
|
lastRefresh = currentMillis;
|
||
|
fetchActiveProblems();
|
||
|
}
|
||
|
|
||
|
displayProblems();
|
||
|
|
||
|
if (newProblemsDetected) {
|
||
|
beep(1000);
|
||
|
newProblemsDetected = false;
|
||
|
}
|
||
|
}
|