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