--[[ ======================================== 4–20 mA TO IEC104 ANALOG (LINEAR SCALING) FOR 10 INPUT TAGS ======================================== PURPOSE: Converts up to 10 input tags (4–20 mA values) into engineering values using linear equation: y = (m * x) + c WHERE: x = input value (Modbus) y = scaled output value (IEC104) USER CONFIGURATION: Define input and output ranges below. RECOMMENDED SETTINGS: IN_MIN = 4 (4 mA) IN_MAX = 20 (20 mA) OUT_MIN = 0 (e.g. 0 bar) OUT_MAX = 100 (e.g. 100 bar) FORMULA: m = (OUT_MAX - OUT_MIN) / (IN_MAX - IN_MIN) c = OUT_MIN - (m * IN_MIN) EXAMPLE: Input: 12 mA Output: 50 (for 0–100 range) IMPORTANT: - Supports input["1"] to input["10"] - Output will be output["1"] to output["10"] - Each input is processed independently ======================================== ]] function AnalogScaling(input) -- Handle nil input if input == nil then return {} end local output = {} ------------------------------------------------- -- USER EDIT SECTION ------------------------------------------------- -- Input range (4–20 mA) local IN_MIN = 4000 local IN_MAX = 20000 -- Output range (engineering units) local OUT_MIN = 0 local OUT_MAX = 100 -- Calculate slope and intercept local m = (OUT_MAX - OUT_MIN) / (IN_MAX - IN_MIN) local c = OUT_MIN - (m * IN_MIN) ------------------------------------------------- -- Loop through 10 input tags for tag = 1, 10 do local key = tostring(tag) local inVec = input[key] -- Skip if no valid input if type(inVec) ~= "table" then -- Optionally create empty output -- output[key] = {} else local outVec = {} for i, v in ipairs(inVec) do local x = v.value or 0 -- Apply scaling local y = (m * x) + c table.insert(outVec, { value = y, quality = v.quality or 0, timestamp = v.timestamp or 0 }) end output[key] = outVec end end return output end