I wanted to share my appdaemon script for getting data from TP-Link Archer VR600 modem using telnet.
This device has a snmp built in but there is no useful information on the snmp agent. It is also not possible to extend the snmp agent. I couldn’t find any other way other than telnet querying the modem to get dsl line values.
If anyone can improve upon it, feel free, I am not really a good programmer.
import appdaemon.plugins.hass.hassapi as hass
import sys, datetime, time, telnetlib
class TelnetDSL(hass.Hass):
def initialize(self):
runtime = datetime.time(0, 0, 0)
self.run_minutely(self.getdata, runtime)
def getdata(self, kwargs):
HOST = "192.168.0.1"
password = "pass"
port = 23
try:
self.log('Opening Telnet Connection to Modem.', level = "INFO")
with telnetlib.Telnet(HOST,port,timeout=10) as tn:
tn.read_until(b'password:', 10)
self.log('Sending password to Modem.', level = "INFO")
tn.write((password + '\r\n').encode('ascii'))
time.sleep(1)
tn.read_until(b'(conf)#', 10)
self.log('Querying for DSL Line Values!', level = "INFO")
tn.write(('adsl show info' + '\r\n').encode('ascii'))
time.sleep(1)
try:
rawdata = tn.read_until(b'cmd:SUCC', 10).decode('utf-8').replace('\r','').splitlines()
rem_items = {'{','}','','cmd:SUCC','adsl show info'}
newlist = [ele for ele in rawdata if ele not in rem_items]
alldict = dict([x.split('=') for x in newlist])
keys = ['status','upstreamCurrRate','downstreamCurrRate','upstreamMaxRate','downstreamMaxRate','upstreamNoiseMargin','downstreamNoiseMargin','upstreamAttenuation','downstreamAttenuation']
datadict = {x:alldict[x] for x in keys}
datadict['upstreamNoiseMargin'] = float(datadict['upstreamNoiseMargin'])/10
datadict['downstreamNoiseMargin'] = float(datadict['downstreamNoiseMargin'])/10
datadict['upstreamAttenuation'] = float(datadict['upstreamAttenuation'])/10
datadict['downstreamAttenuation'] = float(datadict['downstreamAttenuation'])/10
except:
self.log("Telnet data cannot be proccessed!!!", level = "ERROR")
self.set_unv()
return
try:
self.set_state("sensor.modem_status", state=datadict['status'], attributes={"friendly_name":"Modem Status", "icon":"mdi:circle-outline"})
self.set_state("sensor.modem_current_rate_upload", state=datadict['upstreamCurrRate'], attributes={"friendly_name":"Modem Current Rate Upload", "icon":"mdi:mdi:phone-outgoing", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_current_rate_download", state=datadict['downstreamCurrRate'], attributes={"friendly_name":"Modem Current Rate Download", "icon":"mdi:phone-incoming", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_max_rate_upload", state=datadict['upstreamMaxRate'], attributes={"friendly_name":"Modem Max Rate Upload", "icon":"mdi:phone-outgoing-outline", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_max_rate_download", state=datadict['downstreamMaxRate'], attributes={"friendly_name":"Modem MAX Rate Download", "icon":"mdi:mdi:phone-incoming-outline", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_snr_margin_upload", state=datadict['upstreamNoiseMargin'], attributes={"friendly_name":"Modem SNR Upload", "icon":"mdi:phone-missed-outline", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_snr_margin_download", state=datadict['downstreamNoiseMargin'], attributes={"friendly_name":"Modem SNR Download", "icon":"mdi:phone-missed-outline", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_line_attenuation_upload", state=datadict['upstreamAttenuation'], attributes={"friendly_name":"Modem Line Attenuation Upload", "icon":"mdi:phone-plus", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_line_attenuation_download", state=datadict['downstreamAttenuation'], attributes={"friendly_name":"Modem Line Attenuation Download", "icon":"mdi:phone-minus", "device_class":"signal_strength","unit_of_measurement":"dB"})
except:
self.log("Telnet sensors cannot be updated", level = "ERROR")
self.set_unv()
self.log(datadict, level = "INFO")
except EOFError:
self.log("Telnet: Unexpected response from Modem", level = "ERROR")
self.set_unv()
except ConnectionRefusedError:
self.log("Telnet connection refused by Modem. Telnet enabled?", level = "ERROR")
self.set_unv()
except:
self.log("Telnet Error", level = "ERROR")
self.set_unv()
def set_unv(self):
st = 'Unavailable'
self.set_state("sensor.modem_status", state=st, attributes={"friendly_name":"Modem Status", "icon":"mdi:circle-outline"})
self.set_state("sensor.modem_current_rate_upload", state=st, attributes={"friendly_name":"Modem Current Rate Upload", "icon":"mdi:mdi:phone-outgoing", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_current_rate_download", state=st, attributes={"friendly_name":"Modem Current Rate Download", "icon":"mdi:phone-incoming", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_max_rate_upload", state=st, attributes={"friendly_name":"Modem Max Rate Upload", "icon":"mdi:phone-outgoing-outline", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_max_rate_download", state=st, attributes={"friendly_name":"Modem MAX Rate Download", "icon":"mdi:mdi:phone-incoming-outline", "unit_of_measurement":"kbps"})
self.set_state("sensor.modem_snr_margin_upload", state=st, attributes={"friendly_name":"Modem SNR Upload", "icon":"mdi:phone-missed-outline", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_snr_margin_download", state=st, attributes={"friendly_name":"Modem SNR Download", "icon":"mdi:phone-missed-outline", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_line_attenuation_upload", state=st, attributes={"friendly_name":"Modem Line Attenuation Upload", "icon":"mdi:phone-plus", "device_class":"signal_strength","unit_of_measurement":"dB"})
self.set_state("sensor.modem_line_attenuation_download", state=st, attributes={"friendly_name":"Modem Line Attenuation Download", "icon":"mdi:phone-minus", "device_class":"signal_strength","unit_of_measurement":"dB"})