Initial commit
This commit is contained in:
commit
ceadd2d76d
4 changed files with 688 additions and 0 deletions
176
src/main.rs
Normal file
176
src/main.rs
Normal file
|
@ -0,0 +1,176 @@
|
|||
|
||||
/*
|
||||
Три датчика реалтайм:
|
||||
#26-94-1D-75-C2-F8
|
||||
#T1#6.93
|
||||
#H1#21
|
||||
#P1#700.91
|
||||
##
|
||||
|
||||
Формат пакета данных:
|
||||
#MAC[#NAME]\n
|
||||
#mac1#value1[#time1][#name1]\n
|
||||
...
|
||||
#macN#valueN[#timeN][#nameN]\n
|
||||
##
|
||||
|
||||
Загрузка истории показаний:
|
||||
#26-94-1D-75-C2-F8
|
||||
#T1#6.93#1687006667
|
||||
#T1#10.17#1687006067
|
||||
#T1#27.26#1687005467
|
||||
##
|
||||
|
||||
C названием и координатами:
|
||||
#26-94-1D-75-C2-F8#Метео
|
||||
#OWNER#nm17
|
||||
#T1#6.93#Улица
|
||||
#T2#27.26#Дом
|
||||
#P1#700.91#Барометр
|
||||
#LAT#54.308997
|
||||
#LON#48.395861
|
||||
#ALT#233
|
||||
##
|
||||
*/
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeSet, HashMap, HashSet};
|
||||
use std::mem::{size_of, size_of_val};
|
||||
use std::num::NonZeroUsize;
|
||||
use nom::{InputTake, IResult, Needed, Parser};
|
||||
use nom::branch::alt;
|
||||
use nom::bytes::complete::{take_until, take_while_m_n};
|
||||
use nom::bytes::streaming::{take_till1, take};
|
||||
use nom::bytes::complete::tag;
|
||||
use nom::bytes::streaming::take_till;
|
||||
use nom::character::streaming::{anychar, char, hex_digit0, newline};
|
||||
use nom::character::complete::hex_digit1;
|
||||
|
||||
use nom::combinator::{map, map_opt, map_parser, opt, recognize, rest};
|
||||
use nom::Err as NomErr;
|
||||
use nom::error::{Error, ErrorKind as NomErrorKind};
|
||||
use nom::multi::{count, separated_list1};
|
||||
use nom::sequence::{delimited, preceded, separated_pair};
|
||||
use rust_decimal::Decimal;
|
||||
use thiserror::Error;
|
||||
|
||||
struct NarodMonPacketSerializer {
|
||||
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
struct NarodMonValues<'a> {
|
||||
mac: Cow<'a, str>,
|
||||
value: Decimal,
|
||||
time: Option<u64>,
|
||||
name: Option<u64>
|
||||
}
|
||||
|
||||
#[derive(Eq, PartialEq, Hash, Copy, Clone)]
|
||||
enum ValueMac<'a> {
|
||||
Temperature(Cow<'a, str>, Option<u128>)
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
struct NarodMonPacket<'a> {
|
||||
mac: [u8; 6],
|
||||
name: Option<Cow<'a, str>>,
|
||||
values: HashSet<NarodMonValues<'a>>
|
||||
}
|
||||
|
||||
fn parse_mac_address(input: &str) -> IResult<&str, [u8; 6]> {
|
||||
let mut mac = [0u8; 6];
|
||||
|
||||
let mut counter = 0;
|
||||
|
||||
let (leftovers, i) = take(17usize)(input)?;
|
||||
|
||||
let (_, out) = count(|inp| {
|
||||
//dbg!(inp);
|
||||
let (mut i, o) = map_parser(take(2usize), hex_digit1)(inp)?;
|
||||
if counter != 5 {
|
||||
(i, _) = tag("-")(i)?;
|
||||
}
|
||||
counter+=1;
|
||||
Ok((i, o))
|
||||
}, 6)(i)?;
|
||||
|
||||
//dbg!(&out);
|
||||
|
||||
hex::decode_to_slice(out.join(""), &mut mac).unwrap();
|
||||
|
||||
Ok((leftovers, mac))
|
||||
}
|
||||
|
||||
fn parse_packet(input: &str) -> IResult<&str, NarodMonPacket> {
|
||||
let (input, _) = tag("#")(input)?;
|
||||
|
||||
let (input, mac) = parse_mac_address(input)?;
|
||||
|
||||
dbg!(input);
|
||||
|
||||
let (input, opt_name) = opt(delimited(tag("#"), take_till1(|c| c == '\n'), tag("\n")))(input)?;
|
||||
|
||||
|
||||
|
||||
let (input, values) = parse_sensor_values(input)?;
|
||||
|
||||
Ok((input,
|
||||
NarodMonPacket {
|
||||
mac,
|
||||
name: opt_name,
|
||||
values,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_sensor_value(input: Vec<&str>) -> IResult<&str, NarodMonValues> {
|
||||
Ok(
|
||||
(input, NarodMonValues {
|
||||
mac: Default::default(),
|
||||
value: Default::default(),
|
||||
time: None,
|
||||
name: None,
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
fn parse_sensor_values(input: &str) -> IResult<&str, HashSet<NarodMonValues>> {
|
||||
let (input, asd) = map_parser(take_until("##"),separated_list1(tag("\n"), rest))(input)?;
|
||||
|
||||
|
||||
for line in asd {
|
||||
let one = NarodMonValues::default();
|
||||
let (line, _) = tag("#")(line)?;
|
||||
let (line, sensor_mac) = take_till1(|c| c == '\n' || c == "#")(line);
|
||||
let (line, _) = preceded(tag("#"), take_till1(|c| c == '\n' || c == "#")(line);
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
Ok((input,
|
||||
Default::default()
|
||||
))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, world!");
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_mac() {
|
||||
assert_eq!(parse_mac_address("12-34-AA-12-55-AA"), Ok(("", [18, 52, 170, 18, 85, 170])))
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_packet() {
|
||||
let inp = "#26-94-1D-75-C2-F8#Метео\n";
|
||||
|
||||
println!("{:?}", parse_packet(inp));
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue