Examples - Wired M-Bus

Top  Previous  Next

//-----------------------------------------------------------------------------
//
// This example scans for devices on wired M-Bus and requests data from the found devices.
// By sending an SMS containing a filter, a new scan will be done.
//
//-----------------------------------------------------------------------------
INCLUDE rtcu.inc
// Uncomment math.inc to add math library support.
INCLUDE math.inc
 
//  Input variables that can be configured via the configuration dialog (These are global)
VAR_INPUT
 
END_VAR;
 
//  Output variables that can be configured via the configuration dialog (These are global)
VAR_OUTPUT
 
END_VAR;
 
//  These are the global variables of the program
VAR
  mb        : SYSHANDLE;
  // secondary address of found devices
  devices   : ARRAY [1..10] OF STRING;
  // Number of found devices
  dev_count : INT:=0;
 
  clock     : clockLinsecToTime;
  recInfo   : mbusRecordGetInfo;
END_VAR;
 
 
// Convert linsec to time string
FUNCTION GetTime:STRING;
VAR_INPUT
  linsec:DINT;
END_VAR;
 
  clock(linsec:=linsec);
  GetTime:=strFormat(format:="\1:\2:\3", v1:=clock.hour, v2:=clock.minute, v3:=clock.second);
END_FUNCTION;
 
// Convert linsec to date string
FUNCTION GetDate:STRING;
VAR_INPUT
  linsec:DINT;
END_VAR;
  clock(linsec:=linsec);
  GetDate:=strFormat(format:="\1-\2-\3", v1:=clock.year, v2:=clock.month, v3:=clock.day);
END_FUNCTION;
 
 
FUNCTION DumpRecords;
VAR
  rc    : INT;
  count : INT;
  i     : INT;
  str, unit : STRING;
  scale : FLOAT;
  type  : INT;
  d     : DINT;
END_VAR;
  count := mbusRecordCount(handle:=mb);
  DebugFmt(message:=" Records: \1", v1:=count);
 
 
  FOR i := 0 TO count DO
    recInfo(handle:=mb, index:=i);
    IF recInfo.ready THEN
        str := "  Record "+intToStr(v:=i)+", Type: " + intToStr(v:=recInfo.type);
 
        scale:=1.0;
        unit:="";
 
        str := str + ", VIF: "+sintToHex(v:=recInfo.VIF)+", VIFE: "
           + sintToHex(v:=recInfo.VIFE[1])+" "+sintToHex(v:=recInfo.VIFE[2]);
        DebugFmt(message:=str);
        DebugFmt(message:="   Addr: "+recInfo.address);
        DebugFmt(message:="   Dev: \1, Func: \2, Tar \4, Stor: "+dintToStr(v:=recInfo.storage),
                          v1:=recInfo.device, v2:=recInfo.func, v4:=recInfo.tariff);
 
        DebugFmt(message:="   Type: "+recInfo.text);
 
        type := mbusRecordGetType(handle:=mb, index:=i);
        DebugFmt(message:="   Data Type: \1", v1:=type);
 
        IF recInfo.VIF = 16#14 THEN
          // Volume [1e-2  m^3]
          unit := "m^3";
          scale := 0.01;
        END_IF;
 
 
        IF type = _MBUS_TYPE_INT32 THEN
          rc := mbusRecordGetInt(handle:=mb, index:=i, value:=d);
          DebugMsg(message:="   Value:     "+floatToStr(v:=FLOAT(d)*scale)+" "+unit);
        END_IF;
        IF type = _MBUS_TYPE_TIME THEN
          rc := mbusRecordGetLinsec(handle:=mb, index:=i, value:=d);
          IF recInfo.VIF = 16#6D THEN
              // time + date
              DebugMsg(message:="   Value:     "+GetDate(linsec:=d)+" "+GetTime(linsec:=d));
          ELSE
              // Just date
              DebugMsg(message:="   Value:     "+GetDate(linsec:=d));
          END_IF;
        END_IF;
 
    END_IF;
  END_FOR;
END_FUNCTION;
 
 
 
// mbusScanCallback
//
// Description:
//   Declaration of the function called when a slave is detected while scanning
//
// Input:
//   handle           - The handle to the M-bus connection.
//   primary          - The primary address (1..250)
//   secondary        - The secondary address
//
// Returns:
//   none
//
FUNCTION CALLBACK OnScan;
VAR_INPUT
  handle      : SYSHANDLE;
  secondary   : STRING;
  primary     : INT;
END_VAR;
VAR
  tmp:INT;
END_VAR;
  DebugFmt(message:="device found: \1: "+secondary, v1:=primary);
  IF secondary <> "" THEN
    IF dev_count < 10 THEN
        dev_count:=dev_count+1;
        devices[dev_count]:= secondary;
    END_IF;
  END_IF;
 
END_FUNCTION;
 
FUNCTION CALLBACK OnProgress;
VAR_INPUT
  handle      : SYSHANDLE;
  secondary   : STRING;
  primary     : INT;
END_VAR;
VAR
  tmp:INT;
END_VAR;
  DebugFmt(message:="scanning: \1: "+secondary, v1:=primary);
END_FUNCTION;
 
PROGRAM master;
// These are the local variables of the program block
VAR
  rc    : INT;
  i     : INT;
  count : INT := 0;
  sms   : gsmIncomingSMS;
  info  : mbusRecordSlaveInfo;
END_VAR;
// The next code will only be executed once after the program starts
  rc := mbusOpen(handle:=mb, type:=1, baud:=2400);
  DebugFmt(message:="mbusOpen(): \1", v1:=rc);
 
  dev_count:=0;
  rc := mbusScan(handle:=mb, cb_found:=@OnScan, cb_progress:=@OnProgress, smode:=2, mask:="FFFFFFFFFFFFFFFF");
  DebugFmt(message:="mbusScan(): \1", v1:=rc);
 
 
BEGIN
// Code from this point until END will be executed repeatedly
  sms();
  IF sms.status > 0 THEN
     // Use SMS message as filter for scan for secondary addresses
    DebugFmt(message:="Scan: "+sms.message);
    dev_count:=0;
    rc := mbusScan(handle:=mb, cb_found:=@OnScan, cb_progress:=@OnProgress, smode:=2, mask:=sms.message);
    DebugFmt(message:="mbusScan(): \1", v1:=rc);
     
    FOR i := 1 TO dev_count DO
        DebugFmt(message:="Device \1: "+devices[i], v1:=i);
    END_FOR;
  END_IF;
 
  IF count > 10 THEN
 
    FOR i:= 1 TO dev_count DO
        // Request data from device
        rc := mbusDataRequest(
                              handle   := mb,
                              sec_addr := devices[i]
                             );
        DebugFmt(message := "  mbusDataRequest("+devices[i]+")=\1", v1 := rc);
 
        info(handle:=mb);        
        IF info.ready THEN
          DebugFmt(message:="Info for \4:", v4:=info.id);
          DebugFmt(message:=" Enc:  \1", v1:=info.enc_state);
          DebugFmt(message:=" Man:  "+info.manufacturer);
          DebugFmt(message:=" Ver:  \1", v1:=info.version);
          DebugFmt(message:=" Med:  \1", v1:=info.medium);
          DebugFmt(message:=" AN :  \1", v1:=info.accessnumber);
          DebugFmt(message:=" Sta:  \1", v1:=info.status);
          DebugFmt(message:=" Addr: "+info.sec_addr);
          DebugFmt(message:=" Sig:  \1", v1:=info.signal);
 
          DumpRecords();
        ELSE
          DebugMsg(message:="no response");
      END_IF;
    END_FOR;
    count := 0;
  ELSE
    count := count + 1;
    Sleep(delay:=1000);
  END_IF;
 
END;
 
END_PROGRAM;