Compare commits
8 Commits
6ff3352c57
...
master
Author | SHA1 | Date | |
---|---|---|---|
1558beaaf2 | |||
1b35c285df | |||
f39713d97e | |||
816ae120a2 | |||
fb8788420d | |||
7941d32984 | |||
2a5876ef77 | |||
c145e6aee8 |
@@ -1,5 +1,8 @@
|
|||||||
extern Adafruit_SSD1306 display; // Reference to the OLED display object
|
extern Adafruit_SSD1306 display; // Reference to the OLED display object
|
||||||
|
extern unsigned long lastRefresh;
|
||||||
|
extern const unsigned long refreshInterval;
|
||||||
bool is_display_off = false; // State variable to track display on/off status
|
bool is_display_off = false; // State variable to track display on/off status
|
||||||
|
bool is_sound_off = false; // State variable to track display on/off status
|
||||||
|
|
||||||
int buttonDebounceDelay = 50; // Debounce delay in milliseconds
|
int buttonDebounceDelay = 50; // Debounce delay in milliseconds
|
||||||
int buttonLongPressDelay = 2000; // Long press threshold in milliseconds
|
int buttonLongPressDelay = 2000; // Long press threshold in milliseconds
|
||||||
@@ -29,7 +32,10 @@ void cubeButtonHandler() {
|
|||||||
if (!leftBeeped) {
|
if (!leftBeeped) {
|
||||||
beep(1000); // Play beep for a short press
|
beep(1000); // Play beep for a short press
|
||||||
leftBeeped = true; // Mark as beeped to avoid repeat beeps
|
leftBeeped = true; // Mark as beeped to avoid repeat beeps
|
||||||
// Handle left short press action here
|
if (is_sound_off) {
|
||||||
|
is_sound_off = false; // Update display state
|
||||||
|
beep(1600); // Additional beep to confirm display is on
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -43,7 +49,7 @@ void cubeButtonHandler() {
|
|||||||
if (!middleBeeped) {
|
if (!middleBeeped) {
|
||||||
beep(1000); // Play beep for a short press
|
beep(1000); // Play beep for a short press
|
||||||
middleBeeped = true; // Mark as beeped to avoid repeat beeps
|
middleBeeped = true; // Mark as beeped to avoid repeat beeps
|
||||||
// Handle middle short press action here
|
lastRefresh = millis() + refreshInterval + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -71,10 +77,10 @@ void cubeButtonHandler() {
|
|||||||
|
|
||||||
// Long press detection for left button
|
// Long press detection for left button
|
||||||
if (leftPressed && (currentMillis - leftPressStart > buttonLongPressDelay)) {
|
if (leftPressed && (currentMillis - leftPressStart > buttonLongPressDelay)) {
|
||||||
if (!leftBeeped) {
|
if (!is_sound_off) { // Turn off the display if it's on
|
||||||
beep(1000); // Play beep for a long press
|
beep(1400); // Beep to indicate display turn-off
|
||||||
leftBeeped = true; // Mark as beeped to avoid repeat beeps
|
is_sound_off = true; // Update display state
|
||||||
// Handle left long press action here
|
beep(1000); // Additional beep to confirm display is off
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
142
src/main.cpp
142
src/main.cpp
@@ -2,7 +2,7 @@
|
|||||||
#include <Adafruit_SSD1306.h>
|
#include <Adafruit_SSD1306.h>
|
||||||
#include <ESP8266HTTPClient.h>
|
#include <ESP8266HTTPClient.h>
|
||||||
#include <ArduinoJson.h>
|
#include <ArduinoJson.h>
|
||||||
#include "example_config.h"
|
#include "config.h"
|
||||||
#include "SmartCube/cubeSound.h"
|
#include "SmartCube/cubeSound.h"
|
||||||
#include "SmartCube/cubeButtons.h"
|
#include "SmartCube/cubeButtons.h"
|
||||||
#include "SmartCube/cubeWifiManager.h"
|
#include "SmartCube/cubeWifiManager.h"
|
||||||
@@ -12,15 +12,23 @@ cubeWifiManager cubeWifiManager(display);
|
|||||||
|
|
||||||
unsigned long lastRefresh = 0;
|
unsigned long lastRefresh = 0;
|
||||||
const unsigned long refreshInterval = 60000; // 60 seconds
|
const unsigned long refreshInterval = 60000; // 60 seconds
|
||||||
unsigned long lastDisplayUpdate = 0;
|
|
||||||
const unsigned long displayInterval = 100; // 100 ms
|
|
||||||
|
|
||||||
String lastEventId = "";
|
String lastEventId = "";
|
||||||
String problems[10];
|
String problems[10];
|
||||||
String problemDescriptions;
|
String problemDescriptions;
|
||||||
int problemCount = 0;
|
int problemCount = 0;
|
||||||
int severityCounts[5] = {0};
|
int severityCounts[6] = {0};
|
||||||
bool newProblemsDetected = false;
|
bool newProblemsDetected = false;
|
||||||
|
int totalProblems = 0; // Variable to store the total number of active problems
|
||||||
|
|
||||||
|
// History buffer for the graph
|
||||||
|
const int maxHistorySize = 60;
|
||||||
|
int problemHistory[maxHistorySize] = {0}; // Array to store history
|
||||||
|
int historyIndex = 0; // Current index for the latest value
|
||||||
|
|
||||||
|
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 = 120; // Delay in milliseconds between scroll updates
|
||||||
|
|
||||||
void initSystems() {
|
void initSystems() {
|
||||||
pinMode(PIN_BTN_L, INPUT);
|
pinMode(PIN_BTN_L, INPUT);
|
||||||
@@ -33,9 +41,10 @@ void initSystems() {
|
|||||||
Wire.setClock(400000L); // Set I2C to Fast Mode (400 kHz)
|
Wire.setClock(400000L); // Set I2C to Fast Mode (400 kHz)
|
||||||
display.ssd1306_command(SSD1306_SETCONTRAST);
|
display.ssd1306_command(SSD1306_SETCONTRAST);
|
||||||
display.ssd1306_command(200); // Value between 0 and 255
|
display.ssd1306_command(200); // Value between 0 and 255
|
||||||
|
|
||||||
// Initialize the SSD1306 display
|
// Initialize the SSD1306 display
|
||||||
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
|
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Adjust I2C address if needed
|
||||||
for(;;); // Don't proceed, loop forever
|
for (;;); // Don't proceed, loop forever
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rotate the display 180 degrees
|
// Rotate the display 180 degrees
|
||||||
@@ -49,16 +58,15 @@ void initSystems() {
|
|||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
int totalProblems = 0; // Variable to store the total number of active problems
|
|
||||||
|
|
||||||
void fetchActiveProblems() {
|
void fetchActiveProblems() {
|
||||||
WiFiClient client;
|
WiFiClient client;
|
||||||
HTTPClient http;
|
HTTPClient http;
|
||||||
http.begin(client, zabbixServer);
|
http.begin(client, zabbixServer);
|
||||||
|
http.setTimeout(5000); // 5-second timeout
|
||||||
http.addHeader("Content-Type", "application/json");
|
http.addHeader("Content-Type", "application/json");
|
||||||
|
|
||||||
// JSON payload
|
// JSON payload
|
||||||
DynamicJsonDocument doc(1024);
|
DynamicJsonDocument doc(2048); // Increased to avoid memory issues
|
||||||
doc["jsonrpc"] = "2.0";
|
doc["jsonrpc"] = "2.0";
|
||||||
doc["method"] = "problem.get";
|
doc["method"] = "problem.get";
|
||||||
doc["id"] = 1;
|
doc["id"] = 1;
|
||||||
@@ -79,85 +87,135 @@ void fetchActiveProblems() {
|
|||||||
String response = http.getString();
|
String response = http.getString();
|
||||||
|
|
||||||
// Parse response
|
// Parse response
|
||||||
DynamicJsonDocument responseDoc(4096);
|
DynamicJsonDocument responseDoc(8192); // Increased size to fit more data
|
||||||
deserializeJson(responseDoc, response);
|
DeserializationError error = deserializeJson(responseDoc, response);
|
||||||
|
|
||||||
|
if (!error) {
|
||||||
JsonArray result = responseDoc["result"].as<JsonArray>();
|
JsonArray result = responseDoc["result"].as<JsonArray>();
|
||||||
int newProblemCount = 0;
|
|
||||||
memset(severityCounts, 0, sizeof(severityCounts)); // Reset severities
|
// Clear descriptions and severity counts
|
||||||
|
memset(severityCounts, 0, sizeof(severityCounts));
|
||||||
|
problemDescriptions = ""; // Reset before appending
|
||||||
|
|
||||||
totalProblems = result.size(); // Set total problems count
|
totalProblems = result.size(); // Set total problems count
|
||||||
|
|
||||||
|
// Store the current totalProblems in the history buffer
|
||||||
|
problemHistory[historyIndex] = totalProblems;
|
||||||
|
historyIndex = (historyIndex + 1) % maxHistorySize; // Circular buffer
|
||||||
|
|
||||||
|
int newProblemCount = 0;
|
||||||
for (JsonObject problem : result) {
|
for (JsonObject problem : result) {
|
||||||
String eventId = problem["eventid"].as<String>();
|
String eventId = problem["eventid"].as<String>();
|
||||||
int severity = problem["severity"].as<int>();
|
int severity = problem["severity"].as<int>();
|
||||||
String description = problem["name"].as<String>();
|
String description = problem["name"].as<String>();
|
||||||
|
|
||||||
// Check for new problems by comparing event IDs as integers
|
// Check for new problems by comparing event IDs
|
||||||
if (eventId.toInt() > lastEventId.toInt()) {
|
if (eventId.toInt() > lastEventId.toInt()) {
|
||||||
newProblemsDetected = true;
|
newProblemsDetected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add new problem descriptions to the array
|
|
||||||
if (newProblemCount < 10) {
|
|
||||||
problems[newProblemCount] = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Count severities
|
|
||||||
if (severity >= 0 && severity < 5) {
|
if (severity >= 0 && severity < 5) {
|
||||||
severityCounts[severity]++;
|
severityCounts[severity]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
problemDescriptions += description + " "; // Append description with space for better display
|
||||||
newProblemCount++;
|
newProblemCount++;
|
||||||
problemDescriptions += description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
problemCount = newProblemCount;
|
problemCount = newProblemCount;
|
||||||
|
|
||||||
// Update lastEventId after processing the most recent event
|
|
||||||
if (problemCount > 0) {
|
if (problemCount > 0) {
|
||||||
lastEventId = result[0]["eventid"].as<String>();
|
lastEventId = result[0]["eventid"].as<String>();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
beep(2000);
|
beep(1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
problemDescriptions="Zabbix API error";
|
||||||
}
|
}
|
||||||
|
|
||||||
http.end();
|
http.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
int scrollPos = SCREEN_WIDTH; // Global variable to keep track of the scroll position
|
void playAlertMelody() {
|
||||||
unsigned long lastScrollTime = 0; // To control the scroll speed
|
int toneDuration = 60; // Each tone lasts 150ms
|
||||||
const int scrollDelay = 150; // Delay in milliseconds between scroll updates
|
int pauseDuration = 30; // Pause between tones
|
||||||
|
|
||||||
|
// Play first tone
|
||||||
|
tone(PIN_BUZZER, 1500); // 1000 Hz
|
||||||
|
delay(toneDuration);
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
delay(pauseDuration);
|
||||||
|
|
||||||
|
// Play second tone
|
||||||
|
tone(PIN_BUZZER, 1200); // 1200 Hz
|
||||||
|
delay(toneDuration);
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
delay(pauseDuration);
|
||||||
|
|
||||||
|
// Play third tone
|
||||||
|
tone(PIN_BUZZER, 1500); // 1500 Hz
|
||||||
|
delay(toneDuration);
|
||||||
|
noTone(PIN_BUZZER);
|
||||||
|
}
|
||||||
|
|
||||||
void displayProblems() {
|
void displayProblems() {
|
||||||
display.clearDisplay();
|
display.clearDisplay();
|
||||||
display.setTextSize(1);
|
display.setTextSize(1);
|
||||||
display.setCursor(0,0);
|
display.setCursor(0, 0);
|
||||||
display.print("Total Problems: ");
|
display.printf("I:%d W:%d A:%d H:%d D:%d",
|
||||||
display.print(totalProblems); // Display total problems
|
severityCounts[1],
|
||||||
|
severityCounts[2],
|
||||||
|
severityCounts[3],
|
||||||
|
severityCounts[4],
|
||||||
|
severityCounts[5]);
|
||||||
|
if (is_sound_off) {
|
||||||
|
display.setCursor(122, 0);
|
||||||
|
display.print("X");
|
||||||
|
}
|
||||||
|
display.drawLine(0, 45, 127, 45, 1); // Line under the graph
|
||||||
|
display.drawLine(0, 9, 127, 9, 1); // Line under the graph
|
||||||
|
|
||||||
|
// Draw the history graph
|
||||||
|
int graphHeight = 30; // Height of the graph
|
||||||
|
int graphTop = 14; // Top position of the graph
|
||||||
|
int graphBottom = graphTop + graphHeight;
|
||||||
|
|
||||||
|
int maxProblems = *std::max_element(problemHistory, problemHistory + maxHistorySize); // Find max for scaling
|
||||||
|
if (maxProblems == 0) maxProblems = 1; // Avoid division by zero
|
||||||
|
|
||||||
|
for (int i = 0; i < maxHistorySize - 1; i++) {
|
||||||
|
int x1 = (i * SCREEN_WIDTH) / maxHistorySize;
|
||||||
|
int x2 = ((i + 1) * SCREEN_WIDTH) / maxHistorySize;
|
||||||
|
|
||||||
|
int y1 = graphBottom - (problemHistory[(historyIndex + i) % maxHistorySize] * graphHeight) / maxProblems;
|
||||||
|
int y2 = graphBottom - (problemHistory[(historyIndex + i + 1) % maxHistorySize] * graphHeight) / maxProblems;
|
||||||
|
|
||||||
|
display.drawLine(x1, y1, x2, y2, 1); // Draw line between points
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scroll text below the graph
|
||||||
|
int stateWidth = strlen(problemDescriptions.c_str()) * 12;
|
||||||
|
|
||||||
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 (!is_display_off) {
|
||||||
if (millis() - lastScrollTime > scrollDelay) {
|
if (millis() - lastScrollTime > scrollDelay) {
|
||||||
// Update scroll position
|
scrollPos -= 11;
|
||||||
scrollPos -= 11; // Move left by 1 pixel each time
|
|
||||||
|
|
||||||
lastScrollTime = millis();
|
lastScrollTime = millis();
|
||||||
|
|
||||||
// If the text has completely scrolled off, reset scroll position to start from the right
|
|
||||||
if (scrollPos < -stateWidth) {
|
if (scrollPos < -stateWidth) {
|
||||||
scrollPos = SCREEN_WIDTH;
|
scrollPos = SCREEN_WIDTH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Draw the file name with current scroll position
|
|
||||||
display.setTextSize(2);
|
|
||||||
display.setCursor(scrollPos, 54);
|
|
||||||
display.print(problemDescriptions);
|
|
||||||
display.setCursor(0, 44);
|
|
||||||
display.setTextSize(1);
|
|
||||||
|
|
||||||
|
display.setTextSize(2);
|
||||||
|
display.setCursor(scrollPos, 48);
|
||||||
|
display.print(problemDescriptions);
|
||||||
|
display.setTextSize(1);
|
||||||
|
display.fillRect(112,35,16,11,0);
|
||||||
|
display.drawRect(112,35,16,11,1);
|
||||||
|
display.setCursor(114,37);
|
||||||
|
display.print(totalProblems);
|
||||||
display.display();
|
display.display();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -178,8 +236,8 @@ void loop() {
|
|||||||
|
|
||||||
displayProblems();
|
displayProblems();
|
||||||
|
|
||||||
if (newProblemsDetected) {
|
if (newProblemsDetected && !is_sound_off) {
|
||||||
beep(1000);
|
playAlertMelody();
|
||||||
newProblemsDetected = false;
|
newProblemsDetected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
Reference in New Issue
Block a user