{
  "version": 2,
  "name": "Batch Tank Totaliser",
  "exported": "2026-10-13T00:00:00.000Z",
  "notes": "Generic v1.124 example (not tied to one scene). AX1 = tank level transmitter 0-4095 = 0-2000 L. X1 = Batch Complete PB (N.O.), X2 = Fault Reset PB (N.O.). D1 = level in litres (INT), D10 = level in % (REAL, D10-D11), D12 = refill valve demand (INT) copied to AY1. Each press of X1 logs one batch: D26 = batch count (DINT, D26-D27), D22 = total litres (DINT, D22-D23), D24 = average litres per batch (DINT, D24-D25). Y1 = low level below 200 L. Y3 = math fault lamp (SB12); X2 clears the fault flags and SW17.",
  "program": [
    {"id": 1, "rn": 0,
     "comment": "LEVEL IN LITRES — SCL scales AX1 0-4095 to D1 = 0-2000 L (INT, rounded)",
     "elements": [
       {"id":101,"kind":"contact","type":"XIC","addr":"SB1"},
       {"id":102,"kind":"block","type":"SCL","addr":"D1","src":"AX1","inMin":0,"inMax":4095,"outMin":0,"outMax":2000,"dt":"INT","pre":0}
     ]},
    {"id": 2, "rn": 1,
     "comment": "LEVEL IN PERCENT — CPT as REAL keeps the decimals (D10-D11). Reads AX1, not D1: a REAL CPT would read D1 as a REAL",
     "elements": [
       {"id":103,"kind":"contact","type":"XIC","addr":"SB1"},
       {"id":104,"kind":"block","type":"CPT","addr":"D10","expr":"AX1 * 100.0 / 4095","dt":"REAL","pre":0}
     ]},
    {"id": 3, "rn": 2,
     "comment": "Y1 LOW LEVEL — typed compare on a D register: D1 below 200 L",
     "elements": [
       {"id":105,"kind":"compare","type":"LES","addr":"D1","cmp":200,"dt":"INT"},
       {"id":106,"kind":"output","type":"OTE","addr":"Y1"}
     ]},
    {"id": 4, "rn": 3,
     "comment": "REFILL VALVE — CPT works out the demand from the empty space (0-4095), then MOV copies it to AY1",
     "elements": [
       {"id":107,"kind":"contact","type":"XIC","addr":"SB1"},
       {"id":108,"kind":"block","type":"CPT","addr":"D12","expr":"LIMIT(0, (2000 - D1) * 4095 / 2000, 4095)","dt":"INT","pre":0},
       {"id":109,"kind":"block","type":"MOV","addr":"AY1","src":"D12","st":"INT","pre":0}
     ]},
    {"id": 5, "rn": 4,
     "comment": "BATCH LOG — once per press of X1 (P contact): count the batch, convert the level to DINT, add it to the total",
     "elements": [
       {"id":110,"kind":"contact","type":"P","addr":"X1"},
       {"id":111,"kind":"block","type":"INC","addr":"D26","dt":"DINT","pre":0},
       {"id":112,"kind":"block","type":"MOV","addr":"D20","src":"D1","st":"INT","dt":"DINT","pre":0},
       {"id":113,"kind":"block","type":"ADD","addr":"D22","a":"D22","b":"D20","dt":"DINT","pre":0}
     ]},
    {"id": 6, "rn": 5,
     "comment": "AVERAGE PER BATCH — only when at least one batch is logged, so DIV never divides by zero",
     "elements": [
       {"id":114,"kind":"compare","type":"GRT","addr":"D26","cmp":0,"dt":"DINT"},
       {"id":115,"kind":"block","type":"DIV","addr":"D24","a":"D22","b":"D26","dt":"DINT","pre":0}
     ]},
    {"id": 7, "rn": 6,
     "comment": "Y3 MATH FAULT — SB12 is on while any error flag (SB9 overflow, SB10 divide/invalid, SB11 range) is set",
     "elements": [
       {"id":116,"kind":"contact","type":"XIC","addr":"SB12"},
       {"id":117,"kind":"output","type":"OTE","addr":"Y3"}
     ]},
    {"id": 8, "rn": 7,
     "comment": "FAULT RESET — one press of X2 clears the sticky flags and the error code",
     "elements": [
       {"id":118,"kind":"contact","type":"P","addr":"X2"},
       {"id":119,"kind":"output","type":"OTU","addr":"SB9"},
       {"id":120,"kind":"output","type":"OTU","addr":"SB10"},
       {"id":121,"kind":"output","type":"OTU","addr":"SB11"},
       {"id":122,"kind":"block","type":"MOV","addr":"SW17","src":"0","pre":0}
     ]}
  ],
  "comments": {
    "X1": "Batch Complete PB",
    "X2": "Fault Reset PB",
    "AX1": "Tank Level 0-4095",
    "AY1": "Refill Valve Demand",
    "Y1": "Low Level",
    "Y3": "Math Fault",
    "D1": "Level L",
    "D10": "Level % (REAL)",
    "D12": "Valve Demand",
    "D20": "Batch Litres (DINT)",
    "D22": "Total Litres (DINT)",
    "D24": "Average L/Batch (DINT)",
    "D26": "Batch Count (DINT)"
  },
  "dregs": {},
  "dfmt": {}
}
