How can I setup a sensor to monitor the state of my iDirect modem (Rx SNR, Tx RefPower, TX State and selected beam)?


Article Comments

Hello Fredde,

Does the modem support protocols like e.g. SNMP? If so, you can import the MIB file of the manufacturer by using the MIB Importer Tool and create an SNMP Library Sensors in PRTG afterwards. This is also described in this article.

Best regards, Felix


Sep, 2017 - Permalink

Hi Felix,

Thanks but it doesn't support SNMP. I have actually written a custom telnet sensor for it already. I was following the knowledge base article about how to submit custom sensor which said I should create a thread about it here with a question as the subject line so that future users can easily find it.

Source Code

Full source code is available here, https://github.com/Fredde87/PRTG-iDirect-sensor

Here is the code for the main EXEXML file (lets call it iDirect.ps1),

Param (
        [string]$User = "",
        [string]$Password = "",
        [string]$RemoteHost = "",
        [string]$WarnLvlRxSNR = "7",
        [string]$ErrorLvlRxSNR = "5",
        [string]$WarnLvlTxPower = "-18",
        [string]$ErrorLvlTxPower = "-15"
 )
    
Function Get-Telnet
{   Param (
        [String[]]$Commands = @(""),
        [string]$Port = "23",
        [int]$WaitTime = 500
    )
    #Attach to the remote device, setup streaming requirements
    $Socket = New-Object System.Net.Sockets.TcpClient($RemoteHost, $Port)

    Write-Host "<?xml version="1.0" encoding="Windows-1252" ?><prtg>"

    If ($Socket)
    {   $Stream = $Socket.GetStream()
        $Writer = New-Object System.IO.StreamWriter($Stream)
        $Buffer = New-Object System.Byte[] 1024 
        $Encoding = New-Object System.Text.AsciiEncoding

        #Now start issuing the commands
        ForEach ($Command in $Commands)
        {   $Writer.WriteLine($Command) 
            $Writer.Flush()
            Start-Sleep -Milliseconds $WaitTime
        }
        #All commands issued, but since the last command is usually going to be
        #the longest let's wait a little longer for it to finish
        Start-Sleep -Milliseconds ($WaitTime * 4)
        $Result = ""
        #Save all the results
        While($Stream.DataAvailable) 
        {   $Read = $Stream.Read($Buffer, 0, 1024) 
            $Result += ($Encoding.GetString($Buffer, 0, $Read))
        }
        $Writer.Close()
        $Stream.Close()

        Return $Result
    }
    Else     
    {
       Write-Host "<Text> Error connecting to $Host</Text><Error>1</Error>"
       Write-Host '</prtg>'
         Exit 1
    }
}

#
$Process = Get-Telnet -Commands "$User","$Password","rx snr", "tx refpower", "txstate", "beamselector list", "quit"



$BeamNum = [regex]::Match($Process, '(.+) is currently selected').Groups[1].Value -replace "`n|`r"

$BeamName = [regex]::Match($Process, "$($BeamNum)\s+=\s+(.+)").Groups[1].Value -replace "`n|`r"


$TxStateString = [regex]::Match($Process, 'TX State\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($TxStateString -eq 'ON') {
    $TxState = 1
} elseif ($TxStateString -eq 'Warning') {
    $TxState = 2
} else {
    $TxState = 0
}

$DemodStatusString = [regex]::Match($Process, 'Demod Status\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"



If($DemodStatusString -eq "Locked") {
    $DemodStatus = 1
} else {
    $DemodStatus = 0
}

$NCRStatusString = [regex]::Match($Process, 'NCR Status\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($NCRStatusString -eq 'Locked') {
    $NCRStatus = 1
} else {
    $NCRStatus = 0
}

$TxMuteString = [regex]::Match($Process, 'Tx Mute\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($TxMuteString -eq 'False') {
    $TxMute = 0
} else {
    $TxMute = 1
}

$NetworkKeyString = [regex]::Match($Process, 'Network Key\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($NetworkKeyString -eq 'Valid') {
    $NetworkKey = 1
} else {
    $NetworkKey = 0
}


$TxCarrierInfoString = [regex]::Match($Process, 'Tx Carrier Info\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($TxCarrierInfoString -eq 'Valid') {
    $TxCarrierInfo = 1
} else {
    $TxCarrierInfo = 0
}


$TxAuthString = [regex]::Match($Process, 'Tx Authorization\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($TxAuthString -eq 'Valid') {
    $TxAuth = 1
} else {
    $TxAuth = 0
}

$OperatingModeString = [regex]::Match($Process, 'Operating Mode Mismatch\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"

If($OperatingModeString -eq 'True') {
    $OperatingMode = 1
} else {
    $OperatingMode = 0
}

$MissedBTPCount = [regex]::Match($Process, 'Missed BTP Count\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"
$MismatchedBTPCount = [regex]::Match($Process, 'Mismatched BTP Count\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"
$BTPSeqNum = [regex]::Match($Process, 'BTP Seq-Num UnAvailable\s+:\s+(.+)').Groups[1].Value -replace "`n|`r"
   
   
   


$RefPower = [regex]::Match($Process, 'Tx Reference Power\s+=\s+(.+) dbm').Groups[1].Value -replace "`n|`r"


$RxSNR = [regex]::Match($Process, 'SNR:\s+(.+)00').Groups[1].Value -replace "`n|`r"


Write-Host "
<result>
       <channel>Beam Number</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($BeamNum)</value>
"

If(Test-Path $Env:temp\beam.txt) {
    $OldBeam = Get-Content -Path $Env:temp\beam.txt
    If ("$OldBeam" -ne "$($BeamName) ($($BeamNum))")  {
        Write-Host "<NotifyChanged>1</NotifyChanged>
        "
    }
}
Write-Output "$($BeamName) ($($BeamNum))" | Out-File -Force -NoNewline $Env:temp\beam.txt
Write-Host "</result>"


Write-Host "
<result>
       <channel>RX SNR</channel>
       <unit>Custom</unit>
       <customUnit>dB</customUnit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>1</float>
       <value>$($RxSNR)</value>
       <LimitMinError>$($ErrorLvlRxSNR)</LimitMinError>
       <LimitMinWarning>$($WarnLvlRxSNR)</LimitMinWarning>
       <LimitWarningMsg>Rx SNR is low</LimitWarningMsg>
       <LimitErrorMsg>Rx SNR is extremely low</LimitErrorMsg>
       <LimitMode>1</LimitMode>
</result>"


Write-Host "
<result>
       <channel>TX RefPower</channel>
       <unit>Custom</unit>
       <customUnit>dB</customUnit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>1</float>
       <value>$($RefPower)</value>
       <LimitMaxError>$($ErrorLvlTxPower)</LimitMaxError>
       <LimitMaxWarning>$($WarnLvlTxPower)</LimitMaxWarning>
       <LimitWarningMsg>This is higher than normal...    </LimitWarningMsg>
       <LimitErrorMsg>Is there a reason for this? (bad weather etc)...    </LimitErrorMsg>
       <LimitMode>1</LimitMode>
   </result>"



Write-Host "
<result>
       <channel>Tx State</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($TxState)</value>
       <ValueLookup>idirect.preferon</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Demod Status</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($DemodStatus)</value>
       <ValueLookup>idirect.preferlocked</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>NCR Status</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($NCRStatus)</value>
       <ValueLookup>idirect.preferlocked</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Tx Mute</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($TxMute)</value>
       <ValueLookup>idirect.preferfalse</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Network Key</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($NetworkKey)</value>
       <ValueLookup>idirect.prefervalid</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Tx Carrier Info</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($TxCarrierInfo)</value>
       <ValueLookup>idirect.prefervalid</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Tx Authorization</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($TxAuth)</value>
       <ValueLookup>idirect.prefervalid</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Operating Mode Mismatch</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($OperatingMode)</value>
       <ValueLookup>idirect.preferfalse</ValueLookup>
   </result>"

Write-Host "
<result>
       <channel>Missed BTP Count</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($MissedBTPCount)</value>
   </result>"

Write-Host "
<result>
       <channel>Mismatched BTP Count</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($MismatchedBTPCount)</value>
   </result>"

Write-Host "
<result>
       <channel>BTP Seq-Num UnAvailable</channel>
       <unit>Custom</unit>
       <mode>Absolute</mode>
       <showChart>1</showChart>
       <showTable>1</showTable>
       <warning>0</warning>
       <float>0</float>
       <value>$($BTPSeqNum)</value>
   </result>
   "

If ($TxMute -eq 1) {
    Write-Host "<Text>Transmit is muted. Most likely both antennas are in blockage.</Text>"
    Write-Host "<Error>0</Error>"   
} elseif ("$OldBeam" -ne "$($BeamName) ($($BeamNum))") {
    Write-Host "<Text>just changed from beam: $($OldBeam) to $($BeamName) ($($BeamNum)), Rx SNR: $($RxSNR)dB, Tx Power: $($RefPower)dBm</Text>"
    Write-Host "<Error>0</Error>"       
} else {
    Write-Host "<Text>$($BeamName) ($($BeamNum)), Rx SNR: $($RxSNR)dB, Tx Power: $($RefPower)dBm</Text>"
    Write-Host "<Error>0</Error>"       
}

Write-Host '</prtg>'

exit 0

Create the Sensor

-RemoteHost <IP of iDirect Modem> -User <username, for iDirect modem> -Password <password, for iDirect modem>

If you set the username and password as the device's Linux username and password, then you would want the following string, -User %linuxuxer -Password %linuxpassword -RemoteHost %host

Create Lookup Files

For best effect you'll want my lookup files as well. Place these in the PRTG\lookups\custom folder. There are 5 files in total. The filename has to match what I put below for it to work,

Filename: idirect.preferfalse

<?xml version="1.0" encoding="UTF-8"?>
  <ValueLookup id="idirect.preferfalse" desiredValue="0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
    <Lookups>
      <SingleInt state="Error" value="1">
        True
      </SingleInt>
      <SingleInt state="Ok" value="0">
        False
      </SingleInt>
    </Lookups>
  </ValueLookup>

Filename: idirect.preferlocked

<?xml version="1.0" encoding="UTF-8"?>
  <ValueLookup id="idirect.preferlocked" desiredValue="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
    <Lookups>
      <SingleInt state="Ok" value="1">
        Locked
      </SingleInt>
      <SingleInt state="Error" value="0">
        Unlocked
      </SingleInt>
    </Lookups>
  </ValueLookup>

Filename: idirect.preferon

<?xml version="1.0" encoding="UTF-8"?>
  <ValueLookup id="idirect.preferon" desiredValue="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
    <Lookups>
      <SingleInt state="Ok" value="1">
        On
      </SingleInt>
      <SingleInt state="Warning" value="2">
        Warning
      </SingleInt>
      <SingleInt state="Error" value="0">
        Off
      </SingleInt>
    </Lookups>
  </ValueLookup>

Filename: idirect.prefertrue

<?xml version="1.0" encoding="UTF-8"?>
  <ValueLookup id="idirect.prefertrue" desiredValue="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
    <Lookups>
      <SingleInt state="Ok" value="1">
        True
      </SingleInt>
      <SingleInt state="Error" value="0">
        False
      </SingleInt>
    </Lookups>
  </ValueLookup>

Filename: idirect.prefervalid

<?xml version="1.0" encoding="UTF-8"?>
  <ValueLookup id="idirect.prefervalid" desiredValue="1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="PaeValueLookup.xsd">
    <Lookups>
      <SingleInt state="Ok" value="1">
        Valid
      </SingleInt>
      <SingleInt state="Error" value="0">
        Invalid
      </SingleInt>
    </Lookups>
  </ValueLookup>

Additional Notes

You need to load the lookup files via the
Setup | System Administration | Administrative Tools | Load Lookups page, or restart the PRTG Core Server Service.


Sep, 2017 - Permalink

Hi Fredde,

Thank you very much for sharing your script, we appreciate it a lot!

Best regards, Felix


Sep, 2017 - Permalink

Hi Freddy!

Are there any updates for this script? We are trying to get this work with someone from Peassler now for days.

Regards Jelle


Sep, 2020 - Permalink

Hi Jelle, What modem do you have?

iDirect have recently changed in their latest generation modems in the whole telnet syntax.

Since writing this module I have started a new job.

However we are actually deploying a iDirect modem and PRTG in a few months. So at the end of the year I might have a test bed which I can use to create a v2 of this module to support the newer iDirects.

Best Regards

Fredrik


Sep, 2020 - Permalink

Hi Frederik,

We use the iDirect X7 modems. Loaded with CentOS 6.8 and the SES rpm package. The iDirect scripts generate json errors. We created also some "version 2.0" but it is not yet working.


Sep, 2020 - Permalink

Hi Jelle,

Yeah the X7 probably won't work. I think thats the first modem where iDirect completely changed the command structure in telnet. All the commands have changed so I have to rewrite the sensor to work with the newer modems.

I'll try to do so at the end of this year or the start of next year when I have my test bed available. Unfortunately I dont have anything to test with before then.

Best Regards

Fredrik


Sep, 2020 - Permalink

Hi

I still wants to monitor old X1.X3 modem and not updated one. I already put files and everything as par desired location but I am not sure where to put username and password during create sensor..

I just put above string -User %linuxuxer -Password %linuxpassword -RemoteHost %host but it didnt work.. Please let me know where to put username and password...

thanks


Oct, 2020 - Permalink

Hello,

I'm afraid that I cannot give you more input oin that outdated version of the modem. Parsing these parameters sounds valid. If the old version does not work with it, it might be worth contacting the vendor to see if any other syntax is required.


Kind regards,
Felix Saure, Tech Support Team


Oct, 2020 - Permalink

Hi mukeshbhakar,

I think you are misreading the original post.

In the parameter field for the sensor, you can specify int here by using the following format,

-RemoteHost <IP of iDirect Modem> -User <username, for iDirect modem> -Password <password, for iDirect modem>

Obviously change anything within <> to your own IP/Username/Password etc. Here is an example,

-RemoteHost 192.168.0.1 -User admin -Password iDirect

If however you want to use PRTGs inbuilt credentials, then go the Device Settings for your iDirect modem and remove "Inherit" for "Credentials for Linux/Solaris/Mac OS (SSH/WBEM) Systems" and enter the username/password here.

If you do it this way, then the parameter for the sensor should look like this, -User %linuxuxer -Password %linuxpassword -RemoteHost %host


Oct, 2020 - Permalink