Segnetics

Вернуться   Segnetics > Форум Segnetics > Вопросы о программировании

Вопросы о программировании Вопросы, касающиеся программирования на FBD

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 25.05.2023, 11:54   #1
SergVK
Member
 
Регистрация: Oct 2018
Сообщения: 78
Благодарил(а): 7 раз(а)
Поблагодарили: 9 раз(а) в 5 сообщениях
По умолчанию Тянем данные из History на сайт пользователя (по шагам)

Решил поделиться в отдельной ветке.

Задача:
Контроллер работает на птичнике (что бы понять масштабы "бедствия"):
Нажмите на картинку для увеличения

Название:  IMG_1093 (1).jpg
Просмотров: 38
Размер:  547.1 Кбайт

Есть в проекте History блок. Записывает данные по остатку поголовья, показания счетчиков, усредненные значения и т.д. по триггеру раз в сутки.

Нажмите на картинку для увеличения

Название:  1684996778166.jpg
Просмотров: 22
Размер:  158.6 Кбайт

Требуется вытянуть данные на пользовательский сайт в виде графика.

Нажмите на картинку для увеличения

Название:  SMLogix - [chiken_monitoring.0.23.2.psl].jpg
Просмотров: 25
Размер:  377.6 Кбайт

График реализован на Chat.js. В качестве данных принимает json через ajax запрос.

Приступаем.
Проект пишу на PHP.
шаг раз:

Код:
		
$queue = new ZMQSocket(new ZMQContext(1), ZMQ::SOCKET_REQ, "sqliteSocket");
$queue->connect("ipc:///var/run/sql_sync");
$res = $queue->send( "ATTACH '/projects/history_data/data.sqlite' AS data;");
$raw_vars = $queue->recv();
С БД общаемся через ZMQ. Подключаем файл с данными.

шаг два:
Получаем список переменных в БД
Код:
                
$strsql = "select * from data.variable;\0"; 
                echo $strsql;
		$res = $queue->send($strsql."\0");
		$raw_vars = $queue->recv();
                $lines = preg_split("/[\n]+/", $raw_vars);
                echo '<pre>';print_r($lines);echo '</pre>';
Если выполнить этот код должны получить примерно следующее:

Нажмите на картинку для увеличения

Название:  Segnetics - Создать новую тему - Google Chrome.jpg
Просмотров: 33
Размер:  255.8 Кбайт

Из этого списка переменных нас интересует два поля id переменной и ее hid. По ним будем искать требуемые нам данные.

шаг три:

Вытягиваем из проекта настройки исторических блоков и связываем их с переменными в БД по hid. Т.к. только они совпадают и там и там.

Код:
// load history config from project file                
$arHistory = array();

$hist = file_get_contents('/projects/load_files.hist');
$jshist =  json_decode($hist, true);

foreach($jshist['blocks'] as $key_blocks => $block){
            foreach($block['sampling']['inputs'] as $key => $sampling ){
                
                if (array_key_exists($sampling['hid'],$varsByUid)){
                    $arHistory[$sampling['pid']] = $sampling;
                    $arHistory[$sampling['pid']]['variable_id'] = $varsByUid[$sampling['hid']]['id'];
                    
                }
            }    
            foreach($block['ports']['data']['in'] as $k_ports_data => $blocks_data){
                if (array_key_exists($blocks_data['pid'],$arHistory)){
                    $arHistory[$blocks_data['pid']]['block'] = $key_blocks;
                    $arHistory[$blocks_data['pid']]['name'] = $blocks_data['name'];
                    $arHistory[$blocks_data['pid']]['~name'] = str_replace(" ", "_", $blocks_data['name']);
                    $arHistory[$blocks_data['pid']]['type'] = $blocks_data['type'];
                }
            }    
}
В результате выполнения этого кода должно получится примерно следующее:

Нажмите на картинку для увеличения

Название:  10.1.0.13userpagesCA0B4516-4AF6-4BFB-8A9C-DA8E325F03EEtrends_sql.php - Google Chrome.jpg
Просмотров: 28
Размер:  120.2 Кбайт

В массиве видим hid и id_variable исторического значения в БД и имя переменной в проекте. При этом переменные собраны по историческим блокам в массивы, каждый набор в своем.

Шаг четыре:
Ищем в массиве переменных требуемую нам по имени в SMLogix. В рамках проекта она должна быть уникальной. У меня это DAY. Соответственно найдя переменную по имени, понимаем в каком блоке она лежит.

отступление
О формате хранения данных в БД
Каждая переменная хранится отдельной записью в таблице.
Привязка записи к переменной происходит по id_variable (которое у нас уже есть в массиве переменных)
Значение может лежать либо в int_value, либо в real_value, зависит от типа значения
Время создания значения хранится в timestamp формат Unix+ UTC(0) - в миллисекундах.

Нажмите на картинку для увеличения

Название:  210.1.0.13userpagesCA0B4516-4AF6-4BFB-8A9C-DA8E325F03EEtrends_sql.php - Google Chrome.jpg
Просмотров: 10
Размер:  92.5 Кбайт

Шаг пять


Что бы вытянуть из блока все записи в табличном виде придется связать записи с известной нам переменной свзанные по timestamp. Запрос на первый взгляд выглядит монструозно, но для БД он вполне перевариваемый.

Код:
select D.id, D.timestamp , D.int_value as DAY , DATETIME((D.timestamp/1000+10800), 'unixepoch') as TIMESTAMP_X 
, t_REJECT_DEFECT.int_value AS REJECT_DEFECT 
, t_LIVED.int_value AS LIVED 
, t_REJECT_DEATH.int_value AS REJECT_DEATH 
, t_REJECTED.int_value AS REJECTED 
, t_WATER_CNTR.int_value AS WATER_CNTR 
, t_EPOWER_CNTR2.int_value AS EPOWER_CNTR2 
, t_EPOWER_DAY.real_value AS EPOWER_DAY 
, t_AVG_TEMP_ROOM.real_value AS AVG_TEMP_ROOM 
, t_AVG_TEMP_OUTSIDE.real_value AS AVG_TEMP_OUTSIDE 
, t_TEMP_ROOM_MAX.real_value AS TEMP_ROOM_MAX 
, t_TEMP_MAX_ROOM_TIME.int_value AS TEMP_MAX_ROOM_TIME 
, t_TEMP_ROOM_MIN.real_value AS TEMP_ROOM_MIN 
, t_TEMP_MIN_ROOM_TIME.int_value AS TEMP_MIN_ROOM_TIME 
from data.value D LEFT JOIN data.value t_REJECT_DEFECT ON t_REJECT_DEFECT.timestamp = D.timestamp AND t_REJECT_DEFECT.id_variable = 13 
LEFT JOIN data.value t_LIVED ON t_LIVED.timestamp = D.timestamp AND t_LIVED.id_variable = 22 
LEFT JOIN data.value t_REJECT_DEATH ON t_REJECT_DEATH.timestamp = D.timestamp AND t_REJECT_DEATH.id_variable = 19 
LEFT JOIN data.value t_REJECTED ON t_REJECTED.timestamp = D.timestamp AND t_REJECTED.id_variable = 4 
LEFT JOIN data.value t_WATER_CNTR ON t_WATER_CNTR.timestamp = D.timestamp AND t_WATER_CNTR.id_variable = 41 
LEFT JOIN data.value t_EPOWER_CNTR2 ON t_EPOWER_CNTR2.timestamp = D.timestamp AND t_EPOWER_CNTR2.id_variable = 6 
LEFT JOIN data.value t_EPOWER_DAY ON t_EPOWER_DAY.timestamp = D.timestamp AND t_EPOWER_DAY.id_variable = 11 
LEFT JOIN data.value t_AVG_TEMP_ROOM ON t_AVG_TEMP_ROOM.timestamp = D.timestamp AND t_AVG_TEMP_ROOM.id_variable = 2 
LEFT JOIN data.value t_AVG_TEMP_OUTSIDE ON t_AVG_TEMP_OUTSIDE.timestamp = D.timestamp AND t_AVG_TEMP_OUTSIDE.id_variable = 27 
LEFT JOIN data.value t_TEMP_ROOM_MAX ON t_TEMP_ROOM_MAX.timestamp = D.timestamp AND t_TEMP_ROOM_MAX.id_variable = 15 
LEFT JOIN data.value t_TEMP_MAX_ROOM_TIME ON t_TEMP_MAX_ROOM_TIME.timestamp = D.timestamp AND t_TEMP_MAX_ROOM_TIME.id_variable = 40 
LEFT JOIN data.value t_TEMP_ROOM_MIN ON t_TEMP_ROOM_MIN.timestamp = D.timestamp AND t_TEMP_ROOM_MIN.id_variable = 24 
LEFT JOIN data.value t_TEMP_MIN_ROOM_TIME ON t_TEMP_MIN_ROOM_TIME.timestamp = D.timestamp AND t_TEMP_MIN_ROOM_TIME.id_variable = 37 
where D.id_variable = 17 limit 100 ;
В результате имеем примерно такой ответ:
Нажмите на картинку для увеличения

Название:  1685000753186.jpg
Просмотров: 25
Размер:  201.2 Кбайт

Дальше уже дело техники средствами PHP разобрать строки, отформатировать данные и выкинуть их в формате json на фронт.
Скрипт на фронте уже загружает данные в график.

Код:
    function ajax_chart(chart, url, data) {
        var data = data || {};

        $.getJSON(url, data).done(function(response) {
            console.log(response);
            chart.data.labels = response.labels;
            chart.data.datasets[0].data = response.data.LIVED; // or you can iterate for multiple datasets
            chart.data.datasets[1].data = response.data.REJECTED; // or you can iterate for multiple datasets
            chart.update(); // finally update our chart
        });
    }
    
  ajax_chart(animalsChart, json_url);
итог
Нажмите на картинку для увеличения

Название:  1685001035642.jpg
Просмотров: 18
Размер:  98.2 Кбайт
SergVK вне форума   Ответить с цитированием
5 благодарности(ей) от:
Старый 25.05.2023, 12:05   #2
ATS
Senior Member
 
Регистрация: Aug 2013
Сообщения: 3 740
Благодарил(а): 12 раз(а)
Поблагодарили: 192 раз(а) в 188 сообщениях
По умолчанию Ответ: Тянем данные из History на сайт пользователя (по шагам)

Цитата
Сообщение от SergVK Посмотреть сообщение
Решил поделиться в отдельной ветке.
Похвально, не ожидал.


Сначала пожалеем бедного, потом съедим вкусного...

Еще раз спасибо - понял свой затык с ZMQ


__________________
Не являюсь сотрудником Segnetics !!!
ATS вне форума   Ответить с цитированием
Ответ

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать свои сообщения

BB code is Вкл.
[IMG] код Вкл.
HTML код Выкл.


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Транслировать данные на сайт chif.com Связь с внешним миром 25 06.12.2021 13:33


Часовой пояс GMT +4, время: 17:51.


Версия vBulletin: 3.8.3
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Segnetics 2005 - 2023