|
//-----------------------------------------------------------------------------
//
// 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;
|