-- -- adsl log processor - plots a spectrogram of 'xdsl debug bitloadinginfo' output of Thomson TG585 v8 modem. -- -- makePlots( "Latest" , "Spectrogram of Thomson TG585 v8 modem 'xdsl debug bitloadinginfo' output collected at least each time PCs turned on" ) -- -- -- Description: This script plots a spectrogram of 'xdsl debug bitloadinginfo' output of Thomson TG585 v8 modem. -- -- -- To run: I use lua5.1exe and type dofile("adslGDspecThomson.lua") -- -- See: www.lua.org and http://lua-gd.luaforge.net/ for lua downloads -- -- unpack gd and copy lua5.1.exe and lua5.1.dll into lua-gd-2.0.33r2 -- -- dofile("adslGDspecThomson.lua") -- -- Copyright: Doug Rice 2007,2011 -- -- lua-GD: http://lua-gd.luaforge.net/manual.html#license.luagd -- http://www.lua.org/license.html -- -- -- log files are read from .\adslLogs -- plots are put into .\png directory -- -- -------------------------------------------------- -- Sec 0.0 includes -- -------------------------------------------------- require "gd" -- -------------------------------------------------- -- Sec 1.0 Variables -- -------------------------------------------------- -- data file to be parsed, uncomment one dataFilesA = {} -- -------------------------------------------------- -- Sec 1.1 Parse data to find the limits -- -------------------------------------------------- gphA = {} im = nil timeStamp = "" dnStream = 0 upStream = 0 timeStamp = "" downStr = "" upStr = "" xLabel = 275 xOff = 10 xScale = 2 yOff = 40 yOff2 = 10 yScale = 1 yMax = 4550 yInc = 8 yIncAcc = 0 bitCounts = 0 im = gd.createTrueColor( (512+32) * xScale+xOff*2 + xLabel, yMax*yScale+yOff2*2) bg = im:colorAllocateAlpha(127, 127, 127 , 0) labelClr = im:colorAllocateAlpha(255, 255, 127 , 0) erase = im:colorAllocateAlpha(0, 0, 0, 0) bg = im:colorAllocateAlpha(250, 250, 250 , 0) labelClr = im:colorAllocateAlpha(32, 32, 0 , 0) -- first allocated color defines the background. white = im:colorAllocate(255, 255, 255) black = im:colorAllocate(0, 0, 0) red = im:colorAllocate(255, 0, 0) yellow = im:colorAllocate(255, 255, 0) green = im:colorAllocate(0, 255, 0) cyan = im:colorAllocate(0, 255, 255) blue = im:colorAllocate(0, 0, 255) mag = im:colorAllocate(255, 0, 255) gray = im:colorAllocateAlpha(200, 200, 200, 64) grey = im:colorAllocateAlpha(200, 200, 200, 10) gray17 = im:colorAllocateAlpha(255, 000, 255,120) gray16 = im:colorAllocateAlpha(255, 000, 255,110) gray15 = im:colorAllocateAlpha(255, 000, 255, 90) gray14 = im:colorAllocateAlpha(000, 255, 255,120) gray13 = im:colorAllocateAlpha(000, 255, 255, 90) gray12 = im:colorAllocateAlpha(000, 255, 255, 60) gray11 = im:colorAllocateAlpha(255, 255, 100, 60) gray10 = im:colorAllocateAlpha(255, 255, 100, 30) gray9 = im:colorAllocateAlpha(255, 200, 100, 30) gray8 = im:colorAllocateAlpha(255, 180, 100, 30) gray7 = im:colorAllocateAlpha(255, 140, 100, 30) gray6 = im:colorAllocateAlpha(255, 100, 100, 30) gray5 = im:colorAllocateAlpha(100, 255, 100, 45) gray4 = im:colorAllocateAlpha(100, 255, 100, 50) gray3 = im:colorAllocateAlpha(100, 255, 100, 55) gray2 = im:colorAllocateAlpha(100, 100, 255,100) gray1 = im:colorAllocateAlpha(100, 100, 255,110) gray0 = im:colorAllocateAlpha(100, 100, 255,120) -- modified 2011/07/10 gray17 = im:colorAllocateAlpha(255, 000, 255,120) gray16 = im:colorAllocateAlpha(255, 000, 255,110) gray15 = im:colorAllocateAlpha(255, 000, 255, 90) gray14 = im:colorAllocateAlpha(255, 000, 255,100) -- gray14 = im:colorAllocateAlpha(000, 255, 255,100) gray13 = im:colorAllocateAlpha(000, 255, 255, 90) gray12 = im:colorAllocateAlpha(000, 255, 255, 60) gray11 = im:colorAllocateAlpha(255, 255, 100, 60) gray10 = im:colorAllocateAlpha(255, 255, 100, 30) gray9 = im:colorAllocateAlpha(255, 200, 100, 30) gray8 = im:colorAllocateAlpha(255, 180, 100, 30) gray7 = im:colorAllocateAlpha(255, 140, 100, 30) gray6 = im:colorAllocateAlpha(255, 100, 100, 30) gray5 = im:colorAllocateAlpha(100, 255, 100, 40) gray4 = im:colorAllocateAlpha(100, 255, 100, 50) gray3 = im:colorAllocateAlpha(100, 255, 100, 60) gray2 = im:colorAllocateAlpha(100, 100, 100,50) gray1 = im:colorAllocateAlpha(100, 100, 100,70) gray0 = im:colorAllocateAlpha(100, 100, 100,90) -- modified 2011/07/11 gray17 = im:colorAllocateAlpha(255, 000, 255, 50) gray16 = im:colorAllocateAlpha(180, 000, 255, 50) gray15 = im:colorAllocateAlpha(255, 000, 224, 50) gray14 = im:colorAllocateAlpha(255, 000, 126, 50) gray13 = im:colorAllocateAlpha(255, 0, 0, 50) gray12 = im:colorAllocateAlpha(255, 56, 0, 50) gray11 = im:colorAllocateAlpha(255, 112, 0, 50) gray10 = im:colorAllocateAlpha(255, 182, 0, 50) gray9 = im:colorAllocateAlpha(255, 200, 0, 50) gray8 = im:colorAllocateAlpha(255, 245, 0, 50) gray7 = im:colorAllocateAlpha(194, 255, 000, 50) gray6 = im:colorAllocateAlpha(109, 255, 000, 50) gray5 = im:colorAllocateAlpha(100, 255, 100, 50) gray4 = im:colorAllocateAlpha(100, 255, 100, 50) gray3 = im:colorAllocateAlpha( 11, 255, 000, 50) gray2 = im:colorAllocateAlpha( 0, 255, 255, 70) gray1 = im:colorAllocateAlpha( 0, 205, 255, 90) gray0 = im:colorAllocateAlpha( 0, 128, 255, 90) --17/07/2011 gray17 = im:colorAllocateAlpha(255, 000, 255,100) gray16 = im:colorAllocateAlpha(255, 000, 255, 80) gray15 = im:colorAllocateAlpha(255, 000, 255, 60) gray14 = im:colorAllocateAlpha(000, 255, 255,100) gray13 = im:colorAllocateAlpha(000, 255, 255, 80) gray12 = im:colorAllocateAlpha(000, 255, 255, 60) gray11 = im:colorAllocateAlpha(255, 255, 100, 60) gray10 = im:colorAllocateAlpha(255, 255, 100, 30) gray9 = im:colorAllocateAlpha(255, 200, 100, 30) gray8 = im:colorAllocateAlpha(255, 180, 100, 30) gray7 = im:colorAllocateAlpha(255, 140, 100, 20) gray6 = im:colorAllocateAlpha(255, 100, 100, 10) gray5 = im:colorAllocateAlpha(100, 255, 100, 75) gray4 = im:colorAllocateAlpha(100, 255, 100, 50) gray3 = im:colorAllocateAlpha(100, 255, 100, 25) gray2 = im:colorAllocateAlpha(100, 100, 255, 80) gray1 = im:colorAllocateAlpha(100, 100, 255, 90) gray0 = im:colorAllocateAlpha(100, 100, 255,100) erase = im:colorAllocateAlpha(0, 0, 0, 0) coloursA = { gray0,gray1,gray2,gray3,gray4,gray5,gray6,gray7,gray8,gray9,gray10,gray11,gray12,gray13,gray14,gray15,gray16,gray17,gray17 } function clr6() -- modified 2011/07/11 for c1 = 1 , 18 , 3 do coloursA[ c1 + 0 ] = im:colorAllocateAlpha( 255 - c1 * 16,255 - c1 * 32,255 - 0, 10 ) coloursA[ c1 + 1 ] = im:colorAllocateAlpha( 255 - 0,255 - c1 * 16,255 - c1 * 32, 10 ) coloursA[ c1 + 2 ] = im:colorAllocateAlpha( 255 - c1 * 32,255 - 0,255 - c1 * 16, 10 ) end end -- clr6() function clr8() -- modified 2011/07/11 for c1 = 1 , 18 , 6 do coloursA[ c1 + 0 ] = im:colorAllocateAlpha( 255 - c1 * 16,255 - c1 * 16,255 - c1 * 16, 10 + c1*3 ) coloursA[ c1 + 1 ] = im:colorAllocateAlpha( 255 - c1 * 16,255 - c1 * 16,255 - c1 * 32, 10 + c1*3 ) coloursA[ c1 + 2 ] = im:colorAllocateAlpha( 255 - c1 * 32,255 - 0,255 - 0, 10 + c1*3 ) coloursA[ c1 + 3 ] = im:colorAllocateAlpha( 255 - c1 * 16,255 - c1 * 32,255 - 0, 10 + c1*3 ) coloursA[ c1 + 4 ] = im:colorAllocateAlpha( 255 - 0,255 - c1 * 16,255 - c1 * 32, 10 + c1*3 ) coloursA[ c1 + 5 ] = im:colorAllocateAlpha( 255 - c1 * 32,255 - 0,255 - c1 * 16, 10 + c1*3 ) end end -- clr8() function clr9() -- modified 2011/07/11 -- dark, bright, dark -- want blue, green, yellow,red, for c1 = 1 , 4 , 1 do -- r,g,b,aplpha coloursA[ c1 + 0 ] = im:colorAllocateAlpha( 0, 0,255,128- c1*24 ) coloursA[ c1 + 4 ] = im:colorAllocateAlpha( 0, 255,0, c1*24 ) coloursA[ c1 + 8 ] = im:colorAllocateAlpha( 255,255,0,128- c1*24 ) coloursA[ c1 + 12 ] = im:colorAllocateAlpha( 255, 0,0, c1*24 ) end end -- clr9() function clr10() -- modified 2011/07/11 -- dark, bright, dark -- want blue, green, yellow,red, for c1 = 1 , 4 , 1 do -- r,g,b,aplpha coloursA[ c1 + 0 ] = im:colorAllocateAlpha( 16, 128, 255,128- c1*24 ) coloursA[ c1 + 4 ] = im:colorAllocateAlpha( 16, 255, 128, c1*24 ) coloursA[ c1 + 8 ] = im:colorAllocateAlpha( 255, 200, 16,128- c1*24 ) -- coloursA[ c1 + 12 ] = im:colorAllocateAlpha( 255, 128, 16, c1*24 ) coloursA[ c1 + 12 ] = im:colorAllocateAlpha( 255, 16, 16, c1*24 ) end end -- clr10() function plotInit( title ) -- -- -- -- im = gd.createTrueColor( (256+32) * xScale+xOff*2 + xLabel , yMax*yScale+yOff2*2) erase = im:colorAllocateAlpha(0, 0, 0, 0) bg = im:colorAllocateAlpha(250, 250, 250 , 0) labelClr = im:colorAllocateAlpha(32, 32, 0 , 0) im:filledRectangle(0,0, (512+32) * xScale+xOff*2 + xLabel , yMax*yScale+yOff2*2 , bg ) im:string(gd.FONT_LARGE, 10, 5, title , labelClr) im:string(gd.FONT_LARGE, 10, 20, "Key:|512 bit buckets|Timestamp| Bit Load per Channel 0..15 bits: " , labelClr) xOffset = (512+32) * xScale+xOff*2 - 1*10*16 - 150 for x = 1 , 16 , 1 do im:filledRectangle( xOffset + x*10, 24, xOffset + x*10+8,34 , coloursA[ x ] ) end yIncAcc = 0 end function firstPass( dataFile ) -- -- Work through the log files. There are multiple polls of the Solwise 715 router. -- gphA=nil gphA={} gphA["fname"]=dataFile gphA["dn"]={} gphA["up"]={} marginDS = 0 marginUS = 0 fname = dataFile:match( "(%w*).") print( "filename: "..fname ) -- fp = io.open(".\\adslLogs\\" .. dataFile, "r+") fp = io.open( dataFile, "r+") if ( fp ) then else print("File Not Found: ".. dataFile .. "\n" ) return end instCnt = 0 trigger = false timeStamp = "" dnStream = 0 upStream = 0 -- ===ADSL======================= -- 2006-09-08 07:54:19 wantNext = false for line in fp:lines() do --[==[ ============================================ starting:Thu Jul 7 07:11:56 2011 ============================================ ]==] if line:match( "starting:" ) then timeStamp = line:match( "[^:]*:+(.+)$" ) end -- Bandwidth (Down/Up - kbit/s): 4544/444 if line:match( "Bandwidth " ) then downStr, upStr = line:match( "(%d*)\/(%d*)$" ) dnStream, upStream = line:match( "(%d*)\/(%d*)$" ) -- print( "speeds: ", downStr, upStr) end --[==[ Bearers generic info DS US Payload rate [kbps]: 9976 444 Attenuation [dB]: 40.0 24.5 Margins [dB]: 5.0 26.5 Output power [dBm]: 20.5 12.5 Number of bearers: 1 Bearer 0 DS US INP [dmt symbols]: 1.11 0.00 Delay [ms]: 8.00 1.13 R: 12 0 ]==] if line:match( "Margins " ) then marginDS,marginUS = line:match( "(%d*.%d*)%s*(%d*.%d*)$" ) -- print( "Margins: ", marginDS,marginUS ) end if line:match( "^ Tone : # Bits per tone" ) then foundTones = true end if line:match( "^{doug}" ) then foundTones = false end --[==[ ====== Tone : # Bits per tone 0 : 0 0 0 0 0 0 0 0 2 2 10 : 4 4 5 6 6 6 7 7 7 6 20 : 7 7 6 7 6 6 6 6 5 4 30 : 4 3 0 10 12 13 12 13 13 14 40 : 14 13 14 13 13 14 13 14 14 14 ]==] index = line:match("(%d*) :" ) if (index ) and foundTones then -- print( "------" ) -- found string of values now put into array -- first value is index offset index=-1 for val in line:gmatch( "%s*:*(%d+)" ) do if index == -1 then index = val*1 else bitCounts = bitCounts + val*1 --[==[ if ( bitCounts > 16 ) then print( bitCounts, line ) end ]==] gphA[ "dn" ][ index ] = val -- print( index , val , gphA[ "dn" ][ index ]) index = index + 1 end end -- if index*1 == 510 then -- trigger=true -- end end -- ====plot============================================= if line:match( "^====plot====+" ) then -- print("trigger") trigger=true end if trigger then -- print( trigger ,"plotting ====================================================") -- print( "Upstream Bit Load :" ) dir = "dn" plotPass( dataFile , instCnt ) instCnt = instCnt + 1 index = -1 downStr = "" upStr = "" bitCounts = 0 timeStamp = "" trigger = false end end fp:close() fname = dataFile:match( "([^.]*)") print( dataFile .. " \n" ) end function plotPass( dataFile,inst ) -- --------------- -- plot spectogram -- --------------- print( "a_"..fname.."_" .. inst .. ".png" ) im:line( -1*xScale+xOff , 0+yOff+yIncAcc , -1*xScale+xOff , 0+yOff+yInc+yIncAcc , labelClr ) plotPassFlag = true sumDnBits = 0 for x = 0 , 511 , 1 do if gphA[ "dn" ][x] then bits =gphA[ "dn" ][x] sumDnBits = sumDnBits + bits yMax = bits * yScale -- print( "...", x, yMax , yOff ) --print( x*xScale+xOff , 0+yOff+yIncAcc , x*xScale+1+xOff , 0+yOff+6+yIncAcc, coloursA[ 1+gphA[ "dn" ][x] ] ) im:filledRectangle( x*xScale+xOff , 0+yOff+yIncAcc , x*xScale+1+xOff , 0+yOff+6+yIncAcc, coloursA[ 1+gphA[ "dn" ][x] ] ) else -- print( "NIL gphA[ \"dn\" ][x] ",x, gphA[ "dn" ][x] ) plotPassFlag = false end end if plotPassFlag then im:string(gd.FONT_TINY, (513+ 4 )*xScale+xOff, 0+yOff+yIncAcc , " " .. string.format( '%4.1f %4.1f %4d %4d/%3d %s ',marginDS,marginUS,bitCounts,dnStream*1,upStream*1,timeStamp ) , labelClr) end yIncAcc = yIncAcc + yInc -- Plot Dn from left -- Plot Up from left -- (256+32) * xScale -- print( sumDnBits .. " , " .. sumUpBits ) -- fiddle factor to scale sum of bits -- 2.9473684210526315789473684210526 -- k = ( screen width / ( MaxBitRate / sum ) -- k = ( 448 / 152 ) * ( ( 32 ) * xScale / 448 ) k = ( ( 15 ) * xScale / 152 ) end function makePlots( opFileName, title ) gphA = nil gphA = {} yIncAcc = 0 plotInit( title ) yIncAcc = 0 cnt=1 while dataFilesA[cnt] do dataFile = dataFilesA[cnt] im:string(gd.FONT_TINY, 10, 0+yOff+yIncAcc , "File: " .. dataFile , labelClr) im:string(gd.FONT_TINY, (128 -8 )*xScale+xOff , 0+yOff+yIncAcc , "Downstream Bit Load" , labelClr) im:string(gd.FONT_TINY, (0 +257 +0 )*xScale+xOff , 0+yOff+yIncAcc , "Upstream Bit Load" , labelClr) im:string(gd.FONT_TINY, (32+257 +0 )*xScale+xOff , 0+yOff+yIncAcc , "Sum BitLoads Dn/Up, DownStream/Upstream, Timestamp" , labelClr) yIncAcc = yIncAcc + 10 firstPass( dataFile ) cnt = cnt + 1 end -- -- -- print( "lastyIncAcc:" .. yIncAcc ) im:png(".\\png\\a_spec.png") -- -- Trim the img -- -- gd.copy(dstImage, srcImage, dstX, dstY, srcX, srcY, w, h) -- dstImage:copy(srcImage, dstX, dstY, srcX, srcY, w, h) imTrim = gd.createTrueColor( (512+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 ) imTrim:filledRectangle(0,0, (512+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 , bg ) gd.copy(imTrim, im, 0,0 ,0,0, (512+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 ) imTrim:png(".\\png\\a_spec".. opFileName.."Thomson.png") imTrim = nil im:filledRectangle(0,0, (512+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 , bg ) end -- -- -- -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adslThomsonLog.txt" } makePlots( "Latest" , "Spectrogram of Thomson TG585 v8 modem 'xdsl debug bitloadinginfo' output collected at least each time PCs turned on" )