Код:
-- функция,выполняющаяся перед чтением тегов
function OnBeforeReading()
local len; -- количество полученных байт
local startTime;
local ArrCMD={}; --массив под запрос текущих параметров, Было-send2
local ChErr; --error'ы
local ArrCMD_Mask={}; --маска отсылаемого запроса
local ArrCMD_DestMask={}; --маска для текущего состояния
local ArrDest={};
-- задержка чтобы прибор проплевался и стал принимать команды
-- Т.е. код нивелирования последствий предшествующего обмена данными в сети по modbus-протоколу
startTime=os.time()
while true do if os.time()>startTime+2 then break; end; end;
--
-- запрос текущего состояния командой 01h --
table.insert(ArrCMD, 6); --длина блока 6 байт
table.insert(ArrCMD, 225); --тип устройства
table.insert(ArrCMD, 59);-- мл.байт серийного номера (для экземпляра #01595)
table.insert(ArrCMD, 6);-- ст.байт серийного номера (для экземпляра #01595)
table.insert(ArrCMD, 1); --код команды
table.insert(ArrCMD, CheckSum(ArrCMD)); --Контрольная сумма блока запроса
ArrCMD_Mask={"byte", "byte", "byte", "byte", "byte", "byte"}; --маска отсылаемого запроса
ArrCMD_DestMask={"byte", "byte", "int16:1:01", "byte", "float:1:0123", "int16:3:01", "float:5:0123", "byte:6"}; --маска для текущего состояния
len,ArrDest=server.SendAndReceiveDataByMask(0,6,ArrCMD_Mask,ArrCMD,ArrCMD_DestMask,41);
--ожидаем 41 байт в ответ
if len==41 then
server.Message("Запрос выполнен успешно. Получено 41 байт");
server.WriteTag("COM-порт.ВТЭ-2 K2.error", ArrDest[18], OPC_QUALITY_GOOD);
ChErr=CheckErrors(ArrDest[18]); --проверка на наличие ошибок от прибора
--перерасчеты
local temp = ArrDest[5] * 1162.790700;
ArrDest[5] = temp;
ArrDest[6]=ArrDest[6]/100;
ArrDest[7]=ArrDest[7]/100;
--присваиваем тегам считанные с прибора значения
server.WriteTag("COM-порт.ВТЭ-2 K2.ТеплСеть.ТеплЭнВсего", ArrDest[5], ChErr); -- Тепловая энергия
server.WriteTag("COM-порт.ВТЭ-2 K2.ТеплСеть.Тпод", ArrDest[6], ChErr); -- Температура в подающем трубопроводе
server.WriteTag("COM-порт.ВТЭ-2 K2.ТеплСеть.Тобр", ArrDest[7], ChErr); -- Температура в обратном трубопроводе
server.WriteTag("COM-порт.ВТЭ-2 K2.ТеплСеть.РасхВодВсего", ArrDest[9], ChErr); -- Объем по первому расходомеру
server.WriteTag("COM-порт.ВТЭ-2 K2.ТеплСеть.ЭлЭнВсего", ArrDest[13], ChErr); -- Электроэнергия по первому тарифу
else server.Message("ОШИБКА ЧТЕНИЯ: Байт получено: ", len ," -- nil в первом либо пришло меньше 41 байт");
end;
--эта пауза чтобю проплевались остальные приборы, идущие в очереди после ВТЭ-2
StartTime=os.time()
while true do if os.time()>startTime+2 then break; end; end;
end
function CheckErrors(error)
local q;
if error==0 then q=OPC_QUALITY_GOOD
else
--надо побитово анализировать код ошибки
if bit.BitFromData(error, 0) then q=OPC_QUALITY_UNCERTAIN end; --отсутствие расхода по счетчику воды...
if bit.BitFromData(error, 1) then q=OPC_QUALITY_SENSOR_FAILURE end; --температу 1или2 термопреобразователя больше 150 или меньше 0
if bit.BitFromData(error, 2) then q=OPC_QUALITY_SENSOR_FAILURE end; --обратное подключение термопреобразователей 1и2
if bit.BitFromData(error, 3) then q=OPC_QUALITY_DEVICE_FAILURE end; --ошибка системы измерения температур
if bit.BitFromData(error, 4) then q=OPC_QUALITY_DEVICE_FAILURE end; --счетчик часов наработки превысил 4,5года
if bit.BitFromData(error, 5) then q=OPC_QUALITY_DEVICE_FAILURE end; --необходимость замены батарейки
if bit.BitFromData(error, 6) then q=OPC_QUALITY_DEVICE_FAILURE end; --ошибка памяти EEPROM
if bit.BitFromData(error, 7) then q=OPC_QUALITY_COMM_FAILURE end; --энергия в открытой системе отрицательна
end;
return q;
end
function CheckSum(sendtbl)
local cs, j;
cs=0;
for j=1,table.maxn(sendtbl) do --однобайтовое суммирование
if (cs+sendtbl[j])>255 then cs=cs+sendtbl[j]-256
else cs=cs+sendtbl[j]; end;
end;
cs=256-cs; -- инверсией байта дополнение
return cs;
end;