Initial System Monitor Code

This commit is contained in:
Blaster4385 2023-05-20 12:45:38 +05:30
commit 5fd76b071a
9 changed files with 608 additions and 0 deletions

55
README.md Normal file
View file

@ -0,0 +1,55 @@
# ESP8266 Based System Monitor
## Disclaimer!
### This project is based on work from [execuc/esp-hw-monitoring](https://github.com/execuc/esp-hw-monitoring) with several modifications to fit my needs. I take no credit for the original work.
### Modifications include but are not limited to:
- Major code cleanup
- Data format modification
- More efficient data reading
---
## What is this?
This is a simple ESP8266 based system monitor that can be used to monitor system information and resources. It also shows the current time as well as the ambient temperature and humidity.
## Components used
- ESP8266
- 240*320 2.8 inch ILI9341 LCD
- DHT22 temperature module (with resistor)
## Connecting the components
- Connect the LCD to the ESP8266 as follows:
- LCD VCC to ESP8266 3.3V
- LCD GND to ESP8266 GND
- LCD CS to ESP8266 D2
- LCD RESET to ESP8266 D3
- LCD DC to ESP8266 D4
- Connect the DHT22 to the ESP8266 as follows:
- DHT22 VCC to ESP8266 3.3V
- DHT22 GND to ESP8266 GND
- DHT22 DATA to ESP8266 D8
## How to use
- Install the Arduino IDE
- Install the ESP8266 board
- Install the following libraries:
- Adafruit GFX Library
- Adafruit ILI9341
- Adafruit Unified Sensor
- DHT sensor library
- Open the `sysmon.ino` file in the Arduino IDE
- Upload the code to the ESP8266
- Run the sysmon.py script on your computer
- Enjoy!

69
cpu.cpp Normal file
View file

@ -0,0 +1,69 @@
#include "cpu.h"
int16_t cpuUsageGlobal = defaultValue;
int16_t cpuUsage[8] = {defaultValue, defaultValue, defaultValue,defaultValue, defaultValue, defaultValue, defaultValue, defaultValue};
int16_t cpuTempGlobal = defaultValue;
int16_t cpuTemp[8] = {defaultValue, defaultValue, defaultValue,defaultValue, defaultValue, defaultValue, defaultValue, defaultValue};
uint32_t ramFree = defaultValue;
uint32_t ramMax = defaultValue;
static int8_t extractArray(String &command, int16_t *array)
{
int8_t startIndex = 1, lastIndex;
int8_t index = 0;
bool needStop = false;
while(index < 8)
{
lastIndex = command.indexOf(",", startIndex);
if(lastIndex == -1)
{
lastIndex = command.length() - 1;
needStop = true;
}
array[index++] = command.substring(startIndex, lastIndex).toInt();
if(needStop)
break;
startIndex = lastIndex +1;
}
return index;
}
int8_t setCpuTemp(String command)
{
if(command.substring(0, 1) == "[")
{
extractArray(command, cpuTemp);
}
else
{
cpuTempGlobal = command.toInt();
}
return 0;
}
int8_t setCpuUsage(String command)
{
if(command.substring(0, 1) == "[")
{
extractArray(command, cpuUsage);
}
else
{
cpuUsageGlobal = command.toInt();
}
return 0;
}
int8_t setRamMax(String command)
{
ramMax = command.toInt();
return 0;
}
int8_t setRamFree(String command)
{
ramFree = command.toInt();
return 0;
}

21
cpu.h Normal file
View file

@ -0,0 +1,21 @@
#ifndef __CPU_H__
#define __CPU_H__
#include<Arduino.h>
#define defaultValue 0
extern void initCpuParameters();
extern int8_t setCpuTemp(String command);
extern int8_t setCpuUsage(String command);
extern int8_t setRamMax(String command);
extern int8_t setRamFree(String command);
extern int16_t cpuUsageGlobal;
extern int16_t cpuUsage[8];
extern int16_t cpuTempGlobal;
extern int16_t cpuTemp[8];
extern uint32_t ramMax;
extern uint32_t ramFree;
#endif // __CPU_H__

19
datetimeHandler.cpp Normal file
View file

@ -0,0 +1,19 @@
#include "datetimeHandler.h"
uint8_t localTemp = 255;
uint8_t localHum = 255;
uint8_t hour = 0;
uint8_t minute = 0;
uint8_t time_tab[6] = {'-', '-', ':', '-', '-', 0};
void setTime(String time)
{
if(time.length() == 8)
{
hour = time.substring(0,2).toInt();
time.substring(0,5).getBytes(time_tab, 5+1);
minute = time.substring(3,5).toInt();
}
}

13
datetimeHandler.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __DATETIMEHANDLER_H__
#define __DATETIMEHANDLER_H__
#include<Arduino.h>
extern uint8_t localTemp;
extern uint8_t localHum;
extern uint8_t hour;
extern uint8_t minute;
extern uint8_t time_tab[6];
extern void setTime(String time);
#endif // __DATETIMEHANDLER_H__

210
gfx_1.cpp Normal file
View file

@ -0,0 +1,210 @@
#include "gfx_1.h"
#include "datetimeHandler.h"
#include "cpu.h"
#include "Adafruit_GFX.h"
#include <Adafruit_ILI9341.h>
bool gfx1_refresh = true;
static uint8_t s_time_tab[6] = {'0', '0', ':', '0', '0', 0};
static uint8_t s_localHum = 0, s_localTemp = 0, s_cpuTemp = 255;
static int16_t s_cpu_usage = 255;
static uint32_t s_ram_free = 255, s_ram_max = 255;
// 5px size
static void gfx_update_toolbar();
static void gfx_update_cpu();
static void gfx_update_mem();
static void writeArray(const char *buf)
{
uint8_t c= 0;
while(buf[c] != 0)
tft.write(buf[c++]);
}
void gfx1_udpate()
{
// if(!gfx1_refresh)
// return ;
gfx1_refresh = false;
gfx_update_toolbar();
gfx_update_cpu();
gfx_update_mem();
}
#define LINE_Y_REL 29
#define TEXT_Y_REL 9
#define FIRST_TEXT_Y_REL 40
#define TEXT_ESPACE_Y 35
#define TEXT_ESPACE_SHORT_Y 25
char buf[20];
void gfx1_layout()
{
uint8_t c= 0;
tft.fillScreen(ILI9341_BLACK);
tft.drawLine(10, 18, 310, 18, ILI9341_YELLOW);
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
tft.setCursor(35, 0);
tft.setTextSize(1);
tft.write('o');
tft.setTextSize(2);
tft.setCursor(35+8, 2);
tft.write('C');
//Humidity
tft.setCursor(300, 2);
tft.write('%');
// CPU rect
tft.setTextSize(2);
tft.drawRoundRect(5, 45, 150, 90, 10, ILI9341_DARKCYAN);
tft.drawLine(5, 45+LINE_Y_REL, 154, 45+LINE_Y_REL, ILI9341_DARKCYAN);
tft.setTextColor(ILI9341_DARKCYAN, ILI9341_BLACK);
tft.setCursor(60, 45+TEXT_Y_REL);
sprintf(buf, "CPU");
writeArray(buf);
tft.setCursor(15, 45+FIRST_TEXT_Y_REL);
sprintf(buf, "Usage:");
writeArray(buf);
tft.setCursor(15, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
sprintf(buf, "Temp:");
writeArray(buf);
tft.setCursor(15, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y *2);
// memory
tft.drawRoundRect(165, 45, 150, 90, 10, ILI9341_GREEN);
tft.drawLine(165, 45+LINE_Y_REL, 314, 45+LINE_Y_REL, ILI9341_GREEN);
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
tft.setCursor(205, 45+TEXT_Y_REL);
sprintf(buf, "MEMORY");
writeArray(buf);
tft.setCursor(175, 45+FIRST_TEXT_Y_REL);
sprintf(buf, "Max:");
writeArray(buf);
tft.setCursor(175, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
sprintf(buf, "Free:");
writeArray(buf);
gfx1_refresh = true;
gfx1_udpate();
}
void get_formated_space(int32_t valueMb)
{
int8_t unity = 0;
if(valueMb > 999)
{
valueMb = valueMb / 1024;
unity = 1; // GB
}
if(valueMb > 9999)
{
valueMb = valueMb / 1024;
unity = 2; // TB
}
if(unity == 0)
sprintf(buf, "%4d MB", valueMb);
else if(unity == 1)
sprintf(buf, "%4d GB", valueMb);
else
sprintf(buf, "%4d TB", valueMb);
}
static void gfx_update_mem()
{
tft.setTextColor(ILI9341_GREEN, ILI9341_BLACK);
if(s_ram_max != ramMax)
{
tft.setCursor(175 + 50, 45+FIRST_TEXT_Y_REL);
get_formated_space(ramMax);
writeArray(buf);
s_ram_free = ramMax;
}
if(s_ram_free != ramFree)
{
tft.setCursor(175 + 50, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
get_formated_space(ramFree);
writeArray(buf);
s_ram_free = ramFree;
}
}
//s_cpu_usage = 0;
static void gfx_update_cpu()
{
tft.setTextColor(ILI9341_DARKCYAN, ILI9341_BLACK);
if(cpuUsageGlobal != s_cpu_usage)
{
tft.setCursor(15+75, 45+FIRST_TEXT_Y_REL);
sprintf(buf, "%3d %%", cpuUsageGlobal);
writeArray(buf);
s_cpu_usage = cpuUsageGlobal;
}
if(s_cpuTemp != cpuTempGlobal)
{
tft.setCursor(15 + 75, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
sprintf(buf, "%3d ", cpuTempGlobal);
writeArray(buf);
tft.setCursor(15 + 115, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y - 2);
tft.setTextSize(1);
tft.write('o');
tft.setTextSize(2);
tft.setCursor(15 + 115 +8, 45+FIRST_TEXT_Y_REL + TEXT_ESPACE_SHORT_Y);
tft.write('C');
s_cpuTemp = cpuTempGlobal;
}
}
static void gfx_update_toolbar()
{
uint8_t c= 0;
char buf[5];
tft.setTextColor(ILI9341_YELLOW, ILI9341_BLACK);
//time
if(s_time_tab[4] != time_tab[4] || s_time_tab[3] != time_tab[3]
|| s_time_tab[1] != time_tab[1] || s_time_tab[0] != time_tab[0])
{
tft.setTextSize(2);
tft.setCursor(135, 2);
while(c < 5)
{
uint8_t car = time_tab[c];
s_time_tab[c] = car;
tft.write(car);
c++;
}
}
//temp
if(s_localTemp != localTemp)
{
tft.setCursor(10, 2);
if(localTemp != 255)
sprintf(buf, "%2d", localTemp);
else
sprintf(buf, "--");
writeArray(buf);
s_localTemp = localTemp;
}
// humidity
if(s_localHum != localHum)
{
tft.setCursor(275, 2);
if(localHum != 255)
sprintf(buf, "%2d", localHum);
else
sprintf(buf, "--");
writeArray(buf);
s_localHum = localHum;
}
}

14
gfx_1.h Normal file
View file

@ -0,0 +1,14 @@
#ifndef __GFX_1_H__
#define __GFX_1_H__
#include "Adafruit_ILI9341.h"
extern Adafruit_ILI9341 tft;
extern void gfx1_udpate();
extern void gfx1_layout();
extern bool gfx1_refresh;
#endif

108
sysmon.ino Normal file
View file

@ -0,0 +1,108 @@
#include "Adafruit_GFX.h"
#include "Adafruit_ILI9341.h"
#include <XPT2046_Touchscreen.h>
#include "DHT.h"
#include "cpu.h"
#include "datetimeHandler.h"
#include "gfx_1.h"
#define TFT_DC D4
#define TFT_CS D2
#define TFT_RESET D3
#define DHTPIN D8
#define DHTTYPE DHT22
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
DHT dht(DHTPIN, DHTTYPE);
static uint32_t tempTime = 0;
static uint32_t rtcTime = 0;
static uint32_t displayTime = 0;
void setup() {
Serial.begin(9600);
initHardware();
gfx1_layout();
}
void update(String command) {
int delimiterIndex = command.indexOf('=');
// Serial.println(command);
if (delimiterIndex != -1) {
String key = command.substring(0, delimiterIndex);
String value = command.substring(delimiterIndex + 1);
Serial.print(key);
// Check the key and assign the corresponding value
if (key.equals("CpuTemp")) {
setCpuTemp(value);
Serial.print("Received CPU temperature: ");
Serial.println(value);
// gfx1_udpate();
} else if (key.equals("CpuUsage")) {
setCpuUsage(value);
Serial.print("Received CPU usage: ");
Serial.println(value);
// gfx1_udpate();
} else if (key.equals("RamFree")) {
setRamFree(value);
Serial.print("Received Ram free: ");
Serial.println(value);
// gfx1_udpate();
} else if (key.equals("RamMax")) {
setRamMax(value);
Serial.print("Received Ram max: ");
Serial.println(value);
// gfx1_udpate();
} else if (key.equals("Time")) {
setTime(value);
Serial.print("Received Time: ");
Serial.println(value);
// gfx1_udpate();
}
}
gfx1_refresh = true;
gfx1_udpate();
}
void loop() {
Serial.println("Enter data:");
// while (Serial.available() == 0) {}
String command = Serial.readString();
command.trim();
Serial.println(command);
if(!isnan(dht.readTemperature()))
{
localHum = dht.readHumidity();
localTemp = dht.readTemperature() - 4;
Serial.println(localTemp);
gfx1_refresh = true;
gfx1_udpate();
}
// else
// {
// localHum = 255;
// localTemp = 255;
// }
update(command);
// delay(1000);
// if ( currentTime > displayTime ) {
// displayTime = currentTime + 100000;
// }
}
void initHardware()
{
pinMode(TFT_RESET, OUTPUT);
digitalWrite(TFT_RESET, LOW);
delay(1000);
digitalWrite(TFT_RESET, HIGH);
delay(1000);
tft.begin();
tft.setRotation(3);
dht.begin();
// delay(3000);
}

99
sysmon.py Normal file
View file

@ -0,0 +1,99 @@
#!/usr/bin/python
import sys
from datetime import datetime
from datetime import timedelta
import psutil
import serial
from gettext import c2py
from time import sleep
import sensors
import subprocess
import math
import pyowm
import os
CPU_TEMP_PATH = '/sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon2/temp1_input'
file_descriptor = '/dev/ttyUSB0'
baud_rate = 9600
arduino = serial.Serial(port=file_descriptor, baudrate=baud_rate)
sleep(6)
def send_command(command):
print("sent: " + command)
arduino.write(command.encode())
sleep(0.1)
def set_time(date_time):
request = '\nTime=%s\r\n' % date_time.strftime('%H:%M:%S')
send_command(request)
def set_max():
ram_max = int(psutil.virtual_memory().total / (1024.*1024.))
request = 'RamMax=%d\r\n' % ram_max
send_command(request)
def set_free():
ram_free = int(psutil.virtual_memory().free / (1024.*1024.))
request = 'RamFree=%d\r\n' % ram_free
send_command(request)
def set_system_info():
with open('/etc/os-release', 'r') as f:
for line in f:
if line.startswith('NAME='):
OSName = line.split('"')[1]
break
request = 'OS=%s\r\n' % OSName
send_command(request)
sleep(1)
with open('/proc/version', 'r') as f:
for line in f:
Kernel = line.split(' ')[2].split('-')[0]
break
request = 'Kernel=%s\r\n' % Kernel
send_command(request)
sleep(1)
def set_uptime():
uptime_seconds = psutil.boot_time()
uptime = datetime.now() - datetime.fromtimestamp(uptime_seconds)
uptime_hours = int(uptime.total_seconds() // 3600)
uptime_minutes = int((uptime.total_seconds() % 3600) // 60)
uptime = f"{uptime_hours:02d}:{uptime_minutes:02d}"
request = 'Uptime=%s\r\n' % uptime
send_command(request)
def start(tty_serial):
set_system_info()
while 1:
set_uptime()
sleep(1)
cpu_temp = int(subprocess.check_output(['cat', CPU_TEMP_PATH]))/1000
requests = "\nCpuTemp="+str(math.trunc(cpu_temp))
send_command(requests)
sleep(1)
cpu_pct = psutil.cpu_percent(interval=None, percpu=False)
cpu_global = int(cpu_pct)
request = "\nCpuUsage=" + str(math.trunc(cpu_global))
send_command(request)
sleep(1)
set_time(datetime.now())
sleep(1)
set_max()
sleep(1)
set_free()
sleep(1)
def main():
start('/dev/ttyUSB0')
if __name__ == "__main__":
main()