====== Elreha cooling controllers ====== {{ network:vpr_19000_and_logo.png?direct&300|}} The VPR-19000 Controllers for Compressor Compounds, Condenser Fans together with TAR/MSR/SMP refrigeration controller has been popular cooling solution and can be found in many large food malls or supermarkets. There is an obsolete software tool for WinXP to monitor the system, which can show a tree of the controllers network and show/modify their parameters using tables. With the WebHMI visualization, alerting and analytics capabilites, you can greatly empower your refrigeration monitoring system. The controllers can be read using [[custom_protocols?s[]=custom]] Turn to your local representative for more information. SOH = 0x01 STX = 0x02 ETX = 0x03 EOT = 0x04 LIMIT_BYTE_COUNT = 255 CACHE_REFRESH_DELAY = 5 * 60 function readRegister (reg, device, unitId) local iAddrString= tostring(reg.internalAddr) local targetBase = tonumber(string.sub(iAddrString, 1, (#iAddrString - 1))) local targetOffset = tonumber(string.sub(iAddrString, -1)) if replies[targetBase] then ERROR('there is entry for targetBase!') local ifData = replies[targetBase][targetOffset] if ifData then ERROR('there is an entry for page: ') tprint(ifData) return ifData['data'] end end -- ERROR('Target base and offsets ' .. targetBase .. ' ' .. targetOffset) if syncRequest() then local packet = finishRequest() if packet then local b, o = parseRequest(packet) b = tonumber(b) ; o = tonumber(o) if (b and o) then if (not readUntil(string.byte('#'))) then return false else local replyAddr = tonumber(readString(4)) if (replyAddr == b) then ERROR('reply address equals requst addr = ' .. replyAddr) local data = readUntil(ETX) -- DATA PROCESSING if not data then ERROR('Could not read data in response ((( ') return false else -- get string presentation local dataAsString = {} for i, v in ipairs(data) do dataAsString[i] = string.char(v) end data = table.concat(dataAsString) -- ERROR(data) -- check if data in cache if (not replies[b]) then replies[b] = {} ; ERROR('Entry for the ' .. b .. 'device was created!')-- create entry for DEVICE end -- if sub-set in the group if (not replies[b][o]) then replies[b][o] = {} replies[b][o]['data'] = data ; ERROR('Entry for the data in ' .. b .. ' ' .. o .. 'was created!')-- create entry for data replies[b][o]['stamp'] = now ERROR('Now data in cache = ' .. replies[b][o]['data']) end -- check if data is old or no if ((now - replies[b][o]['stamp']) > CACHE_REFRESH_DELAY) then replies[b][o] = nil ; ERROR("Killed data in " .. b .. ' ' .. o .. 'after timeout!') end ERROR('types of targetBase, targetOffset, b, o') ERROR(type(targetBase) .. ' ' .. type(targetOffset) .. ' ' .. type(b) .. ' ' .. type(o)) ERROR('data in cache in this point ' .. replies[b][o]['data']) if not replies[targetBase] or not replies[targetOffset] then ERROR('No data in cache for ' .. targetBase .. ' ' .. targetOffset) return false else return replies[targetBase][targetOffset]['data'] end return 1 end else ERROR('reply address does not equal requst addr = ' .. replyAddr .. ' ' .. b) return false end end else ERROR('Wrong base offset from parseRequest!') return false end else return false end else return false end end -- readRegister