weather info initial
This commit is contained in:
parent
1c12173b77
commit
9cc39ab295
@ -8,3 +8,4 @@ edition = "2021"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bit = "0.1.1"
|
bit = "0.1.1"
|
||||||
embedded-graphics = "0.8.0"
|
embedded-graphics = "0.8.0"
|
||||||
|
openweathermap = "0.2.4"
|
||||||
|
@ -1,12 +1,16 @@
|
|||||||
use bit::BitIndex;
|
use bit::BitIndex;
|
||||||
|
use core::time;
|
||||||
use embedded_graphics::{
|
use embedded_graphics::{
|
||||||
image::{Image, ImageRaw},
|
image::{Image, ImageRaw},
|
||||||
|
mono_font::{iso_8859_1::FONT_6X10, MonoTextStyle},
|
||||||
pixelcolor::{BinaryColor, Rgb565},
|
pixelcolor::{BinaryColor, Rgb565},
|
||||||
prelude::*,
|
prelude::*,
|
||||||
primitives::{Line, PrimitiveStyle},
|
primitives::{Line, PrimitiveStyle},
|
||||||
|
text::Text,
|
||||||
};
|
};
|
||||||
use std::env;
|
use openweathermap::{self, CurrentWeather};
|
||||||
use std::net::UdpSocket;
|
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_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;
|
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 IMAGE_LENGTH: usize = (IMAGE_WIDTH_BYTE * IMAGE_HEIGHT_BYTE) as usize;
|
||||||
const PACKAGE_LENGTH: usize = (IMAGE_LENGTH + 1) as usize;
|
const PACKAGE_LENGTH: usize = (IMAGE_LENGTH + 1) as usize;
|
||||||
|
|
||||||
struct UdpDisplay<'a> {
|
struct UdpDisplay {
|
||||||
image_slice: &'a mut[u8; IMAGE_SIZE_BYTE],
|
image: [u8; IMAGE_SIZE_BYTE],
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OriginDimensions for UdpDisplay<'_> {
|
impl OriginDimensions for UdpDisplay {
|
||||||
fn size(&self) -> Size {
|
fn size(&self) -> Size {
|
||||||
Size::new(IMAGE_WIDTH, IMAGE_HEIGHT)
|
Size::new(IMAGE_WIDTH, IMAGE_HEIGHT)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DrawTarget for UdpDisplay<'_> {
|
impl DrawTarget for UdpDisplay {
|
||||||
type Color = BinaryColor;
|
type Color = BinaryColor;
|
||||||
type Error = core::convert::Infallible;
|
type Error = core::convert::Infallible;
|
||||||
|
|
||||||
@ -63,33 +67,86 @@ impl DrawTarget for UdpDisplay<'_> {
|
|||||||
I: IntoIterator<Item = Pixel<Self::Color>>,
|
I: IntoIterator<Item = Pixel<Self::Color>>,
|
||||||
{
|
{
|
||||||
for pixel in pixels {
|
for pixel in pixels {
|
||||||
|
if pixel.0.x < 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if pixel.0.y < 0 {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
let x = pixel.0.x as u32;
|
let x = pixel.0.x as u32;
|
||||||
let y = pixel.0.y 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();
|
let v = pixel.1.is_on();
|
||||||
|
//println!("pint {x} {y} is on {v}");
|
||||||
let offset: usize = (x + y * IMAGE_WIDTH) as usize;
|
let offset: usize = (x + y * IMAGE_WIDTH) as usize;
|
||||||
|
|
||||||
let subbit: usize = (offset % 8).into();
|
let subbit: usize = (offset % 8).into();
|
||||||
let byte_offset: 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);
|
current.set_bit(subbit, v);
|
||||||
}
|
}
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_package(ipaddress: String) {
|
fn send_package(ipaddress: String, data: &Option<Result<CurrentWeather, String>>) {
|
||||||
let mut package = [0; PACKAGE_LENGTH];
|
let mut package: [u8; PACKAGE_LENGTH] = [0; PACKAGE_LENGTH];
|
||||||
|
|
||||||
// Brightness
|
// Brightness
|
||||||
package[0] = 128;
|
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))
|
let style = PrimitiveStyle::with_stroke(BinaryColor::On, 1);
|
||||||
.into_styled(PrimitiveStyle::with_stroke(BinaryColor::On, 1))
|
let text_style = MonoTextStyle::new(&FONT_6X10, BinaryColor::On);
|
||||||
.draw(&mut display).unwrap();
|
|
||||||
|
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");
|
let socket = UdpSocket::bind("0.0.0.0:4242").expect("couldn't bind to address");
|
||||||
socket
|
socket
|
||||||
@ -119,7 +176,32 @@ fn main() {
|
|||||||
// one argument passed
|
// one argument passed
|
||||||
2 => {
|
2 => {
|
||||||
let ip = &args[1];
|
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
|
// all the other cases
|
||||||
_ => {
|
_ => {
|
||||||
|
Loading…
Reference in New Issue
Block a user