mirror of
https://git.alemi.dev/pc-monitor.git
synced 2024-11-21 15:04: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 psutil
|
||||
|
||||
BAR_MAX_HEIGHT = 255
|
||||
|
||||
class State:
|
||||
run: bool
|
||||
device: str
|
||||
|
@ -36,6 +38,7 @@ class State:
|
|||
await self._loop.run_in_executor(None, self.port.write, pkt)
|
||||
except serial.SerialException as e:
|
||||
logging.error("[!] Error operating with device: %s", str(e))
|
||||
await asyncio.sleep(30)
|
||||
except Exception as e:
|
||||
logging.exception("unhandled exception")
|
||||
self.run = False
|
||||
|
@ -47,42 +50,50 @@ class State:
|
|||
rx = 0
|
||||
tx = 0
|
||||
while self.run:
|
||||
cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 1, True)
|
||||
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.1, True)
|
||||
net = psutil.net_io_counters(pernic=True)
|
||||
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")
|
||||
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
|
||||
tx = d_tx
|
||||
|
||||
async def cpu_load_leds(self):
|
||||
while self.run:
|
||||
cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 0.05, True)
|
||||
load = [ int(((x/100) **2) * 255) for x in cpu_report ] # mypy whines but percpu returns a list
|
||||
logging.info("CPU [%d|%d|%d|%d]", *load)
|
||||
await self.packets.put(struct.pack("BBBBBB", 1, 4, *load))
|
||||
# async def cpu_load_leds(self):
|
||||
# return
|
||||
# while self.run:
|
||||
# cpu_report = await self._loop.run_in_executor(None, psutil.cpu_percent, 0.05, True)
|
||||
# load = [ int(((x/100) **2) * 255) for x in cpu_report ] # mypy whines but percpu returns a list
|
||||
# logging.info("CPU [%d|%d|%d|%d]", *load)
|
||||
# await self.packets.put(struct.pack("BBBBBB", 1, 4, *load))
|
||||
|
||||
async def net_traffic_leds(self):
|
||||
rx = 0
|
||||
tx = 0
|
||||
while self.run:
|
||||
net = psutil.net_io_counters(pernic=True)
|
||||
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")
|
||||
logging.info("NET [TX %d | %d RX]", d_tx - tx, d_rx - rx)
|
||||
await self.packets.put(struct.pack("BBBB", 2, 2, min(d_tx - tx, 255), min(d_rx - rx, 255)))
|
||||
rx = d_rx
|
||||
tx = d_tx
|
||||
await asyncio.sleep(0.01)
|
||||
# async def net_traffic_leds(self):
|
||||
# return
|
||||
# rx = 0
|
||||
# tx = 0
|
||||
# while self.run:
|
||||
# net = psutil.net_io_counters(pernic=True)
|
||||
# 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")
|
||||
# logging.info("NET [TX %d | %d RX]", d_tx - tx, d_rx - rx)
|
||||
# await self.packets.put(struct.pack("BBBB", 2, 2, min(d_tx - tx, 255), min(d_rx - rx, 255)))
|
||||
# rx = d_rx
|
||||
# tx = d_tx
|
||||
# await asyncio.sleep(0.01)
|
||||
|
||||
async def run_tasks(self):
|
||||
self._loop = asyncio.get_event_loop()
|
||||
port_manager = self._loop.create_task(self.run_port_manager())
|
||||
cpu_leds = self._loop.create_task(self.cpu_load_leds())
|
||||
net_leds = self._loop.create_task(self.net_traffic_leds())
|
||||
# cpu_leds = self._loop.create_task(self.cpu_load_leds())
|
||||
# net_leds = self._loop.create_task(self.net_traffic_leds())
|
||||
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 len(sys.argv) < 2:
|
||||
|
@ -91,7 +102,7 @@ if __name__ == "__main__":
|
|||
|
||||
logging.basicConfig(level=logging.WARNING)
|
||||
|
||||
state = State(sys.argv[1])
|
||||
state = State(sys.argv[1], baudrate=115200)
|
||||
|
||||
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!
|
||||
}
|
||||
|
||||
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) {
|
||||
Rectangle::new(Point::new(0, 0), Size::new(85, 64))
|
||||
.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
|
||||
// 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.
|
||||
// Rectangle::new(Point::new(87, 16), Size::new(11, 48))
|
||||
// .into_styled(style.border_style)
|
||||
// .draw(display)
|
||||
// .unwrap();
|
||||
Rectangle::new(Point::new(87, 16), Size::new(11, 48))
|
||||
.into_styled(style.border_style)
|
||||
.draw(display)
|
||||
.unwrap();
|
||||
|
||||
Rectangle::new(Point::new(100, 0), Size::new(28, 64))
|
||||
.into_styled(style.border_style)
|
||||
|
@ -87,20 +98,29 @@ pub enum NetDirection {
|
|||
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 height = byte_to_height(value, 54);
|
||||
Rectangle::new(Point::new(x as i32, 8), Size::new(10, 54 - (height-1) as u32))
|
||||
let height_fine = byte_to_height(value_fine, 54);
|
||||
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)
|
||||
.draw(display)
|
||||
.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)
|
||||
.draw(display)
|
||||
.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_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, 4, cpu4, style);
|
||||
|
||||
draw_network_bar(display, NetDirection::TX, tx, style);
|
||||
draw_network_bar(display, NetDirection::RX, rx, style);
|
||||
draw_network_bar(display, NetDirection::TX, tx, tx_wide, style);
|
||||
draw_network_bar(display, NetDirection::RX, rx, rx_wide, style);
|
||||
|
||||
display.flush().unwrap();
|
||||
}
|
||||
|
|
16
src/main.rs
16
src/main.rs
|
@ -20,7 +20,7 @@ mod display;
|
|||
|
||||
use crate::packet::PacketBuilder;
|
||||
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> {
|
||||
border_style: PrimitiveStyle<BinaryColor>,
|
||||
|
@ -41,10 +41,10 @@ fn main() -> ! {
|
|||
let mut led_tx = pins.d4.into_output(); // red
|
||||
let button = pins.d2.into_pull_up_input();
|
||||
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.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(
|
||||
dp.TWI, pins.a4.into_pull_up_input(), pins.a5.into_pull_up_input(), 800000
|
||||
|
@ -75,6 +75,7 @@ fn main() -> ! {
|
|||
// prepare display
|
||||
let interface = I2CDisplayInterface::new(i2c);
|
||||
let mut display = Ssd1306::new(interface, DisplaySize128x64, DisplayRotation::Rotate0).into_buffered_graphics_mode();
|
||||
let mut s = Spinner::new(91, 10);
|
||||
|
||||
display.init().unwrap();
|
||||
cpu_leds.set(1, 255);
|
||||
|
@ -124,13 +125,14 @@ fn main() -> ! {
|
|||
}
|
||||
},
|
||||
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, 2, payload[1], &style);
|
||||
draw_cpu_bar(&mut display, 3, payload[2], &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::RX, payload[5], &style);
|
||||
draw_network_bar(&mut display, NetDirection::TX, payload[4], payload[6], &style);
|
||||
draw_network_bar(&mut display, NetDirection::RX, payload[5], payload[7], &style);
|
||||
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?
|
||||
pub struct FourLedDisplay {
|
||||
led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||
led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||
led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||
led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||
led1: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||
led2: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||
led3: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||
led4: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||
}
|
||||
|
||||
impl FourLedDisplay {
|
||||
pub fn new(
|
||||
mut led1: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||
mut led2: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||
mut led3: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||
mut led4: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||
mut led1: Pin<PwmOutput<Timer2Pwm>, PB3>,
|
||||
mut led2: Pin<PwmOutput<Timer1Pwm>, PB2>,
|
||||
mut led3: Pin<PwmOutput<Timer1Pwm>, PB1>,
|
||||
mut led4: Pin<PwmOutput<Timer2Pwm>, PD3>,
|
||||
) -> Self {
|
||||
led1.enable();
|
||||
led2.enable();
|
||||
|
|
Loading…
Reference in a new issue