mirror of
https://git.alemi.dev/pc-monitor.git
synced 2024-11-25 00:44:50 +01:00
feat: split net bars in 2, small fixes
This commit is contained in:
parent
b1a3d7b033
commit
06ed013f19
4 changed files with 84 additions and 51 deletions
|
@ -8,6 +8,8 @@ from time import sleep
|
||||||
import serial
|
import serial
|
||||||
import psutil
|
import psutil
|
||||||
|
|
||||||
|
BAR_MAX_HEIGHT = 255
|
||||||
|
|
||||||
class State:
|
class State:
|
||||||
run: bool
|
run: bool
|
||||||
device: str
|
device: str
|
||||||
|
@ -36,6 +38,7 @@ class State:
|
||||||
await self._loop.run_in_executor(None, self.port.write, pkt)
|
await self._loop.run_in_executor(None, self.port.write, pkt)
|
||||||
except serial.SerialException as e:
|
except serial.SerialException as e:
|
||||||
logging.error("[!] Error operating with device: %s", str(e))
|
logging.error("[!] Error operating with device: %s", str(e))
|
||||||
|
await asyncio.sleep(30)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging.exception("unhandled exception")
|
logging.exception("unhandled exception")
|
||||||
self.run = False
|
self.run = False
|
||||||
|
@ -47,42 +50,50 @@ class State:
|
||||||
rx = 0
|
rx = 0
|
||||||
tx = 0
|
tx = 0
|
||||||
while self.run:
|
while self.run:
|
||||||
cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 1, True)
|
cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 0.1, True)
|
||||||
load = [ int(((x/100) **2) * 255) for x in cpu_report ] # mypy whines but percpu returns a list
|
|
||||||
net = psutil.net_io_counters(pernic=True)
|
net = psutil.net_io_counters(pernic=True)
|
||||||
d_rx = sum(v.bytes_recv for k, v in net.items() if k != "lo")
|
d_rx = sum(v.bytes_recv for k, v in net.items() if k != "lo")
|
||||||
d_tx = sum(v.bytes_sent for k, v in net.items() if k != "lo")
|
d_tx = sum(v.bytes_sent for k, v in net.items() if k != "lo")
|
||||||
await self.packets.put(struct.pack("BBBBBBBB", 3, 6, *load, min(int((d_tx - tx) / 1000), 255), min(int((d_rx - rx) / 1000), 255)))
|
p_rx = min(int(d_rx - rx), 255)
|
||||||
|
p_tx = min(int(d_tx - tx), 255)
|
||||||
|
w_rx = min(int((d_rx - rx) / 4096), 255)
|
||||||
|
w_tx = min(int((d_tx - tx) / 4096), 255)
|
||||||
|
await self.packets.put(struct.pack("BBBBBB", 1, 4, *( int(((x/100) **2) * BAR_MAX_HEIGHT) for x in cpu_report )))
|
||||||
|
await self.packets.put(struct.pack("BBBB", 2, 2, min(int((d_tx - tx) / 1024), BAR_MAX_HEIGHT), min(int((d_rx - rx) / 1024), 255)))
|
||||||
|
await self.packets.put(struct.pack("BBBBBBBBBB", 3, 8, *( int((x/100) * BAR_MAX_HEIGHT) for x in cpu_report ), p_tx, p_rx, w_tx, w_rx))
|
||||||
rx = d_rx
|
rx = d_rx
|
||||||
tx = d_tx
|
tx = d_tx
|
||||||
|
|
||||||
async def cpu_load_leds(self):
|
# async def cpu_load_leds(self):
|
||||||
while self.run:
|
# return
|
||||||
cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 0.05, True)
|
# while self.run:
|
||||||
load = [ int(((x/100) **2) * 255) for x in cpu_report ] # mypy whines but percpu returns a list
|
# cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 0.05, True)
|
||||||
logging.info("CPU [%d|%d|%d|%d]", *load)
|
# load = [ int(((x/100) **2) * 255) for x in cpu_report ] # mypy whines but percpu returns a list
|
||||||
await self.packets.put(struct.pack("BBBBBB", 1, 4, *load))
|
# logging.info("CPU [%d|%d|%d|%d]", *load)
|
||||||
|
# await self.packets.put(struct.pack("BBBBBB", 1, 4, *load))
|
||||||
|
|
||||||
async def net_traffic_leds(self):
|
# async def net_traffic_leds(self):
|
||||||
rx = 0
|
# return
|
||||||
tx = 0
|
# rx = 0
|
||||||
while self.run:
|
# tx = 0
|
||||||
net = psutil.net_io_counters(pernic=True)
|
# while self.run:
|
||||||
d_rx = sum(v.bytes_recv for k, v in net.items() if k != "lo")
|
# net = psutil.net_io_counters(pernic=True)
|
||||||
d_tx = sum(v.bytes_sent for k, v in net.items() if k != "lo")
|
# d_rx = sum(v.bytes_recv for k, v in net.items() if k != "lo")
|
||||||
logging.info("NET [TX %d | %d RX]", d_tx - tx, d_rx - rx)
|
# d_tx = sum(v.bytes_sent for k, v in net.items() if k != "lo")
|
||||||
await self.packets.put(struct.pack("BBBB", 2, 2, min(d_tx - tx, 255), min(d_rx - rx, 255)))
|
# logging.info("NET [TX %d | %d RX]", d_tx - tx, d_rx - rx)
|
||||||
rx = d_rx
|
# await self.packets.put(struct.pack("BBBB", 2, 2, min(d_tx - tx, 255), min(d_rx - rx, 255)))
|
||||||
tx = d_tx
|
# rx = d_rx
|
||||||
await asyncio.sleep(0.01)
|
# tx = d_tx
|
||||||
|
# await asyncio.sleep(0.01)
|
||||||
|
|
||||||
async def run_tasks(self):
|
async def run_tasks(self):
|
||||||
self._loop = asyncio.get_event_loop()
|
self._loop = asyncio.get_event_loop()
|
||||||
port_manager = self._loop.create_task(self.run_port_manager())
|
port_manager = self._loop.create_task(self.run_port_manager())
|
||||||
cpu_leds = self._loop.create_task(self.cpu_load_leds())
|
# cpu_leds = self._loop.create_task(self.cpu_load_leds())
|
||||||
net_leds = self._loop.create_task(self.net_traffic_leds())
|
# net_leds = self._loop.create_task(self.net_traffic_leds())
|
||||||
display = self._loop.create_task(self.display_polling())
|
display = self._loop.create_task(self.display_polling())
|
||||||
await asyncio.gather(port_manager, cpu_leds, net_leds, display)
|
# await asyncio.gather(port_manager, cpu_leds, net_leds, display)
|
||||||
|
await asyncio.gather(port_manager, display)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
|
@ -91,7 +102,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
logging.basicConfig(level=logging.WARNING)
|
logging.basicConfig(level=logging.WARNING)
|
||||||
|
|
||||||
state = State(sys.argv[1])
|
state = State(sys.argv[1], baudrate=115200)
|
||||||
|
|
||||||
asyncio.run(state.run_tasks())
|
asyncio.run(state.run_tasks())
|
||||||
|
|
||||||
|
|
|
@ -37,6 +37,17 @@ fn byte_to_height(val: u8, max: u8) -> u32 {
|
||||||
// return ((val as f32 / 255.0) * max as f32) as u32; // TODO get rid of floating point operations!
|
// return ((val as f32 / 255.0) * max as f32) as u32; // TODO get rid of floating point operations!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn _draw_number_as_box(display: &mut Display, value: u32, width: u32, height: u32, base_x: u32, base_y: u32) {
|
||||||
|
let mut i = 0;
|
||||||
|
for x in 0..width {
|
||||||
|
for y in 0..height {
|
||||||
|
display.set_pixel(base_x + x, base_y + y, ((value << i) & 1) == 1);
|
||||||
|
i = (i + i) % 32;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
pub fn draw_ui(display: &mut Display, style: &DisplayStyle) {
|
pub fn draw_ui(display: &mut Display, style: &DisplayStyle) {
|
||||||
Rectangle::new(Point::new(0, 0), Size::new(85, 64))
|
Rectangle::new(Point::new(0, 0), Size::new(85, 64))
|
||||||
.into_styled(style.border_style)
|
.into_styled(style.border_style)
|
||||||
|
@ -51,10 +62,10 @@ pub fn draw_ui(display: &mut Display, style: &DisplayStyle) {
|
||||||
// since my specific display is 2 displays of different colors joined, there's a small gap
|
// since my specific display is 2 displays of different colors joined, there's a small gap
|
||||||
// between pixels 19 and 20. This makes the 2 extra blank pixels look bad, so I'm removing 3.
|
// between pixels 19 and 20. This makes the 2 extra blank pixels look bad, so I'm removing 3.
|
||||||
// On normal screens this will look worse and you should put them back.
|
// On normal screens this will look worse and you should put them back.
|
||||||
// Rectangle::new(Point::new(87, 16), Size::new(11, 48))
|
Rectangle::new(Point::new(87, 16), Size::new(11, 48))
|
||||||
// .into_styled(style.border_style)
|
.into_styled(style.border_style)
|
||||||
// .draw(display)
|
.draw(display)
|
||||||
// .unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Rectangle::new(Point::new(100, 0), Size::new(28, 64))
|
Rectangle::new(Point::new(100, 0), Size::new(28, 64))
|
||||||
.into_styled(style.border_style)
|
.into_styled(style.border_style)
|
||||||
|
@ -87,20 +98,29 @@ pub enum NetDirection {
|
||||||
TX, RX
|
TX, RX
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn draw_network_bar(display: &mut Display, direction: NetDirection, value: u8, style: &DisplayStyle) {
|
pub fn draw_network_bar(display: &mut Display, direction: NetDirection, value_fine: u8, value_wide: u8, style: &DisplayStyle) {
|
||||||
let x = match direction { NetDirection::TX => 103, NetDirection::RX => 115 };
|
let x = match direction { NetDirection::TX => 103, NetDirection::RX => 115 };
|
||||||
let height = byte_to_height(value, 54);
|
let height_fine = byte_to_height(value_fine, 54);
|
||||||
Rectangle::new(Point::new(x as i32, 8), Size::new(10, 54 - (height-1) as u32))
|
let height_wide = byte_to_height(value_wide, 54);
|
||||||
|
Rectangle::new(Point::new(x as i32, 8), Size::new(2, 54 - (height_fine-1) as u32))
|
||||||
.into_styled(style.background_style)
|
.into_styled(style.background_style)
|
||||||
.draw(display)
|
.draw(display)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Rectangle::new(Point::new(x as i32, (62 - height) as i32), Size::new(10, 1 + height as u32))
|
Rectangle::new(Point::new(x as i32, (62 - height_fine) as i32), Size::new(2, 1 + height_fine as u32))
|
||||||
|
.into_styled(style.bar_style)
|
||||||
|
.draw(display)
|
||||||
|
.unwrap();
|
||||||
|
Rectangle::new(Point::new(3 + x as i32, 8), Size::new(7, 54 - (height_wide-1) as u32))
|
||||||
|
.into_styled(style.background_style)
|
||||||
|
.draw(display)
|
||||||
|
.unwrap();
|
||||||
|
Rectangle::new(Point::new(3 + x as i32, (62 - height_wide) as i32), Size::new(7, 1 + height_wide as u32))
|
||||||
.into_styled(style.bar_style)
|
.into_styled(style.bar_style)
|
||||||
.draw(display)
|
.draw(display)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _draw_all(display: &mut Display, cpu1: u8, cpu2: u8, cpu3: u8, cpu4: u8, tx: u8, rx: u8, style: &DisplayStyle) {
|
fn _draw_all(display: &mut Display, cpu1: u8, cpu2: u8, cpu3: u8, cpu4: u8, tx: u8, rx: u8, tx_wide:u8, rx_wide: u8, style: &DisplayStyle) {
|
||||||
draw_ui(display, style);
|
draw_ui(display, style);
|
||||||
|
|
||||||
draw_cpu_bar(display, 1, cpu1, style);
|
draw_cpu_bar(display, 1, cpu1, style);
|
||||||
|
@ -108,8 +128,8 @@ fn _draw_all(display: &mut Display, cpu1: u8, cpu2: u8, cpu3: u8, cpu4: u8, tx:
|
||||||
draw_cpu_bar(display, 3, cpu3, style);
|
draw_cpu_bar(display, 3, cpu3, style);
|
||||||
draw_cpu_bar(display, 4, cpu4, style);
|
draw_cpu_bar(display, 4, cpu4, style);
|
||||||
|
|
||||||
draw_network_bar(display, NetDirection::TX, tx, style);
|
draw_network_bar(display, NetDirection::TX, tx, tx_wide, style);
|
||||||
draw_network_bar(display, NetDirection::RX, rx, style);
|
draw_network_bar(display, NetDirection::RX, rx, rx_wide, style);
|
||||||
|
|
||||||
display.flush().unwrap();
|
display.flush().unwrap();
|
||||||
}
|
}
|
||||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -20,7 +20,7 @@ mod display;
|
||||||
|
|
||||||
use crate::packet::PacketBuilder;
|
use crate::packet::PacketBuilder;
|
||||||
use crate::utils::FourLedDisplay;
|
use crate::utils::FourLedDisplay;
|
||||||
use display::{draw_ui, draw_cpu_bar, draw_network_bar, NetDirection};
|
use display::{draw_ui, draw_cpu_bar, draw_network_bar, NetDirection, Spinner};
|
||||||
|
|
||||||
pub struct DisplayStyle<'a> {
|
pub struct DisplayStyle<'a> {
|
||||||
border_style: PrimitiveStyle<BinaryColor>,
|
border_style: PrimitiveStyle<BinaryColor>,
|
||||||
|
@ -41,10 +41,10 @@ fn main() -> ! {
|
||||||
let mut led_tx = pins.d4.into_output(); // red
|
let mut led_tx = pins.d4.into_output(); // red
|
||||||
let button = pins.d2.into_pull_up_input();
|
let button = pins.d2.into_pull_up_input();
|
||||||
let mut cpu_leds = FourLedDisplay::new(
|
let mut cpu_leds = FourLedDisplay::new(
|
||||||
pins.d3.into_output().into_pwm(&timer2),
|
|
||||||
pins.d9.into_output().into_pwm(&timer1),
|
|
||||||
pins.d10.into_output().into_pwm(&timer1),
|
|
||||||
pins.d11.into_output().into_pwm(&timer2),
|
pins.d11.into_output().into_pwm(&timer2),
|
||||||
|
pins.d10.into_output().into_pwm(&timer1),
|
||||||
|
pins.d9.into_output().into_pwm(&timer1),
|
||||||
|
pins.d3.into_output().into_pwm(&timer2),
|
||||||
);
|
);
|
||||||
let i2c = arduino_hal::i2c::I2c::new(
|
let i2c = arduino_hal::i2c::I2c::new(
|
||||||
dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), 800000
|
dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), 800000
|
||||||
|
@ -75,6 +75,7 @@ fn main() -> ! {
|
||||||
// prepare display
|
// prepare display
|
||||||
let interface = I2CDisplayInterface::new(i2c);
|
let interface = I2CDisplayInterface::new(i2c);
|
||||||
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode();
|
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode();
|
||||||
|
let mut s = Spinner::new(91, 10);
|
||||||
|
|
||||||
display.init().unwrap();
|
display.init().unwrap();
|
||||||
cpu_leds.set(1, 255);
|
cpu_leds.set(1, 255);
|
||||||
|
@ -124,13 +125,14 @@ fn main() -> ! {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
PacketId::ScreenDrawPacket => {
|
PacketId::ScreenDrawPacket => {
|
||||||
if let Some(payload) = pkt.payload && payload.len() == 6 {
|
if let Some(payload) = pkt.payload && payload.len() == 8 {
|
||||||
|
s.draw(&mut display);
|
||||||
draw_cpu_bar(&mut display, 1, payload[0], &style);
|
draw_cpu_bar(&mut display, 1, payload[0], &style);
|
||||||
draw_cpu_bar(&mut display, 2, payload[1], &style);
|
draw_cpu_bar(&mut display, 2, payload[1], &style);
|
||||||
draw_cpu_bar(&mut display, 3, payload[2], &style);
|
draw_cpu_bar(&mut display, 3, payload[2], &style);
|
||||||
draw_cpu_bar(&mut display, 4, payload[3], &style);
|
draw_cpu_bar(&mut display, 4, payload[3], &style);
|
||||||
draw_network_bar(&mut display, NetDirection::TX, payload[4], &style);
|
draw_network_bar(&mut display, NetDirection::TX, payload[4], payload[6], &style);
|
||||||
draw_network_bar(&mut display, NetDirection::RX, payload[5], &style);
|
draw_network_bar(&mut display, NetDirection::RX, payload[5], payload[7], &style);
|
||||||
display.flush().unwrap();
|
display.flush().unwrap();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
16
src/utils.rs
16
src/utils.rs
|
@ -2,18 +2,18 @@ use arduino_hal::{simple_pwm::*, port::{Pin, mode::PwmOutput}, hal::port::{PD3,
|
||||||
|
|
||||||
// TODO can I make it a generic "Pin" and use a slice?
|
// TODO can I make it a generic "Pin" and use a slice?
|
||||||
pub struct FourLedDisplay {
|
pub struct FourLedDisplay {
|
||||||
led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
led1: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||||
led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
led2: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||||
led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
led3: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||||
led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
led4: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FourLedDisplay {
|
impl FourLedDisplay {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
mut led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
mut led1: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||||
mut led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
mut led2: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||||
mut led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
mut led3: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||||
mut led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
mut led4: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
led1.enable();
|
led1.enable();
|
||||||
led2.enable();
|
led2.enable();
|
||||||
|
|
Loading…
Reference in a new issue