Skip to content

Commit

Permalink
Merge pull request '[app, complex, meln_logic] Применение структуры M…
Browse files Browse the repository at this point in the history
…eln в программе. Closed #8' (#16) from meln_logic into master

Reviewed-on: https://git.oberon-alfa.ru/prishchepa.aleksej/SimpleUI_Rust/pulls/16

Реактивный подход для автоматизации внедрён
  • Loading branch information
prishchepa.aleksej committed Oct 22, 2021
2 parents c5b9c90 + e481486 commit 49f61c7
Show file tree
Hide file tree
Showing 21 changed files with 713 additions and 432 deletions.
1 change: 1 addition & 0 deletions meln_logic/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ name = "meln_logic"
tokio = { version = "1.3.0", features = ["sync", "macros"]}
async-stream = "*"
futures-core = "0.3"
futures-util = "0.3"

macros = {path="./macros", package="meln_logic_macro", optional=true}
modbus = {path = "../modbus", optional=true}
Expand Down
2 changes: 1 addition & 1 deletion meln_logic/src/init_clear.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ impl Complect {
let pdu_rs = Arc::new(Device::from(init::make_pdu_rs("192.168.1.13", 12)));
let owen_mkon = Arc::new(Device::from(init::make_mkon("192.168.1.13", 1)));

let values = Self::init_values(&mut [&invertor_1.device(), &invertor_1.device(), &digit_i.device(), &digit_o.device(), &analog_1, &analog_2, &pdu_rs]);
let values = Self::init_values(&mut [&invertor_1.device(), &invertor_2.device(), &digit_i.device(), &digit_o.device(), &analog_1, &analog_2, &pdu_rs]);
let values_dozator = values.get_values_by_name_starts(&["Двигатель подачи материала в камеру/", "Направление вращения двигателя ШД/"]);
Complect {
values: values,
Expand Down
5 changes: 3 additions & 2 deletions meln_logic/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,6 @@ pub use init_clear::init;
// pub mod algorithm;
pub mod devices;

mod structs_2;
use structs_2::*;
pub mod structs_2;
pub use structs_2 as structs;
pub use structs_2::{Meln, values, watcher};
18 changes: 10 additions & 8 deletions meln_logic/src/structs_2/dozator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub struct Dozator {
speed: ValueArc, // скоость ШИМа
direct: ValueArc,

target_speed: Mutex<Option<(/*speed:*/ i32, /*delta:*/ i32)>>,
target_speed: Mutex<Option<(/*speed:*/ i32, /*delta:*/ i32, /*step:*/ u32)>>,
}

impl Dozator {
Expand All @@ -30,15 +30,15 @@ impl Dozator {
let mut target_speed = self.target_speed.lock().unwrap();
let current_speed = self.speed();
let dlt: i32 = (speed - current_speed) / Self::STEPS as i32;

*target_speed = Some((speed, dlt));
*target_speed = Some((speed, dlt, Self::STEPS));
}
fn get_next_step(&self) -> Option<i32> {
let mut target = self.target_speed.lock().unwrap();
if let Some((target_speed, delta)) = *target {
if let Some((target_speed, delta, ref mut step)) = target.as_mut() {
let current_speed = self.speed();
if current_speed != target_speed {
return Some(delta);
if *step>0 {
*step -= 1;
return Some(*delta);
}
}
*target = None;
Expand All @@ -53,7 +53,7 @@ impl Dozator {
use tokio::time::{sleep, Duration};
loop {
self.next_step();
sleep(Duration::from_millis(1000 / super::Dozator::STEPS as u64)).await;
sleep(Duration::from_millis(5_000 / super::Dozator::STEPS as u64)).await;
}
}
}
Expand All @@ -70,7 +70,9 @@ impl From<&ModbusValues> for Dozator {
}

pub mod watcher {
use crate::Property;
use crate::structs::Property;

#[derive(Default)]
pub struct Dozator {
pub speed: Property<i32>,
pub motor: Property<bool>,
Expand Down
54 changes: 39 additions & 15 deletions meln_logic/src/structs_2/half_meln.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ pub struct HalfMeln {
pub motor: Motor,
pub vibro: ValueArc,
part: HalfPartInner,
pub температура_верх: ValueArc,
pub температура_нижн: ValueArc,
}

enum HalfPartInner {
Expand All @@ -34,54 +36,64 @@ impl From<&HalfPartInner> for HalfPart {

impl HalfMeln {
pub fn low(values: &ModbusValues) -> Self {
let values = values.get_values_by_name_ends(&["М1"])
+ values.get_values_by_name_starts(&["5) Invertor"]);
let values = values.get_values_by_name_contains(&["М1/"]).convert_to_sensor()
+ values.get_values_by_name_start("5) Invertor/");
let температура_масла = ["Температура масла на верхн. выходе дв. М1", "Температура масла на нижн. выходе дв. М1" ];
HalfMeln {
invertor: Invertor::from(&values),
motor: Motor::from(&values),
vibro: values.get_value_arc("Виброскорость").unwrap(),
vibro: values.get_value_arc_starts("Виброскорость").unwrap(),
part: HalfPartInner::Low{
температура_масла_values: values.get_values_by_name_contains(&температура_масла)
},
температура_верх: values.get_value_arc(температура_масла[0]).unwrap(),
температура_нижн: values.get_value_arc(температура_масла[1]).unwrap(),
values: values,
}
}
pub fn top(values: &ModbusValues) -> Self {
let values = values.get_values_by_name_ends(&["М2"])
+ values.get_values_by_name_starts(&["6) Invertor"]);
// values.get_values_by_name_contains(
let values = values.get_values_by_name_contains(&["М2/"]).convert_to_sensor()
+ values.get_values_by_name_start("6) Invertor/");
let температура_подшибника = ["Температура верх подшипника дв. М2", "Температура нижн подшипника дв. М2"];
HalfMeln {
invertor: Invertor::from(&values),
motor: Motor::from(&values),
vibro: values.get_value_arc("Виброскорость").unwrap(),
vibro: values.get_value_arc_starts("Виброскорость").unwrap(),
part: HalfPartInner::Top{
температура_подшибника_values: values.get_values_by_name_contains(&температура_подшибника)
},
температура_верх: values.get_value_arc(температура_подшибника[0]).unwrap(),
температура_нижн: values.get_value_arc(температура_подшибника[1]).unwrap(),
values: values,
}
}
pub fn get_part(&self) -> HalfPart {
HalfPart::from(&self.part)
}

pub fn stop(&self) {
self.invertor.stop();
}
}

pub type Invertor = modbus::InvertorValues;

pub struct Motor {
speed: ValueArc,
// speed: ValueArc,
// speed_changed: Signal<SpeedChange>,

// "Температура статора",
// "Температура ротора Пирометр",
pub температура_статора: ValueArc, // "Температура статора",
pub температура_ротора: ValueArc, // "Температура ротора Пирометр",

температуры_values: ModbusValues, // Значения температур
}

impl From<&ModbusValues> for Motor {
fn from(values: &ModbusValues) -> Self {
Motor {
speed: values.get_value_arc("Скорость двигателя").unwrap(),
// speed: values.get_value_arc("Скорость двигателя").unwrap(),
температура_статора: values.get_value_arc_starts("Температура статора").unwrap(),
температура_ротора: values.get_value_arc_starts("Температура ротора Пирометр").unwrap(),
температуры_values: values.get_values_by_name_contains(&["Температура статора", "Температура ротора Пирометр",]),
}
}
Expand All @@ -96,8 +108,17 @@ pub enum SpeedChange {
Stop, // Остановка
}

impl Default for SpeedChange {
fn default() -> Self {
SpeedChange::Stop
}
}

pub mod watcher {
use crate::Property;
// #[macro_use]
use crate::structs::{Property, changed_any};

#[derive(Default)]
pub struct HalfMeln {
pub invertor: Invertor,
pub motor: Motor,
Expand All @@ -113,16 +134,17 @@ pub mod watcher {
pub(crate) fn update_property(&self, values: &super::HalfMeln) {
use modbus::{Value, TryFrom};
self.invertor.update_property(&values.invertor);
let vibro: f32 = f32::try_from(&values.vibro as &Value).unwrap(); // todo: Необходимо обработать ошибку
self.vibro.set(vibro);
if let Ok(vibro) = f32::try_from(&values.vibro as &Value) { // todo: Необходимо обработать ошибку
self.vibro.set(vibro);
}
}

pub(crate) async fn automation(&self) {
let mut vibro = self.vibro.subscribe();
let mut hz = self.invertor.hz.subscribe();
let mut amper = self.invertor.amper.subscribe();
loop {
crate::changed_any!(vibro, hz, amper);
changed_any!(vibro, hz, amper);
{
let vibro = *vibro.borrow();
let hz = *hz.borrow();
Expand All @@ -141,6 +163,7 @@ pub mod watcher {
}
}

#[derive(Default)]
pub struct Invertor {
pub hz: Property<u32>,
pub speed: Property<u32>,
Expand All @@ -158,6 +181,7 @@ pub mod watcher {
}
}

#[derive(Default)]
pub struct Motor {
pub speed: Property<u32>,

Expand Down
132 changes: 132 additions & 0 deletions meln_logic/src/structs_2/klapans.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
use modbus::{ValueArc, ModbusValues};

pub struct Klapans {
pub давление_воздуха: ValueArc,
двигатель_компрессора_воздуха: ValueArc,

// // Материал
// клапан_подачи_материала: ValueArc, // ШК2
// клапан_верхнего_контейнера: ValueArc, // ШК5
// клапан_помольной_камеры: ValueArc, // ШК3
// клапан_нижнего_контейнера: ValueArc, // ШК1
//
// // Вакуум
// клапан_напуска: ValueArc,
// клапан_насоса: ValueArc,

klapans: ModbusValues,
klapans_шк: ModbusValues,
}

impl From<&ModbusValues> for Klapans {
fn from(values: &ModbusValues) -> Self {
let klapans_шк = (0..12).map(|i|
format!("Клапан ШК{} {}", i/2+1,
if i%2==0 {"открыт"} else {"закрыт"})
).collect::<Vec<_>>();
Klapans {
давление_воздуха: values.get_value_arc("Давление воздуха компрессора").unwrap(),
двигатель_компрессора_воздуха: values.get_value_arc("Двигатель компрессора воздуха").unwrap(),
klapans: values.get_values_by_name_contains(
&["Клапан нижнего контейнера", "Клапан верхнего контейнера",
"Клапан подачи материала", "Клапан помольной камеры",
"Клапан напуска", "Клапан насоса М5"]
),
klapans_шк: values.get_values_by_name_contains(
klapans_шк.iter().map(|name| name.as_str())
.collect::<Vec<_>>().as_slice()
),
}
}
}

impl Klapans {

pub fn klapan_turn(&self, name: &str, enb: bool) {
// if self.давление_воздуха.is_error() {
// return;
// }

if let Err(e) = self.klapans.set_bit(name, enb) {
dbg!(e);
}
}
fn двигатель_компрессора_воздуха_turn(&self, enb: bool) {
self.двигатель_компрессора_воздуха.set_bit(enb);
}
}

pub mod watcher {
use crate::structs::Property;
use std::collections::HashMap;
use tokio::sync::broadcast;

pub struct Klapans {
pub давление_воздуха: Property<f32>,

pub klapans: HashMap<String, Property<bool>>,
pub klapans_send: broadcast::Sender<(String, bool)>,

pub klapans_шк: HashMap<(String, String), Property<bool>>,
pub klapans_шк_send: broadcast::Sender<(String, bool)>,
}
impl Klapans {
pub(crate) fn update_property(&self, values: &super::Klapans) {
for (n, p) in &self.klapans {
p.set(values.klapans.get_bit(n).unwrap());
}
for ((шк, _n), p) in &self.klapans_шк {
p.set(values.klapans_шк.get_bit(&format!("Клапан {} открыт", шк)).unwrap());
}
}

pub(crate) async fn automation(&self) {
let futs1 = self.klapans.iter()
.map(|(name, prop)| {
let mut sub = prop.subscribe();
async move {
loop {
sub.changed().await;
let klapan = sub.borrow();
let _ = self.klapans_send.send((name.to_owned(), *klapan));
}
}
});
let futs2 = self.klapans_шк.iter()
.map(|((_шк, name), prop)| {
let mut sub = prop.subscribe();
async move {
loop {
sub.changed().await;
let klapan = sub.borrow();
let _ = self.klapans_send.send((name.to_owned(), *klapan));
}
}
});
tokio::join!(
futures_util::future::join_all(futs1),
futures_util::future::join_all(futs2),
);
}
}

impl Default for Klapans {
fn default() -> Self {
let klapan_names = [
("ШК1", "Клапан нижнего контейнера"), // ШК1
("ШК3", "Клапан верхнего контейнера"), // ШК5
("ШК2", "Клапан подачи материала"), // ШК2
("ШК5", "Клапан помольной камеры"), // ШК3
("ШК4", "Клапан напуска"), // ШК4
("ШК6", "Клапан насоса М5"), // ШК6
];
Klapans {
давление_воздуха: Property::default(),
klapans: klapan_names.iter().map(|&(_, n)| (n.to_owned(), Property::<bool>::default())).collect(),
klapans_send: broadcast::channel(16).0,
klapans_шк: klapan_names.iter().map(|&(шк, n)| ((шк.to_owned(), n.to_owned()), Property::<bool>::default())).collect(),
klapans_шк_send: broadcast::channel(16).0,
}
}
}
}
13 changes: 11 additions & 2 deletions meln_logic/src/structs_2/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,20 @@ impl From<&ModbusValues> for Material {
}
}

impl Material {
pub fn ШК_в_рабочее_положение(&self, enb: bool) {
self.клапан_нижнего_контейнера.set_bit(enb);
self.клапан_верхнего_контейнера.set_bit(enb);
//self.set_klapan("Клапан подачи материала", enb); // ШК2
self.клапан_помольной_камеры.set_bit(enb);
}
}

pub mod watcher {
use crate::Property;
use super::super::*;
use crate::structs::*;
use dozator::watcher::Dozator;

#[derive(Default)]
pub struct Material {
pub dozator: Dozator,

Expand Down
Loading

0 comments on commit 49f61c7

Please sign in to comment.