-- -- adsl log processor - plots a spectrogram of ADSL SHOW CHANNEL output of Solwise EL715 ADSL modem. -- -- Description: This script plots a spectrogram of the ADSL SHOW CHANNEL output. -- -- To run: I use lua5.1exe and type dofile("adslGDspec.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("adslGDspec.lua") -- -- Copyright: Doug Rice 2007 -- 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 = { "adsl.log" } -- -------------------------------------------------- -- Sec 1.1 Parse data to find the limits -- -------------------------------------------------- gphA = {} im = nil timeStamp = "" dnStream = 0 upStream = 0 timeStamp ="" xLabel = 275 xOff = 10 xScale = 3 yOff = 40 yOff2 = 10 yScale = 1 yMax = 4550 yInc = 8 yIncAcc = 0 im = gd.createTrueColor( (256+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) --[==[ 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, 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, 80) gray1 = im:colorAllocateAlpha(100, 100, 255, 90) gray0 = im:colorAllocateAlpha(100, 100, 255,100) ]==] erase = im:colorAllocateAlpha(0, 0, 0, 0) -- coloursA = { black,red,yellow,green, cyan,blue,mag,white,black,red,yellow,green, cyan,blue,mag,white } coloursA = { gray0,gray1,gray2,gray3,gray4,gray5,gray6,gray7,gray8,gray9,gray10,gray11,gray12,gray13,gray14,gray15,gray16,gray17 } im:string(gd.FONT_LARGE, 10, 5, "Spectrogram of ADSL SHOW CHANNEL Bit Loads collected at least each time PCs turned on" , labelClr) 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, (256+32) * xScale+xOff*2, yMax*yScale+yOff2*2 , erase ) im:filledRectangle(0,0, (256+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:|Downstream |Upstream |Timestamp| Bit Load per Channel 0..15 bits: " , labelClr) xOffset = (256+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"]={} fname = dataFile:match( "(%w*).") print( "filename: "..fname ) fp = io.open(".\\adslLogs\\" .. 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 p1 = line:match( "(ipoa list transports)" ) if p1 then -- print( p1 ) end if line:match( "UTC" ) then timeStamp = line end -- ===ADSL======================= -- 2006-09-08 07:54:19 if wantNext then timeStamp = line wantNext = false end if line:match( "===ADSL=======================" ) then wantNext = true end if line:match( "Downstream Bit Rate :" ) then dnStream = line:match( "Downstream Bit Rate : (%d*)" ) end if line:match( "Upstream Bit Rate :" ) then upStream = line:match( "Upstream Bit Rate : (%d*)" ) end if line:match( "Upstream Bit Load :" ) then -- print( "Upstream Bit Load :" ) dir = "up" trigger = true end if line:match( "Downstream Bit Load :" ) then -- print( "Downstream Bit Load :" ) dir = "dn" instCnt = instCnt+1 end if line:match( "-->" ) then -- print( "Upstream Bit Load :" ) dir = "up" if ( trigger == true ) then plotPass( dataFile , instCnt ) trigger = false end end -- print( line ) -- parse lines like -- ch[ 64] = 0 ch[ 65] = 9 ch[ 66] = 10 ch[ 67] = 10 -- i1,l1 = line:match("^ch%[%s*(%d*)%] =%s*(%d*)" ) -- i1,l1,i2,l2,i3,l3,i4,l4 = line:match( "^ch%[%s*(%d*)%] =%s*(%d*)ch%[%s*(%d*)%] =%s*(%d*)ch%[%s*(%d*)%] =%s*(%d*)ch%[%s*(%d*)%] =%s*(%d*)" ) -- print( line:match("(ch%[%s*%d*%] =%s*%d*)") ) -- i1,l1 = line:match("ch%[%s*(%d*)%] =%s*(%d*)" ) -- if i1 then print( i1 , l1 ) end for i1,l1 in line:gmatch( "ch%[%s*(%d*)%] =%s*(%d*)" ) do -- print( i1, l1 ) gphA[ dir ][i1*1] = l1*1 -- print( i1, l1, gphA[ dir ][i1*1] ) 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 ) for x = 0 , 255 , 1 do end sumDnBits = 0 for x = 0 , 255 , 1 do bits =gphA[ "dn" ][x] sumDnBits = sumDnBits + bits yMax = bits * yScale -- print( "...", x, yMax , yOff ) im:filledRectangle( x*xScale+xOff , 0+yOff+yIncAcc , x*xScale+1+xOff , 0+yOff+6+yIncAcc, coloursA[ 1+gphA[ "dn" ][x] ] ) end im:line( 256*xScale+xOff , 0+yOff+yIncAcc , 256*xScale+xOff , 0+yOff+yInc+yIncAcc , labelClr ) sumUpBits = 0 for x = 0 , 31 , 1 do bits =gphA[ "up" ][x] sumUpBits = sumUpBits + bits yMax = bits * yScale -- print( "...", x, yMax , yOff ) im:filledRectangle( (x+257)*xScale+xOff , 0+yOff+yIncAcc , (x+257)*xScale+1+xOff , 0+yOff+6+yIncAcc, coloursA[ 1+gphA[ "up" ][x] ] ) end -- plot sumDnBits and sumUpBits im:line( (257+32)*xScale+xOff , 0+yOff+yIncAcc , (257+32)*xScale+xOff , 0+yOff+yInc+yIncAcc , labelClr ) im:string(gd.FONT_TINY, (257+32)*xScale+xOff, 0+yOff+yIncAcc , " " .. string.format( '%4d/%3d %4d/%3d %s ' ,sumDnBits,sumUpBits,dnStream,upStream,timeStamp ) , labelClr) 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 ) --[==[ im:line( xOff , 0+yOff+yIncAcc , sumDnBits * k + xOff , 0+yOff+yIncAcc, grey ) im:line( xOff + (256+2) * xScale, 0+yOff+yIncAcc , sumUpBits * k + xOff + (256+2) * xScale, 0+yOff+yIncAcc, grey ) yIncAcc = yIncAcc + 2 ]==] 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( (256+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 ) imTrim:filledRectangle(0,0, (256+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 , bg ) gd.copy(imTrim, im, 0,0 ,0,0, (256+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 ) imTrim:png(".\\png\\a_spec".. opFileName..".png") imTrim = nil im:filledRectangle(0,0, (256+32) * xScale+xOff*2 + xLabel, 0+yOff+yIncAcc+8 , bg ) end --[==[ -- -- -- -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl.log" } makePlots( "Latest2" , "Spectrogram of ADSL SHOW CHANNELs collected at least each time PCs turned on" ) ]==] -- -- -- --[==[ -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_support.log" } makePlots( "support" ,"Spectrogram: Plugged into F1 Solwise 2 wire micro filter " ) -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl080111.log" } makePlots( "080111" ,"Spectrogram: Effects of Extension cable " ) -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f1_c1.log", "adsl_f1_c2.log", "adsl_f1_c3.log" } makePlots( "f1" ," F1 Solwise 2 wire micro filter " ) -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f1_c1.log", "adsl_f1_c2.log", "adsl_f1_c3.log" } makePlots( "f1" ," F1 Solwise 2 wire micro filter " ) -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f2_c1.log" } makePlots( "f2" ," F2 Solwise 2 wire micro filter ") -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f3_c1.log", "adsl_f3_c2.log", "adsl_f3_c3.log", "adsl_f3_c4.log", "adsl_f3_c5.log", "adsl_f3_c6.log", "adsl_f3_c7.log", "adsl_f3_c8.log", "adsl_f3_c9.log", "adsl_f3_c10.log", "adsl_f3_c11.log", "adsl_f3_c12.log" } makePlots( "f3" ," F3 Solwise 2 wire micro filter ") -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f4_c1.log", "adsl_f4_c2.log", "adsl_f4_c3.log", "adsl_f4_c4.log", "adsl_f4_c5.log" } makePlots( "f4" ," F4 Solwise 2 wire micro filter ") -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f5_c1.log", "adsl_f5_c2.log", "adsl_f5_c3.log", "adsl_f5_c4.log", "adsl_f5_c5.log", "adsl_f5_c6.log", "adsl_f5_c7.log", "adsl_f5_c8.log" } makePlots( "f5" ," F5 - Elmers - PhonaPart ADSL/Broadband filter LJ5109/BP") -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl_f2f4_c1.log", "adsl_f2f4_c2.log", "adsl_f2f4_c3.log", "adsl_f2f4_c4.log", "adsl_f2f4_c5.log", "adsl_f2f4_c6.log", "adsl_f2f4_c7.log", "adsl_f2f4_c8.log", "adsl_f2f4_c9.log" } makePlots( "f2f4" , " F2 & F4 Solwise 2 wire micro filters " ) ]==] -- data file to be parsed, uncomment one --[==[ dataFilesA = nil dataFilesA = { "adsl080110.log", "adsl080111.log", "adsl080115.log", "adsl080130.log", "adsl080208.log", "adsl080221.log", "adsl080325.log", "adsl080419.log", "adsl080429.log", "adsl080504.log", "adsl080514.log", -- "adsl080517.log", "adsl080709.log" } makePlots( "080709" , "Spectrogram of ADSL SHOW CHANNELs collected at least each time PCs turned on" ) ]==] -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adsl.log" } makePlots( "Latest" , "Spectrogram of ADSL SHOW CHANNELs collected at least each time PCs turned on" ) --[==[ -- data file to be parsed, uncomment one dataFilesA = nil dataFilesA = { "adslLgCh.txt", "adslLogCh.txt", "adslLog060910.txt", "adsl_070909.log", "adsl_f1_c1.log", "adsl_f1_c2.log", "adsl_f1_c3.log", "adsl_f2_c1.log", "adsl_f3_c1.log", "adsl_f3_c2.log", "adsl_f3_c3.log", "adsl_f3_c4.log", "adsl_f3_c5.log", "adsl_f3_c6.log", "adsl_f3_c7.log", "adsl_f3_c8.log", "adsl_f3_c9.log", "adsl_f3_c10.log", "adsl_f3_c11.log", "adsl_f3_c12.log", "adsl_f4_c1.log", "adsl_f4_c2.log", "adsl_f4_c3.log", "adsl_f4_c4.log", "adsl_f4_c5.log", "adsl_f2f4_c1.log", "adsl_f2f4_c2.log", "adsl_f2f4_c3.log", "adsl_f2f4_c4.log", "adsl_f2f4_c5.log", "adsl_f2f4_c6.log", "adsl_f2f4_c7.log", "adsl_f2f4_c8.log", "adsl_f2f4_c9.log", "adsl_f5_c1.log", "adsl_f5_c2.log", "adsl_f5_c3.log", "adsl_f5_c4.log", "adsl_f5_c5.log", "adsl_f5_c6.log", "adsl_f5_c7.log", "adsl_f5_c8.log" -- "adsl.log" } makePlots( "All" , "Spectrogram of ADSL SHOW CHANNELs collected at least each time PCs turned on" ) ]==]