zoukankan      html  css  js  c++  java
  • openwrt19.07中获取光猫工作温度的lua脚本

    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.
    ")
      -- 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.
    ")
      -- 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,'	*',''))
    
    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,'
    ',''))
    
    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[ 	]*= (Number((d+))',buf)
       Current=re.findall(r'this.WorkElectric[ 	]*= (Number((d+))',buf)
       Temperature=re.findall(r'this.WorkTemperature[ 	]*= transTemperature((d+))',buf)
       SendPower=re.findall(r'this.SendPower[ 	]*= (Math.round(Math.log((Number((d+))',buf)
       RecvPower=re.findall(r'this.RecvPower[ 	]*= (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()# 最后输出一个空行
    

    转载注明来源: 本文链接 来自osnosn的博客.

  • 相关阅读:
    模块 hashlib模块
    设计模式
    类中双下方法
    工作小结 常见定制类
    python collections模块
    启动脚本
    anaconda镜像
    理解python的可变参数
    使用spark
    python 异常处理
  • 原文地址:https://www.cnblogs.com/osnosn/p/13871699.html
Copyright © 2011-2022 走看看