2024-11-26 20:50:30 +01:00
|
|
|
#include <Arduino.h>
|
|
|
|
#include <Adafruit_SSD1306.h>
|
|
|
|
#include <ESP8266HTTPClient.h>
|
|
|
|
#include <ArduinoJson.h>
|
2024-11-27 18:49:39 +01:00
|
|
|
#include "config.h"
|
2024-11-26 20:50:30 +01:00
|
|
|
#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
|
|
|
|
|
|
|
|
String lastEventId = "";
|
|
|
|
String problems[10];
|
2024-11-27 18:49:39 +01:00
|
|
|
String problemDescriptions = "Test";
|
2024-11-26 20:50:30 +01:00
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
int totalProblems = 0; // Variable to store the total number of active problems
|
|
|
|
|
2024-11-26 20:50:30 +01:00
|
|
|
void fetchActiveProblems() {
|
|
|
|
WiFiClient client;
|
|
|
|
HTTPClient http;
|
|
|
|
http.begin(client, zabbixServer);
|
2024-11-27 18:49:39 +01:00
|
|
|
http.setTimeout(5000); // 5-second timeout
|
2024-11-26 20:50:30 +01:00
|
|
|
http.addHeader("Content-Type", "application/json");
|
|
|
|
|
|
|
|
// JSON payload
|
2024-11-27 18:49:39 +01:00
|
|
|
DynamicJsonDocument doc(2048); // Increased to avoid memory issues
|
2024-11-26 20:50:30 +01:00
|
|
|
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
|
2024-11-27 18:49:39 +01:00
|
|
|
DynamicJsonDocument responseDoc(8192); // Increased size to fit more data
|
|
|
|
DeserializationError error = deserializeJson(responseDoc, response);
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-27 18:49:39 +01:00
|
|
|
if (!error) {
|
|
|
|
JsonArray result = responseDoc["result"].as<JsonArray>();
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-27 18:49:39 +01:00
|
|
|
// Clear descriptions and severity counts
|
|
|
|
memset(severityCounts, 0, sizeof(severityCounts));
|
|
|
|
problemDescriptions = ""; // Reset before appending
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-27 18:49:39 +01:00
|
|
|
totalProblems = result.size(); // Set total problems count
|
|
|
|
|
|
|
|
int newProblemCount = 0;
|
|
|
|
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
|
|
|
|
if (eventId.toInt() > lastEventId.toInt()) {
|
|
|
|
newProblemsDetected = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (newProblemCount < 10) {
|
|
|
|
problems[newProblemCount] = description;
|
|
|
|
}
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-27 18:49:39 +01:00
|
|
|
if (severity >= 0 && severity < 5) {
|
|
|
|
severityCounts[severity]++;
|
|
|
|
}
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-27 18:49:49 +01:00
|
|
|
problemDescriptions += description + " "; // Append description with space for better display
|
2024-11-27 18:49:39 +01:00
|
|
|
newProblemCount++;
|
|
|
|
}
|
|
|
|
|
|
|
|
problemCount = newProblemCount;
|
|
|
|
|
|
|
|
if (problemCount > 0) {
|
|
|
|
lastEventId = result[0]["eventid"].as<String>();
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
beep(1000);
|
2024-11-26 20:50:30 +01:00
|
|
|
}
|
2024-11-27 18:49:39 +01:00
|
|
|
} else {
|
|
|
|
display.clearDisplay();
|
|
|
|
display.setCursor(0,30);
|
|
|
|
display.print("Error querying zabbix API");
|
2024-11-26 20:50:30 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
http.end();
|
|
|
|
}
|
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
int scrollPos = SCREEN_WIDTH; // Global variable to keep track of the scroll position
|
|
|
|
unsigned long lastScrollTime = 0; // To control the scroll speed
|
|
|
|
const int scrollDelay = 150; // Delay in milliseconds between scroll updates
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
void displayProblems() {
|
2024-11-26 20:50:30 +01:00
|
|
|
display.clearDisplay();
|
|
|
|
display.setTextSize(1);
|
2024-11-26 22:10:51 +01:00
|
|
|
display.setCursor(0,0);
|
|
|
|
display.print("Total Problems: ");
|
|
|
|
display.print(totalProblems); // Display total problems
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
int stateWidth = strlen(problemDescriptions.c_str()) * 12; // Approximate width of the status text in pixels
|
|
|
|
// Scroll the text to the left
|
|
|
|
if (!is_display_off) {
|
|
|
|
if (millis() - lastScrollTime > scrollDelay) {
|
|
|
|
// Update scroll position
|
|
|
|
scrollPos -= 11; // Move left by 1 pixel each time
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
lastScrollTime = millis();
|
2024-11-26 20:50:30 +01:00
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
// If the text has completely scrolled off, reset scroll position to start from the right
|
|
|
|
if (scrollPos < -stateWidth) {
|
2024-11-26 20:50:30 +01:00
|
|
|
scrollPos = SCREEN_WIDTH;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2024-11-26 22:10:51 +01:00
|
|
|
// Draw the file name with current scroll position
|
|
|
|
display.setTextSize(2);
|
2024-11-27 18:49:49 +01:00
|
|
|
display.setCursor(scrollPos, 48);
|
2024-11-26 22:10:51 +01:00
|
|
|
display.print(problemDescriptions);
|
2024-11-27 18:49:49 +01:00
|
|
|
display.drawLine(0,46,127,46,1);
|
2024-11-26 22:10:51 +01:00
|
|
|
|
2024-11-26 20:50:30 +01:00
|
|
|
display.display();
|
|
|
|
}
|
|
|
|
|
|
|
|
void setup() {
|
|
|
|
initSystems();
|
|
|
|
cubeWifiManager.start();
|
|
|
|
fetchActiveProblems();
|
|
|
|
}
|
|
|
|
|
|
|
|
void loop() {
|
|
|
|
unsigned long currentMillis = millis();
|
|
|
|
cubeButtonHandler();
|
|
|
|
|
2024-11-26 22:10:51 +01:00
|
|
|
if (!is_display_off && currentMillis - lastRefresh >= refreshInterval) {
|
2024-11-26 20:50:30 +01:00
|
|
|
lastRefresh = currentMillis;
|
|
|
|
fetchActiveProblems();
|
|
|
|
}
|
|
|
|
|
|
|
|
displayProblems();
|
|
|
|
|
|
|
|
if (newProblemsDetected) {
|
|
|
|
beep(1000);
|
|
|
|
newProblemsDetected = false;
|
|
|
|
}
|
|
|
|
}
|