Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Надежный физический интерфейс для управления умным домом

Компоненты и расходные материалы

Сервопривод TowerPro SG90 × 1
Маленькие петли × 1 комплект
Кнопки × 1 комплект
Arduino Yun × 1
Трансформатор тока 100А × 1
Резисторы и конденсаторы × 7 шт.

О проекте

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Смотрите два видео ниже для быстрого понимания проекта.

Физический интерфейс домашней автоматизации — управление реальным миром

Интерфейс передает информацию и позволяет управлять. Большинство систем умного дома используют «виртуальный интерфейс»: достаете телефон, открываете приложение, смотрите состояние дома, включаете/выключаете свет. Это работает, когда вы вне дома. Но виртуальное представление требует фокуса, неинтуитивно.

Я хотел сделать «физический интерфейс» — маленькую модель дома, которая физически копирует состояния реального дома. Если гараж открыт — ворота модели тоже открыты. Модель на столе — взглянете перед сном: гараж открыт? На работе — глянете: входная дверь закрыта? Физический интерфейс может быть таким творческим или утилитарным, каким вы его сделаете.

Надежный физический интерфейс для управления умным домом

План:

  1. Построить модель дома: положение дверей, потребление энергии, свет.
  2. Сделать монитор энергии (библиотека OpenEnergyMonitor), слать данные в модель и в OpenHAB.
  3. Способы передачи положения дверей/окон. Использование Wink Hub и датчика Wink Tripper в DIY-системе.
  4. Использование Wink + Arduino для выходов: открытие реальных ворот гаража, включение света.

Модель имеет сервоприводы и LED, подключенные к Arduino. Контроллер подписан на MQTT-топики (положение дверей, энергия) и двигает сервы. То же для LED индикации света. Есть варианты доставки данных датчиков к MQTT-брокеру — детально в следующих шагах. В центре — Raspberry Pi с Mosquitto (MQTT) и OpenHAB. OpenHAB не обязателен для модели, но нужен для приложения на телефоне и удаленного мониторинга/управления. Физический интерфейс не значит отказ от виртуального.

На модели две кнопки: одна переключает Zigbee-лампочку, вторая — открывает/закрывает реальные ворота гаража.

Часть 1: Постройка модели дома

Шаг 1: Конструкция модели

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Не претендую на прескриптивность. Я новичок в поделках — просто покажу как сделал. Стройте под свой дом и заботы. Много места для креатива. Некоторые компоненты (трансформатор тока) используются в следующих шагах.

Компоненты:

Крыша

Вырезал боковой клапан коробки, прикрепил к другому (оставшемуся) для образования крыши. Маленькая коробка для прямого угла, позже усилил LEGO-деталью. Можно импровизировать.

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Двери / Окна

Вырезайте отверстия для дверей. Петля на двери (двухсторонний скотч) → к дому. Использовал 3M пенные полоски. Сервоприводы тоже на пенном скотче. Гараж: серва открывает, гравитация закрывает. Входная дверь: нитка на петле, серва тянет за нитку. Желтая LEGO-деталь — отступ сервы от петли.

Надежный физический интерфейс для управления умным домом

Счетчик энергии

Стрелка на руке сервы. Кустик с шкалой киловатт, серва втиснута между коробкой и кустиком.

Надежный физический интерфейс для управления умным домом

Над сервой энергии — красный LED.

Две кнопки управления светом и воротами гаража. Моментальные, резьба с гайкой снаружи для фиксации к картону. Снаружи металлические контакты для пайки проводов.

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Шаг 2: Проводка и код

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Проводка

Схема на фото. Если нужно просто соответствие пинов:

Варианты контроллера

Arduino Uno клон + Ethernet Shield (~$20) — дешевле, но привязывает к кабелю. Перешел на Arduino Yun (~$65) — дороже, но Wi-Fi свобода. Yun прост: подключить к роутеру кабелем → веб-интерфейс Yun → пароли/статический IP → загрузить скетч.

Скетчи для Uno и Yun во вложениях. Похожи, кроме Ethernet/Yun bridge. Кнопки добавил после перехода на Yun, поэтому в скетче Uno их нет.

Видео с Yun (в шаге 1). Видео с Uno + Ethernet Shield (кнопок еще не было): YouTube

Файлы: smarthome_ethernet.ino, smarthome_yun.ino

Часть 2: Входы (Датчики)

Шаг 3: Датчик: Монитор энергии

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Теперь нужен сенсорный узел для чтения потребления дома и публикации в MQTT. Способов несколько. Я использую Arduino Yun — проще, но не дешевле. Альтернативы: Uno + Ethernet Shield + Wi-Fi роутер-бридж, или Raspberry Pi + OpenEnergyMonitor. Опишу Yun.

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Трансформатор тока $7 с eBay (Yhdc SCT-013-000 100A). Схема подключения выше, скетч Yun внизу шага. Поменяйте IP MQTT-брокера. Референс: OpenEnergyMonitor. Идеальные значения компонентов:

Моя схема не совпадает с идеальной: не было 33 Ом — поставил 2×68 Ом параллельно. Не было 10 мкФ — 2×22 мкФ последовательно (эквивалент ~11 мкФ, достаточно).

Трансформатор на одной входящей фазе. Только один 100А трансформатор — мониторю одну фазу. Хочу добавить больше для второй фазы и групповых цепей. По амперметру: моя схема всегда показывает +1А выше реального — просто вычитаю в коде.

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

OpenHAB

Данные идут — выведем в OpenHAB для графиков. Конфиг:

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Items:

Number itm_smarthome_energy_amps "Energy (amps) [%.1f]" {mqtt="<[mymosquitto:2853:state:default]"}
Number itm_smarthome_energy_watts "Energy (Watts) [%.1f]" {mqtt="<[mymosquitto:2852:state:default]"}

Sitemap:

Text label="Energy" icon="firstfloor"
{
  Frame label="Energy Usage" {
    Text item=itm_smarthome_energy_amps
    Text item=itm_smarthome_energy_watts
    Chart item=itm_smarthome_energy_watts period=h refresh=5000
  }
}

Persistence (RRD4J):

Strategies {
  everyMinute : "0 * * * * ?"
}
Items {
  DemoSwitch,NoOfLights,Window_GF_Toilet,Heating* : strategy = everyChange, everyMinute, restoreOnStartup
  Temperature*,Weather_Chart* : strategy = everyMinute, restoreOnStartup
  itm_smarthome_energy_watts : strategy = everyUpdate
}

Экран энергии в OpenHAB:

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Файл: energy_monitor_yun.ino

Шаг 4: Датчик: DIY беспроводные сенсорные узлы

Надежный физический интерфейс для управления умным домом

Варианты беспроводных датчиков открытия/закрытия.

В прошлом проекте использовал $5 радио-трансивер для отправки данных через MQTT-шлюз. Еще использую для статуса ворот гаража в OpenHAB — в демо видео именно так модель отражает реальные ворота. Код и схема в том проекте (в гараже, эстетика не важна).

Также датчик света (фоторезистор) — показывает, оставлен ли свет включенным. Часть «Uber sensor» из того же проекта. Здесь просто подписываюсь на MQTT-топик уровня света.

Надежный физический интерфейс для управления умным домом

Сделал батарейный рид-свитч на том же трансивере/шлюзе. Но выглядит ужасно — не поставишь на внутреннюю дверь/окно. Поэтому использую красивые потребительские датчики Wink — следующий шаг.

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Шаг 5: Датчик: Wink Hub

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Нашел блог раннего пользователя Wink Hub, взломавшего хаб для доступа к PHP-эксплойту. Утилита «aprontest» позволяет управлять устройствами, спаренными с Wink. Так я управляю светом из OpenHAB.

Главное преимущество рутированного Wink Hub — локальное управление светом и чтение датчиков без интернета (Wink API всегда ходит на сервер Wink). Теперь операции остаются в локальной LAN.

Надежный физический интерфейс для управления умным домом

PHP-скрипт (внизу шага) запускается на Raspberry Pi, опрашивает Wink Hub о статусе двух Wink Tripper рид-свитчей. Статус → OpenHAB через REST API. OpenHAB публикует MQTT-топики положения дверей. Контроллер модели подписывается и двигает двери.

Три конфига OpenHAB (items, sitemap, rules) во вложениях — нужны для работы. Определяют контактные items для polling-скрипта через REST. Есть пример скрипта управления Zigbee-лампочкой через OpenHAB.

Видео: YouTube

Скрипты и конфиги: sitemap.txt, rules.txt, items.txt, demo_1_general.sh, polling.php

Шаг 6: Выход: Свет

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Конфиги из шага 5 уже дают всё для управления «умной лампочкой» через физический интерфейс и OpenHAB. Лампочки, поддерживаемые Wink: тестировал Cree Connected и GE Wink — работают. Видео работы датчика света и кнопок: YouTube

Шаг 7: Выход: Открыватель ворот гаража

Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом
Надежный физический интерфейс для управления умным домом

Конфиги шага 5 покрывают OpenHAB items для ворот. Нужно устройство для физического открытия. Использую модификацию прошлого проекта:

Arduino управляет рид-реле (замыкает/размыкает сухие контакты). Кнопка пульта запаяна параллельно контактам реле. Pin 5 и GND Arduino → катушка реле (два внешних пина), внутренние контакты реле → кнопка пульта.

Arduino подписан на MQTT-топик, ждет команду open/close. При получении — кратковременно заряжает реле, замыкая кнопку пульта. Скетч во вложениях. Добавьте garage_monitor_rules.txt в rules (дополнительно к rules шага 5). Если не используете ультразвуковой датчик — адаптируйте.

Видео: YouTube

Если ворота тихие или нужен звуковой алерт в другом месте дома — правило выше воспроизводит аудиофайл при открытии. Слышно в первом демо ~1:30. YouTube

Файлы: garage_monitor_rules.txt, grage_opener.ino

Шаг 8: Другие мысли

Надежный физический интерфейс для управления умным домом

Решения отражают мои инструменты, запчасти и приоритеты. У вас — другие. MQTT + OpenHAB дают гибкость — не обязательно копировать точно.

Много способов. Я тяну к «наименьшему общему знаменателю» — Arduino и картонные коробки.

Код

smarthome_yun.ino

// Eric Tsai
// 2015-04-13
// Arduino Yun code for controlling physical smart home interface
// Modify MQTT topic names to match your use
// Modify MQTT broker IP address

#include 
#include 
#include 
#include 

unsigned long keepalivetime=0;
unsigned long MQTT_reconnect=0;

YunClient yun;
PubSubClient client("192.168.1.101", 1883, callback, yun);
bool conn_ok;

int ledPin = 4;       // indicate lights on
int statusPin = 7;    // indicate MQTT conn status

int servo1Pin = 3;    // front door
int servo2Pin = 5;    // garage door
int servo3Pin = 6;    // energy usage meter
Servo servo1, servo2, servo3;

int button1 = 8;      // button over front door
int button2 = 9;      // button over garage door

int servo1_target = 5;    // door, closed
int servo2_target = 5;    // garage, closed
int servo3_target = 180;  // energy, 180 = "0" watts (motor mounted backwards)

int servo1_pos_cur = 5;
int servo2_pos_cur = 5;
int servo3_pos_cur = 180;

int servo1Opened = 5;
int servo1Closed = 130;
int servo2Opened = 5;
int servo2Closed = 150;

unsigned long servo1_time = 0;
unsigned long servo2_time = 0;
unsigned long servo3_time = 0;

unsigned long button1_db = 0;
unsigned long button2_db = 0;
int button = 0;
int callback_flag = 0;
char buff_message[12];

void callback(char* topic, byte* payload, unsigned int length) {
  int mytopic = atoi(topic);
  payload[length] = '\0';
  float mymsg = atof((const char*)payload);

  if (mytopic == 2822) { // LED
    digitalWrite(ledPin, mymsg == 1 ? HIGH : LOW);
  }
  if (mytopic == 2832) { // servo 1, front door
    servo1_target = (mymsg == 1) ? servo1Opened : servo1Closed;
  }
  if (mytopic == 2842) { // servo 2, garage door
    servo2_target = (mymsg == 1) ? servo2Opened : servo2Closed;
  }
  if (mytopic == 2852) { // servo 3, energy meter
    if (mymsg > 6000) mymsg = 6000;
    if (mymsg < 0) mymsg = 0;
    servo3_target = 180 - ((1 - ((6000 - mymsg) / 6000)) * 180) - 25;
    callback_flag = 1;
  }
}

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(statusPin, OUTPUT);
  pinMode(button1, INPUT_PULLUP);
  pinMode(button2, INPUT_PULLUP);
  digitalWrite(ledPin, HIGH);
  Bridge.begin();
  client.connect("yun smarthome");
  client.publish("watch", "Smart Home Connected!");
  keepalivetime = millis();
  MQTT_reconnect = millis();
  client.subscribe("2822");
  client.subscribe("2832");
  client.subscribe("2842");
  client.subscribe("2852");
  digitalWrite(ledPin, LOW);
  servo1.attach(servo1Pin); servo1.write(90);
  servo2.attach(servo2Pin); servo2.write(90);
  servo3.attach(servo3Pin); servo3.write(5);
}

void loop() {
  client.loop();

  if ((millis() - servo1_time) > 20) {
    if (servo1_pos_cur > servo1_target) servo1_pos_cur--;
    if (servo1_pos_cur < servo1_target) servo1_pos_cur++;
    servo1.write(servo1_pos_cur);
    servo1_time = millis();
  }
  if ((millis() - servo2_time) > 20) {
    if (servo2_pos_cur > servo2_target) servo2_pos_cur--;
    if (servo2_pos_cur < servo2_target) servo2_pos_cur++;
    servo2.write(servo2_pos_cur);
    servo2_time = millis();
  }
  if ((millis() - servo3_time) > 20) {
    if (servo3_pos_cur > servo3_target) servo3_pos_cur--;
    if (servo3_pos_cur < servo3_target) servo3_pos_cur++;
    servo3.write(servo3_pos_cur);
    servo3_time = millis();
  }

  if (callback_flag == 1) {
    callback_flag = 0;
    dtostrf(servo3_target, 4, 5, buff_message);
    client.publish("watch", buff_message);
  }

  button = digitalRead(button1);
  if (button == 0) {
    if ((millis() - button1_db > 3000) || (button1_db > millis())) {
      button1_db = millis();
      client.publish("2862", "button1 yaya");
    }
  }

  button = digitalRead(button2);
  if (button == 0) {
    if ((millis() - button2_db > 3000) || (button2_db > millis())) {
      button2_db = millis();
      client.publish("2872", "button2 yaya");
    }
  }

  if ((millis() - MQTT_reconnect) > 60000) {
    conn_ok = client.connected();
    digitalWrite(statusPin, conn_ok ? HIGH : LOW);
    if (!conn_ok) {
      client.disconnect();
      delay(5000);
      while (client.connect("smarthouse") != 1) {
        digitalWrite(statusPin, LOW);
        delay(4000);
      }
      digitalWrite(statusPin, HIGH);
    }
    MQTT_reconnect = millis();
    client.publish("watch", "smart home heartbeat!");
  }
}

smarthome_ethernet.ino

// Eric Tsai
// 2015-04-1
// Arduino Uno w/ Ethernet, code for controlling physical smart home interface

#include 
#include 
#include 
#include 

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x43, 0x13 };
byte server[] = { 192, 168, 1, 101 };
EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

unsigned long keepalivetime=0;
unsigned long MQTT_reconnect=0;
bool conn_ok;

int ledPin = 4;
int statusPin = 7;

int servo1Pin = 3;
int servo2Pin = 5;
int servo3Pin = 6;
Servo servo1, servo2, servo3;

int servo1_target = 5;
int servo2_target = 5;
int servo3_target = 180;
int servo1_pos_cur = 5;
int servo2_pos_cur = 5;
int servo3_pos_cur = 180;
int servo1Opened = 5;
int servo1Closed = 120;
int servo2Opened = 5;
int servo2Closed = 150;

unsigned long servo1_time = 0;
unsigned long servo2_time = 0;
unsigned long servo3_time = 0;

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.println("received MQTT");
  int mytopic = atoi(topic);
  payload[length] = '\0';
  float mymsg = atof((const char*)payload);

  Serial.print("("); Serial.print(mytopic); Serial.print(", "); Serial.print(mymsg); Serial.println(")");

  if (mytopic == 2822) { digitalWrite(ledPin, mymsg == 1 ? HIGH : LOW); }
  if (mytopic == 2832) { servo1_target = (mymsg == 1) ? servo1Opened : servo1Closed; Serial.println(servo1_target); }
  if (mytopic == 2842) { servo2_target = (mymsg == 1) ? servo2Opened : servo2Closed; }
  if (mytopic == 2852) {
    if (mymsg > 6000) mymsg = 6000;
    if (mymsg < 0) mymsg = 0;
    servo3_target = 180 - ((1 - ((6000 - mymsg) / 6000)) * 180);
  }
}

void setup() {
  Serial.begin(9600);
  Serial.println("starting");
  pinMode(ledPin, OUTPUT);
  pinMode(statusPin, OUTPUT);
  digitalWrite(ledPin, HIGH);
  while (Ethernet.begin(mac) != 1) {
    Serial.println("Error getting IP via DHCP, retry...");
    delay(5000);
  }
  Serial.println("ethernet OK");
  keepalivetime = millis();
  while (client.connect("smarthouse") != 1) {
    Serial.println("Error connecting to MQTT");
    delay(4000);
  }
  MQTT_reconnect = millis();
  Serial.println("setup complete");
  client.publish("smarthouse", "hello world");
  client.subscribe("2822");
  client.subscribe("2832");
  client.subscribe("2842");
  client.subscribe("2852");
  digitalWrite(ledPin, LOW);
  servo1.attach(servo1Pin); servo1.write(90);
  servo2.attach(servo2Pin); servo2.write(90);
  servo3.attach(servo3Pin); servo3.write(5);
}

void loop() {
  client.loop();

  if ((millis() - servo1_time) > 20) {
    if (servo1_pos_cur > servo1_target) servo1_pos_cur--;
    if (servo1_pos_cur < servo1_target) servo1_pos_cur++;
    servo1.write(servo1_pos_cur);
    servo1_time = millis();
  }
  if ((millis() - servo2_time) > 20) {
    if (servo2_pos_cur > servo2_target) servo2_pos_cur--;
    if (servo2_pos_cur < servo2_target) servo2_pos_cur++;
    servo2.write(servo2_pos_cur);
    servo2_time = millis();
  }
  if ((millis() - servo3_time) > 20) {
    if (servo3_pos_cur > servo3_target) servo3_pos_cur--;
    if (servo3_pos_cur < servo3_target) servo3_pos_cur++;
    servo3.write(servo3_pos_cur);
    servo3_time = millis();
  }

  if ((millis() - MQTT_reconnect) > 60000) {
    conn_ok = client.connected();
    digitalWrite(statusPin, conn_ok ? HIGH : LOW);
    Serial.println(conn_ok ? "MQTT connected OK" : "MQTT NOT connected OK");
    if (!conn_ok) {
      client.disconnect();
      delay(5000);
      while (client.connect("smarthouse") != 1) {
        digitalWrite(statusPin, LOW);
        delay(4000);
      }
      digitalWrite(statusPin, HIGH);
    }
    MQTT_reconnect = millis();
    client.publish("smarthouse", "heartbeat every minute!");
  }
}

energy_monitor_yun.ino

/* Eric Tsai 2015-04-22
   Arduino Yun code for publishing energy use to MQTT broker
   Modify the "PubSubClient client" for your broker IP address */

#include 
#include 
#include 
#include "EmonLib.h"

int LED = 3;
EnergyMonitor emon1;
unsigned long MQTT_reconnect = 0;
unsigned long read_energy = 0;
double Irms;
bool conn_ok;

YunClient yun;
void callback(char* topic, byte* payload, unsigned int length) {
  digitalWrite(LED, HIGH);
  delay(500);
  digitalWrite(LED, LOW);
}

PubSubClient client("192.168.1.101", 1883, callback, yun);

void setup() {
  pinMode(LED, OUTPUT);
  digitalWrite(LED, HIGH);
  delay(1000);
  digitalWrite(LED, LOW);
  Bridge.begin();
  client.connect("yun_energy");
  client.publish("watch", "Energy Monitor Connected!");
  client.subscribe("yun_energy");
  digitalWrite(LED, HIGH);
  delay(3000);
  digitalWrite(LED, LOW);
  emon1.current(5, 60); // pin, calibration
}

void loop() {
  char buff_message[12];
  float value;
  client.loop();
  Irms = emon1.calcIrms(1480);

  if (millis() - read_energy > 10000) {
    value = Irms;
    dtostrf(value, 4, 5, buff_message);
    client.publish("2853", buff_message); // amps
    value = Irms * 115;
    dtostrf(value, 4, 5, buff_message);
    client.publish("2852", buff_message); // watts
    read_energy = millis();
  }

  if ((millis() - MQTT_reconnect) > 60000) {
    conn_ok = client.connected();
    digitalWrite(LED, conn_ok ? HIGH : LOW);
    if (!conn_ok) {
      client.disconnect();
      delay(5000);
      while (client.connect("yun_energy") != 1) delay(4000);
      digitalWrite(LED, HIGH);
      client.publish("watch", "Energy Monitor reconnected");
    }
    MQTT_reconnect = millis();
  }
}

Схемы

Надежный физический интерфейс для управления умным домом Надежный физический интерфейс для управления умным домом Надежный физический интерфейс для управления умным домом

Производственный процесс

  1. Домашний тест на беременность: принцип действия, дизайн и будущее
  2. Освоение интерфейсов в C#: определение, реализация и практические примеры
  3. Интерфейсы в Java: концепции, реализация и лучшие практики
  4. Как технологии умного дома трансформируют повседневную жизнь
  5. Создайте систему домашней автоматизации на Raspberry Pi для удаленного управления
  6. Labman Automation: пионерские роботизированные решения для промышленности
  7. IoT и домашняя автоматизация: формирование умной жизни завтрашнего дня
  8. Интерфейсы в C#: контракты для надежного ООП
  9. Промышленная автоматизация 4.0: революционизируем производственную эффективность
  10. Автоматизация прессов: технологии, безопасность и эффективность