<?xml version="1.0" encoding="utf-8"?>
<Templates format="2" protocolVersion="83">
  <Template id="b164fb69-d2c0-42fe-af72-03372bb3fac9" revision="1.0">
    <SuggestedCCUParameters>
      <TcpPort>502</TcpPort>
      <ReadWriteTimeout>1000</ReadWriteTimeout>
    </SuggestedCCUParameters>
    <RevisionHistory>
      <Revision id="1.0">Initial version</Revision>
    </RevisionHistory>
    <Name>solvimus MBUS-GEM – M-Bus water meter</Name>
    <CcuModel>ModbusTcpCCU</CcuModel>
    <Producer>solvimus</Producer>
    <Model>MBUS-GEM</Model>
    <Description/>
    <Category>5</Category>
    <ImportParameters>
      <Parameter>
        <Id>IpAddress</Id>
        <Name>${ipAddress}</Name>
        <Value>192.168.1.100</Value>
      </Parameter>
      <Parameter>
        <Id>SlaveId</Id>
        <Name>Modbus slave address of the meter (with Modbus multi slave: the number in the Register column of the meter row; without it: 255)</Name>
        <Value>1</Value>
      </Parameter>
    </ImportParameters>
    <Module>
      <Name>solvimus MBUS-GEM – water meter</Name>
      <Id>-1</Id>
      <Model>ModbusModule</Model>
      <DeviceProperties>
        <IpAddress>$[IpAddress]</IpAddress>
        <Port>502</Port>
        <SlaveId>$[SlaveId]</SlaveId>
        <MaxPrefetchGroupSize>100</MaxPrefetchGroupSize>
        <PrefetchModeId>0</PrefetchModeId>
        <ModuleVariables>[{&quot;Name&quot;:&quot;RegMeter&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:10},{&quot;Name&quot;:&quot;RegVolume&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:20},{&quot;Name&quot;:&quot;RegFlow&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:30}]</ModuleVariables>
      </DeviceProperties>
      <Devices>
        <Device>
          <Name>Water volume</Name>
          <Id>-2</Id>
          <Model>ModbusVariable</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>15000</InternalPollInterval>
            <IsReadOnly>True</IsReadOnly>
            <PrefetchModeId>0</PrefetchModeId>
            <ReadState>VAR info := MODBUSR(H, RegVolume+7, UInt16);
VAR unit := GETBITS(info, 0, 8);
VAR factor := SWITCH(unit, 7, 1, 0);
IF GETBITS(info, 8, 8) != 0 OR factor = 0
    ADDERROR(1, &quot;RegVolume does not point to a volume value in m³ (entry type &quot; + TOSTRING(GETBITS(info, 8, 8)) + &quot;, unit code &quot; + TOSTRING(unit) + &quot;) – copy the Register number of this value from the gateway Meter tab&quot;);
    RETURN(NaN);
END
RETURN(ROUND(MODBUSR(H, RegVolume+4, Float) * factor * 1000) / 1000);</ReadState>
            <ReadScript>VAR meterInfo := MODBUSR(H, RegMeter+7, UInt16);
VAR medium := 0;
VAR flags := 0;
IF GETBITS(meterInfo, 8, 8) != 2
    ADDERROR(1, &quot;RegMeter does not point to a meter entry (entry type &quot; + TOSTRING(GETBITS(meterInfo, 8, 8)) + &quot;) – set RegMeter to the start of the meter entry (10 with Modbus multi slave, otherwise the Register number of the meter row in the gateway Meter tab)&quot;);
ELSE
    medium := GETBITS(MODBUSR(H, RegMeter+3, UInt16), 0, 8);
    IF medium != 6 AND medium != 7 AND medium != 21 AND medium != 22 AND medium != 23
        ADDWARNING(2, &quot;RegMeter points to a meter with medium code &quot; + TOSTRING(medium) + &quot;, which is not a water meter – check that RegMeter and SlaveId belong to the water meter&quot;);
    END
    flags := MODBUSR(H, RegMeter+8, UInt16);
    IF GETBIT(flags, 0)
        ADDERROR(3, &quot;The gateway could not read the meter in its last readout – check the M-Bus wiring, the meter address and the meter list of the gateway&quot;);
    ELSEIF GETBIT(flags, 1)
        ADDWARNING(4, &quot;Not all meter values were updated in the last gateway readout&quot;);
    END
END</ReadScript>
            <ServiceAttributesFormulas>[{&quot;AttributeDefinition&quot;:{&quot;Name&quot;:&quot;Meter serial number&quot;},&quot;ReadFormula&quot;:&quot;TOSTRING(MODBUSR(H, RegMeter+0, UInt32))&quot;}]</ServiceAttributesFormulas>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Average water flow since previous readout</Name>
          <Id>-3</Id>
          <Model>ModbusVariable</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>15000</InternalPollInterval>
            <IsReadOnly>True</IsReadOnly>
            <PrefetchModeId>0</PrefetchModeId>
            <ReadState>VAR info := MODBUSR(H, RegVolume+7, UInt16);
VAR ts := 0;
VAR vol := 0;
IF GETBITS(info, 8, 8) != 0 OR GETBITS(info, 0, 8) != 7
    ADDERROR(1, &quot;RegVolume does not point to a volume value in m³ (entry type &quot; + TOSTRING(GETBITS(info, 8, 8)) + &quot;, unit code &quot; + TOSTRING(GETBITS(info, 0, 8)) + &quot;) – copy the Register number of the volume value from the gateway Meter tab&quot;);
    RETURN(NaN);
END
ts := MODBUSR(H, RegMeter+4, UInt32);
IF ts = 0
    RETURN(NaN);
END
IF ts != PrevTime
    vol := MODBUSR(H, RegVolume+4, Float);
    IF PrevTime &gt; 0 AND ts &gt; PrevTime AND vol &gt;= PrevVolume
        AvgFlow := (vol - PrevVolume) * 1000 * 3600 / (ts - PrevTime);
    ELSE
        AvgFlow := 0;
    END
    PrevVolume := vol;
    PrevTime := ts;
END
RETURN(AvgFlow);</ReadState>
            <CustomDeviceVariables>[{&quot;Name&quot;:&quot;PrevVolume&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:0},{&quot;Name&quot;:&quot;PrevTime&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:0},{&quot;Name&quot;:&quot;AvgFlow&quot;,&quot;ValueTypeId&quot;:1,&quot;NumericValue&quot;:0}]</CustomDeviceVariables>
          </DeviceProperties>
        </Device>
        <Device>
          <Name>Water flow rate</Name>
          <Id>-4</Id>
          <Model>ModbusVariable</Model>
          <DeviceProperties>
            <DeviceType>0</DeviceType>
            <InternalPollInterval>15000</InternalPollInterval>
            <IsReadOnly>True</IsReadOnly>
            <PrefetchModeId>0</PrefetchModeId>
            <ReadState>VAR info := MODBUSR(H, RegFlow+7, UInt16);
VAR unit := GETBITS(info, 0, 8);
VAR factor := SWITCH(unit, 15, 1, 16, 60, 17, 3600, 0);
IF GETBITS(info, 8, 8) != 0 OR factor = 0
    ADDERROR(1, &quot;RegFlow does not point to a volume flow value (entry type &quot; + TOSTRING(GETBITS(info, 8, 8)) + &quot;, unit code &quot; + TOSTRING(unit) + &quot;) – copy the Register number of this value from the gateway Meter tab&quot;);
    RETURN(NaN);
END
RETURN(MODBUSR(H, RegFlow+4, Float) * factor);</ReadState>
          </DeviceProperties>
        </Device>
      </Devices>
    </Module>
  </Template>
</Templates>
