openwrt19.07中獲取光貓工作溫度的lua腳本
轉載注明來源: 本文鏈接 來自osnosn的博客,寫於 2020-10-25.
本文的 lua 腳本都是運行在 openwrt 的 shell 中
- openwrt 自身的 lan IP 改為非
192.168.1.x
網段。
因為光貓都是192.168.1.1
這個IP。
光貓 HG6201T
#!/usr/bin/lua
-- for "HG6201T" MODEM, 2020-10
-- --- command line argument, help ---
if(arg[1]==nil or string.len(arg[1])<1) then
local cmd=' '..arg[0]..' '
print('Usage:')
print(cmd..'origin')
print(cmd..'string')
print(cmd..'info')
print(cmd..'temp')
os.exit()
end
local show="none"
if(string.lower(string.sub(arg[1],1,1))=="t") then
show="temp"
elseif(string.lower(string.sub(arg[1],1,1))=="o") then
show="origin"
elseif(string.lower(string.sub(arg[1],1,1))=="s") then
show="str"
elseif(string.lower(string.sub(arg[1],1,1))=="i") then
show="info"
end
-- --- get MODEM Temperature ---
require("luci.sys")
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
-- If someone logs in, prevent being logged out.
-- Because one login, the whole network can access the MODEM.
-- First get the PON information directly.
local ponurl="http://192.168.1.1:8080/cgi-bin/pon_link_info.cgi?_=1234560123456"
local pon=luci.sys.httpget(ponurl)
if(string.find(pon,'window.location.href =')~=nil)
then
print("login and get.\n")
-- login
url="http://192.168.1.1:8080/cgi-bin/login.htm.cgi?username=telecomadmin&password=nE7jA%5m"
getcmd="/bin/wget --no-check-certificate -qO- '%s'" %url
a=luci.sys.exec(getcmd)
getcmd="/bin/wget --no-check-certificate -qO- '%s'" % ponurl
pon=luci.sys.exec(getcmd)
-- logout
url="http://192.168.1.1:8080/cgi-bin/exit.htm.cgi"
getcmd="/bin/wget --no-check-certificate -qO- '%s'" %url
a=luci.sys.exec(getcmd)
end
if(show=="origin") then
print(pon)
os.exit()
end
require("luci.jsonc")
ponTable=luci.jsonc.parse(pon)
if(show=="str") then
print(ponTable["PONINFO"]["poninfo_COUNstr"])
os.exit()
end
coun=string.split(ponTable["PONINFO"]["poninfo_COUNstr"],"&")
if(show=="temp") then
print('Temperature:',coun[4])
os.exit()
end
if(show=="info") then
print('Send(dBm):',coun[1])
print('Receive(dBm):',coun[2])
print('Voltage(V):',coun[3])
print('Current(mA):',coun[5])
print('Temperature:',coun[4])
os.exit()
end
光貓 TG1400ct
#!/usr/bin/lua
-- for "TG1400ct" MODEM, 2020-10
-- --- command line argument, help ---
if(arg[1]==nil or string.len(arg[1])<1) then
local cmd=' '..arg[0]..' '
print('Usage:')
print(cmd..'origin')
print(cmd..'string')
print(cmd..'info')
print(cmd..'temp')
os.exit()
end
local show="none"
if(string.lower(string.sub(arg[1],1,1))=="t") then
show="temp"
elseif(string.lower(string.sub(arg[1],1,1))=="o") then
show="origin"
elseif(string.lower(string.sub(arg[1],1,1))=="s") then
show="str"
elseif(string.lower(string.sub(arg[1],1,1))=="i") then
show="info"
end
-- --- get MODEM Temperature ---
require("luci.sys")
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
-- If someone logs in, prevent being logged out.
-- Because one login, the whole network can access the MODEM.
-- First get the PON information directly.
local ponurl="http://192.168.1.1/status_gpon.asp"
local pon=luci.sys.httpget(ponurl)
if(string.find(pon,'type="password"')~=nil)
then
print("login and get.\n")
-- login
-- post data need "&" at begin and end of the string
postdata='&psd=nE7jA%255m&username=telecomadmin'
url="http://192.168.1.1/boaform/admin/formLogin"
getcmd="/bin/wget --no-check-certificate --post-data='%s' -qO- '%s'" % {postdata, url}
a=luci.sys.exec(getcmd)
getcmd="/bin/wget --no-check-certificate -qO- '%s'" % ponurl
pon=luci.sys.exec(getcmd)
-- logout
url="http://192.168.1.1/boaform/admin/formLogout"
getcmd="/bin/wget --no-check-certificate -qO- '%s'" %url
a=luci.sys.exec(getcmd)
end
nn1=string.find(pon,'<table class="flat" border="1" cellpadding="1" cellspacing="1">')
nn2=string.find(pon,'<table class="flat" border="1" cellpadding="1" cellspacing="1">',nn1+2)
nn3=string.find(pon,'</table>',nn2+2)
pon_sector=string.sub(pon,nn2,nn3+7)
pon_sector=(string.gsub(pon_sector,'\t*',''))
if(show=="origin") then
print(pon_sector)
os.exit()
end
pon_sector=(string.gsub(pon_sector,'</td>','##'))
pon_sector=(string.gsub(pon_sector,'<.->',''))
pon_sector=(string.gsub(pon_sector,'\n',''))
if(show=="str") then
print(pon_sector)
os.exit()
end
coun=string.split(pon_sector,"##")
if(show=="temp") then
print('Temperature:',coun[6])
os.exit()
end
if(show=="info") then
print('Send(dBm):',coun[2])
print('Receive(dBm):',coun[4])
print('Voltage(V):',coun[8])
print('Current(mA):',coun[10])
print('Temperature:',coun[6])
os.exit()
end
光貓 TEWA-708G
- 這款光貓,用 openwrt 缺省的 wget 實在是無法登錄。
只好裝個 curl , 在路由中執行opkg install curl
,才搞定登錄。
#!/usr/bin/lua
-- for "TEWA-708G" MODEM, 2020-10
-- --- command line argument, help ---
if(arg[1]==nil or string.len(arg[1])<1) then
local cmd=' '..arg[0]..' '
print('Usage:')
print(cmd..'origin')
print(cmd..'string')
print(cmd..'info')
print(cmd..'temp')
os.exit()
end
local show="none"
if(string.lower(string.sub(arg[1],1,1))=="t") then
show="temp"
elseif(string.lower(string.sub(arg[1],1,1))=="o") then
show="origin"
elseif(string.lower(string.sub(arg[1],1,1))=="s") then
show="str"
elseif(string.lower(string.sub(arg[1],1,1))=="i") then
show="info"
end
-- --- get MODEM Temperature ---
require("luci.sys")
string.split = function(s, p)
local rt= {}
string.gsub(s, '[^'..p..']+', function(w) table.insert(rt, w) end )
return rt
end
-- If someone logs in, prevent being logged out.
-- Because one login, the whole network can access the MODEM.
-- First get the PON information directly.
local ponurl="http://192.168.1.1:8080/SW_Pon_Linkinfo.html"
local pon=luci.sys.httpget(ponurl)
if(string.find(pon,':8080/login.html')~=nil)
then
-- login
url="http://192.168.1.1:8080/login.cgi"
local post='&username=telecomadmin&password=nE7jA%255m&'
-- wget post always FAIL to login
--getcmd="wget --no-check-certificate --post-data='%s' -qO- '%s'" % { post, url }
getcmd="curl -s -d '%s' -X POST 'http://192.168.1.1:8080/login.cgi'" % {post,url}
a=luci.sys.exec(getcmd)
getcmd="wget --no-check-certificate -qO- '%s'" % ponurl
pon=luci.sys.exec(getcmd)
-- logout
url="http://192.168.1.1:8080/logout.cgi?sessionKey=1234567890"
getcmd="wget --no-check-certificate -qO- '%s'" %url
a=luci.sys.exec(getcmd)
end
pon=string.match(pon,"obj3Items = '[^']+';")
if (pon == nil or #pon <10) then
print("login failed.")
os.exit()
end
if(show=="origin") then
print(pon)
os.exit()
end
pon=string.sub(pon,14,-4)
if(show=="str") then
print(pon)
os.exit()
end
coun0=string.split(pon,"|")
coun2=string.split(coun0[1],"/")
coun1=string.split(coun0[2],"/")
if(show=="temp") then
print('Temperature:',coun2[1])
os.exit()
end
if(show=="info") then
print('Send(dBm):',coun2[4])
print('Receive(dBm):',coun2[5])
print('Voltage(V):',coun2[2])
print('Current(mA):',coun2[3])
print('Temperature:',coun2[1])
os.exit()
end
- 讀懂上面幾個程序,其他型號的光貓,也不難寫出來。
- openwrt中默認安裝的wget,POST請求兼容性不太好。如果老是失敗,可以考慮裝個curl解決,curl的兼容性很好。
- 如果用python3來寫,就更方便了。py3無論用
urllib.request
還是用requests
,POST兼容性非常好。基本不會出問題。
以下的是 python3 的程序
光貓 PT632 G_2
- 這款光貓,登錄用到了cookie。openwrt中的lua搞不定了。只好用debian中的python3了。
#!/usr/bin/python3
# -*- coding: utf-8 -*- #
# 從MODEM 光貓中,獲取PON溫度
import urllib.request
import http.cookiejar
import time
import sys, getopt
import os
import re
import math
def getPON():
cookie=http.cookiejar.CookieJar()
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cookie))
header={
'Origin': 'http://192.168.1.1',
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36',
'Accept':'*/*',
}
# only for 天翼光貓 "PT632 G_2"
if 1:
#print('Do login.')
host='http://192.168.1.1/'
req=urllib.request.Request(host, None,header)
try:
content=opener.open(req, timeout=5)
except urllib.error.URLError as e: # 404
if hasattr(e,'file'):
#print(e.errno,e.reason,e.strerror,e.args)
e.file.headers.add_header('Set-Cookie', 'UID=telecomadmin; path=/')
e.file.headers.add_header('Set-Cookie', 'PSW=nE7jA%5m; path=/')
e.file.headers.add_header('Set-Cookie', 'LoginTimes=1')
cookie.extract_cookies(e.file, req)
e.file.close()
else:
#print(e,e.reason)
print(e)
return None
host='http://192.168.1.1/cgi-bin/index2.asp'
postdata=b'Username=telecomadmin&Logoff=0&hLoginTimes=1&hLoginTimes_Zero=0&value_one=1&Password1=nE7jA%255m&Password2=nE7jA%255m&logintype=usr&Password=nE7jA%255m'
req=urllib.request.Request(host, postdata,header)
req.add_header('Referer', 'http://192.168.1.1/cgi-bin/index2.asp')
content=opener.open(req, timeout=5)
buf=content.read().decode('gbk')
content.close()
# h獲取PON溫度
host='http://192.168.1.1/cgi-bin/sta-network.asp'
req=urllib.request.Request(host, None,header)
content=opener.open(req, timeout=10)
# read()有時會卡住. 在上一行加入timeout,再觀察 2020-11-26
buf=content.read()
content.close()
# 退出登錄
host='http://192.168.1.1/cgi-bin/logout.cgi'
req=urllib.request.Request(host, None,header)
content=opener.open(req, timeout=5)
content.close()
opener.close()
buf=buf.decode('gbk')
Voltage=re.findall(r'this\.WorkVoltage[ \t]*= \(Number\((\d+)\)',buf)
Current=re.findall(r'this\.WorkElectric[ \t]*= \(Number\((\d+)\)',buf)
Temperature=re.findall(r'this\.WorkTemperature[ \t]*= transTemperature\((\d+)\)',buf)
SendPower=re.findall(r'this\.SendPower[ \t]*= \(Math.round\(Math.log\(\(Number\((\d+)\)',buf)
RecvPower=re.findall(r'this\.RecvPower[ \t]*= \(Math.round\(Math.log\(\(Number\((\d+)\)',buf)
if len(Voltage)>0:
Voltage=float(Voltage[0])/10
if len(Current)>0:
Current=float(Current[0])*2/1000
if len(Temperature)>0:
Temperature=float(Temperature[0])
if Temperature>=pow(2,15):
Temperature=-1*(pow(2,16)-Temperature)/256
else:
Temperature=Temperature/256
if len(SendPower)>0:
SendPower=math.log(float(SendPower[0])/10000)/math.log(10)*10
if len(RecvPower)>0:
RecvPower=math.log(float(RecvPower[0])/10000)/math.log(10)*10
#print('Voltage:',Voltage,'mV')
#print('Current:',Current,'mA')
#print('Temperature: %0.1f 度'% Temperature)
#print('SendPower: %0.2f dBm'% SendPower)
#print('RecvPower: %0.2f dBm'% RecvPower)
#print(Voltage.groups(),Current.groups())
# return [收發器溫度(度),工作電壓(mV),工作電流(mA),發送光功率(dBm),接收光功率(dBm)]
return [[Temperature,Voltage,Current,SendPower,RecvPower],[0,]]
def usage():
print(u'Usage:')
print(sys.argv[0]+' [-p|--print] [-h|--help]')
print(' -p, --print print stdout.')
print(' -h, --help print usage.')
return
if __name__=='__main__':
if(len(sys.argv)<2):
usage()
exit()
try:
opts, args = getopt.gnu_getopt(sys.argv[1:],'hp',['help','print',])
except getopt.GetoptError as e:
print(e)
usage()
exit(2)
report_print=False
for op,value in opts:
if op in ('-h','--help'):
usage()
exit()
elif op in('-p','--print'):
report_print=True
if not report_print:
usage()
exit()
s=getPON()
if s is None:
print('ERR: get modem stat.')
exit()
if report_print:
print(time.strftime('%F %T'))
print('{0:^8},{1:^9},{2:^8},{3:^10},{4:^10} '.format('收發器溫度(度)','工作電壓(mV)','工作電流(mA)','發送光功率(dBm)','接收光功率(dBm)'))
print('{0[0]:^14.1f} {0[1]:^13} {0[2]:^12} {0[3]:^15.1f} {0[4]:^15.1f} '.format(s[0]))
print()# 最后輸出一個空行