PDA

Просмотр полной версии : МСД-200. Сбор архивных данных в Scada систему с помощью скрипта.



Gorillaz
02.07.2019, 11:45
Добрый день!

Исходные данные:
- Овен МСД-200
- MasterOPC Modbus server 4.2.37
- MasterScada 3.10

Что хочу:
- При пропадании связи с MasterScada необходимо автоматическое "подтягивание" накопленных в МСД-200 значений при возобновлении связи. Насколько это реально?

Что я уже знаю, но не понимаю как сделать:
- в МСД-200 есть пользовательская функция 71 (0х47) с помощью которой можно обращаться к подфункции чтения файлов из прибора (к примеру, ReadFileFirst).
- Данные запросы я должен писать в скриптах MasterOPC Modbus server.


Возможно увидеть пример такого запроса?

Gorillaz
02.07.2019, 15:25
В инструкции к прибору дана структура запроса (фото прикреплено), где есть "длина параметров в байтах". Какие параметры передаются? Где в этом запросе вызывать адрес подфункции? Контрольная сумма ZZ. Что значит ZZ? 43414

Начудил вот такой вот скриптик (пока не рабочий, пытаюсь прочитать хотя бы состояние карты памяти(подфукция 0х06)):


-- Initialization
function OnInit()
end
-- Uninitialization
function OnClose()
end
-- Processing
function OnRead()
--Addr=server.GetCurrentDeviceAddress( );
--server.Message(Addr);
server.Message(Query());
end

function Query()
local send={};
local Addr=server.GetCurrentDeviceAddress( );
table.insert(send, Addr);
table.insert(send, 0x47);
table.insert(send, 0x06);
local sendmask={"byte","byte"};
local dest={};
local destmask={"byte","byte","byte"};
dest=server.SendAndReceiveDataByMask(2,3,sendmask, send, destmask, 200);
end

Gorillaz
04.07.2019, 12:03
Добрый день!

Исходные данные:
- Овен МСД-200
- MasterOPC Modbus server 4.2.37
- MasterScada 3.10

Что хочу сделать:
- При пропадании связи с MasterScada необходимо автоматическое "подтягивание" накопленных в МСД-200 значений при возобновлении связи. Насколько это реально?

Я узнал, что:
- в МСД-200 есть пользовательская функция 71 (0х47) с помощью которой можно обращаться к подфункции чтения файлов из прибора (к примеру, ReadFileFirst(0x03)).
- Данные запросы я должен писать в скриптах MasterOPC Modbus server.


Попытался прочитать хотя бы статус карты памяти, но скрипт не работает.

-- Initialization
function OnInit()
end
-- Uninitialization
function OnClose()
end
-- Processing
function OnRead()
local send={};
local Addr=server.GetCurrentDeviceAddress( );
table.insert(send, Addr);
table.insert(send, 0x11);
table.insert(send, 0x06); -- опрос состояния SD карты
local sendmask={"byte","byte","byte"};
local dest={};
local destmask={"byte","byte","byte","byte"};
dest=server.SendAndReceiveDataByMask(2,3,sendmask, send, destmask, 200);
server.Message(dest[3]);
end

Инструкции:
43473
43474

SCADAMaster
04.07.2019, 12:23
На первый взгляд в скрипте все нормально. Смотрите что именно не работает - вкладка Запросы, смотрите что посылается в порт.
Включите запись лога - смотрите лог.

Gorillaz
04.07.2019, 12:48
Выводится следующий лог:
04-07-2019 12:47:49.577 Tag1:Node1.Device1.Tag1 >> (node)Node1:(device)Device1:(teg)Tag1:(OnRead)::Se ndAndReceiveDataByMask : количество параметров в таблице меньше указанного в параметре Count
stack traceback:
[C]: at 0x0063a91c
[C]: in function 'SendAndReceiveDataByMask'
[string "--[[(R)Node1.Device1.Tag1]]..."]:21: in function <[string "--[[(R)Node1.Device1.Tag1]]..."]:12>

SCADAMaster
04.07.2019, 13:01
Попробуйте так
err,dest,len=server.SendAndReceiveDataByMask(2,tab le.maxn(send),sendmask, send, destmask, 200);
И посмотрите вот эту документацию (https://insat.ru/products/Universal_MasterOPC/MU_MasterOPC_Server_API_UG.pdf) ну и справку тоже

Gorillaz
04.07.2019, 15:26
Переделал скрипт:


-- Initialization
function OnInit()
end
-- Uninitialization
function OnClose()
end
-- Processing
function OnRead()
local send={};
local Addr=server.GetCurrentDeviceAddress( );
table.insert(send, Addr);
table.insert(send, 0x47);
table.insert(send, 0x06); -- опрос состояния SD карты
local sendmask={"byte","byte","byte",0};
local dest={};
local destmask={"byte","byte","byte","byte","byte"};
dest=server.SendAndReceiveDataByMask(2,table.maxn( send),sendmask, send, destmask, 200);

server.Message(dest);
end


Функция возвращает -1, что значит ошибка связи, как я понял. Документ и справку я штудировал, у меня полное ощущение, что я в неверной форме создаю маски запроса и ответа, но документация к прибору не дает мне понимания как это сделать правильно.

SCADAMaster
04.07.2019, 15:58
local sendmask={"byte","byte","byte",0};
А что тут 0 в конце делает?
Смотрите какие запросы отправляет ОРС в порт и сравнивайте с тем что должно.

Gorillaz
04.07.2019, 16:56
Решил воспользоваться более простой функцией 0х11 (узнать марку прибора и версию ПО), в ответе на запрос приходит правильная посылка!!! 4D 53 44 2D 32 30 30 20 56 31 2E 35 31 - эта штучка и есть наименование прибора.Но вот вернуть в читаемом виде с помощью функции SendAndReceiveDataByMask не выходит. Функция возвращает 16 (адрес прибора такой)
04-07-2019 16:54:43.366 Node1.Device1.Tag1:16 .
Сам скрипт:
-- Processing
function OnRead()
local send={};
local Addr=server.GetCurrentDeviceAddress( );
table.insert(send, Addr);
table.insert(send, 0x11);
--table.insert(send, 0x06); -- опрос состояния SD карты
local sendmask={"byte","byte"};
local dest={};
local destmask={"byte","byte","byte","byte"};
dest=server.SendAndReceiveDataByMask(2,table.maxn( send),sendmask, send, destmask, 200);

server.Message(dest);
end



04-07-2019 16:49:37.914 Node1::Device1:(COM6) Rx: [0018] 10 11 0D 4D 53 44 2D 32 30 30 20 56 31 2E 35 31 1E BE
04-07-2019 16:49:37.865 Node1::Device1:(COM6) Tx: [0004] 10 11 CC 7C

Не подскажите, что я не так сделал?

SCADAMaster
04.07.2019, 17:19
Так а что вы вообще сделали? Вот у вас маска запроса:
local destmask={"byte","byte","byte","byte"};
А вот ваш ответ:
Rx: [0018] 10 11 0D 4D 53 44 2D 32 30 30 20 56 31 2E 35 31 1E BE
И как он должен на нее наложиться?
Прочитайте в документации и справке как работает маска, и как ее нужно прописывать.

SCADAMaster
05.07.2019, 10:45
Еще раз - внимательно посмотрите справку к этой функции.
Вы ее вообще неправильно пишите - первым вам параметром идет err

Gorillaz
05.07.2019, 10:56
Добрый день!

10 11 0D 4D 53 44 2D 32 30 30 20 56 31 2E 35 31 1E BE , где:

10 - адрес прибора
11 - функция
0D - количество байт данных
1E BE - CRC
4D 53 44 2D 32 30 30 20 56 31 2E 35 31 - MSD-200 V1.51

Создаю маску:
destmask={"byte"(адрес прибора),"byte"(функция),"byte"(кол-во байт данных),"string:4"(MSD-),"int16:3:10"(200),"string:2"(пробел V),"int16:10"(1),"string"(. (точка)),"int16:2:10"(51)};

Итоговый код:
function OnRead()
local send={};
local Addr=server.GetCurrentDeviceAddress( );
table.insert(send, Addr);
table.insert(send, 0x11);
local sendmask={"byte","byte"};
local dest={};
local destmask={"byte","byte","byte","string:4","int16:3:10","string:2","int16:10","string","int16:2:10"};
dest=server.SendAndReceiveDataByMask(2,table.maxn( send),sendmask, send, destmask, 200);

server.Message(dest[4]); -- Читаю букву "М"
end

Получаю ошибку:
05-07-2019 10:53:24.483 Tag1:Node1.Device1.Tag1 >> (node)Node1:(device)Device1:(teg)Tag1:(OnRead)::[string "--[[(R)Node1.Device1.Tag1]]..."]:20: attempt to index local 'dest' (a number value)
stack traceback:
[C]: in function '__index'
[string "--[[(R)Node1.Device1.Tag1]]..."]:20: in function <[string "--[[(R)Node1.Device1.Tag1]]..."]:9>

SCADAMaster
05.07.2019, 11:28
Ответ был дан ранее

melky
05.07.2019, 11:34
з.ы. у вас в руках устройство с расширенными функциями Modbus, по крайней мере парсер Modbus говорит об этом. Это просто набор запрошенного количества байт, где вы сами определяете набор данных. и сами же этот набор потом раскатываете как вам укажет производитель железки.

Part of Data Package Description Value
10 Slave address 0x10 (16)
11 Function code 0x11 (17)
0D 4D 53 44 2D 32 30 30 20 56 31 2E 35 31 Data
1E BE CRC 0x1EBE (7870)

Точнее набор байт, типы переменных и т.д. должен предоставить производитель устройства...