weather info initial

This commit is contained in:
Empire 2023-05-26 22:25:04 +02:00
parent 1c12173b77
commit 9cc39ab295
2 changed files with 99 additions and 16 deletions

View File

@ -8,3 +8,4 @@ edition = "2021"
[dependencies]
bit = "0.1.1"
embedded-graphics = "0.8.0"
openweathermap = "0.2.4"

View File

@ -1,12 +1,16 @@
use bit::BitIndex;
use core::time;
use embedded_graphics::{
image::{Image, ImageRaw},
mono_font::{iso_8859_1::FONT_6X10, MonoTextStyle},
pixelcolor::{BinaryColor, Rgb565},
prelude::*,
primitives::{Line, PrimitiveStyle},
text::Text,
};
use std::env;
use openweathermap::{self, CurrentWeather};
use std::net::UdpSocket;
use std::{env, sync::mpsc::Receiver, thread};
const IMAGE_SIZE_BYTE: usize = (IMAGE_WIDTH_BYTE * IMAGE_HEIGHT) as usize; /* one byte contains 8 LEDs, one in each bit */
const IMAGE_WIDTH: u32 = 5 * 32;
@ -17,17 +21,17 @@ const IMAGE_HEIGHT_BYTE: u32 = 40;
const IMAGE_LENGTH: usize = (IMAGE_WIDTH_BYTE * IMAGE_HEIGHT_BYTE) as usize;
const PACKAGE_LENGTH: usize = (IMAGE_LENGTH + 1) as usize;
struct UdpDisplay<'a> {
image_slice: &'a mut[u8; IMAGE_SIZE_BYTE],
struct UdpDisplay {
image: [u8; IMAGE_SIZE_BYTE],
}
impl OriginDimensions for UdpDisplay<'_> {
impl OriginDimensions for UdpDisplay {
fn size(&self) -> Size {
Size::new(IMAGE_WIDTH, IMAGE_HEIGHT)
}
}
impl DrawTarget for UdpDisplay<'_> {
impl DrawTarget for UdpDisplay {
type Color = BinaryColor;
type Error = core::convert::Infallible;
@ -63,33 +67,86 @@ impl DrawTarget for UdpDisplay<'_> {
I: IntoIterator<Item = Pixel<Self::Color>>,
{
for pixel in pixels {
if pixel.0.x < 0 {
continue;
}
if pixel.0.y < 0 {
continue;
}
let x = pixel.0.x as u32;
let y = pixel.0.y as u32;
if x > (IMAGE_WIDTH - 1) {
continue;
}
if y > (IMAGE_HEIGHT - 1) {
continue;
}
let y = y as u32;
let v = pixel.1.is_on();
//println!("pint {x} {y} is on {v}");
let offset: usize = (x + y * IMAGE_WIDTH) as usize;
let subbit: usize = (offset % 8).into();
let byte_offset: usize = (offset / 8).into();
let current = &mut self.image_slice[byte_offset];
let current = &mut self.image[byte_offset];
current.set_bit(subbit, v);
}
return Ok(());
}
}
fn send_package(ipaddress: String) {
let mut package = [0; PACKAGE_LENGTH];
fn send_package(ipaddress: String, data: &Option<Result<CurrentWeather, String>>) {
let mut package: [u8; PACKAGE_LENGTH] = [0; PACKAGE_LENGTH];
// Brightness
package[0] = 128;
let image_slice: &mut [u8; IMAGE_SIZE_BYTE] =
&mut package[1..PACKAGE_LENGTH].try_into().unwrap();
let mut display = UdpDisplay { image_slice };
let mut display = UdpDisplay {
image: [0; IMAGE_SIZE_BYTE],
};
Line::new(Point::new(50, 20), Point::new(60, 35))
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
.draw(&mut display).unwrap();
let style = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
Line::new(Point::new(0, 0), Point::new((IMAGE_WIDTH - 1) as i32, 0))
.into_styled(style)
.draw(&mut display)
.unwrap();
match data {
Some(v) => match v {
Err(error) => {
Text::new(&error, Point::new(0, 5), text_style)
.draw(&mut display)
.unwrap();
println!("{}", &error);
}
Ok(result) => {
let mut y = 10;
for condition in result.weather.as_slice() {
let text = condition.main.to_owned() + " " + &condition.description + " " + &condition.icon;
Text::new(&text, Point::new(0, y), text_style)
.draw(&mut display)
.unwrap();
println!("{}", &condition.main);
y += 10;
}
}
},
None => {
Text::new("Waiting for data", Point::new(20, 30), text_style)
.draw(&mut display)
.unwrap();
println!("{}", "no result");
}
}
package[1..PACKAGE_LENGTH].copy_from_slice(&display.image);
let socket = UdpSocket::bind("0.0.0.0:4242").expect("couldn't bind to address");
socket
@ -119,7 +176,32 @@ fn main() {
// one argument passed
2 => {
let ip = &args[1];
send_package(ip.to_string());
let receiver = openweathermap::init(
"Mannheim",
"metric",
"de",
"978882ab9dd05e7122ff2b0aef2d3e55",
60,
);
let mut lastData = Option::None;
loop {
let delay = time::Duration::from_millis(10000);
thread::sleep(delay);
let answer = openweathermap::update(&receiver);
match answer {
Some(_) => {
lastData = answer;
}
None => {
}
}
send_package(ip.to_string(), &lastData);
}
}
// all the other cases
_ => {