feat: split net bars in 2, small fixes

This commit is contained in:
əlemi 2022-08-30 20:48:33 +02:00
parent b1a3d7b033
commit 06ed013f19
No known key found for this signature in database
GPG key ID: BBCBFE5D7244634E
4 changed files with 84 additions and 51 deletions

View file

@ -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())

View file

@ -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();
}

View file

@ -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();
}
},

View file

@ -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();