Skip to content

Instantly share code, notes, and snippets.

@arrjay
Created July 24, 2023 02:58
Show Gist options
  • Save arrjay/19db3a4acf206de0d3a87662c9374235 to your computer and use it in GitHub Desktop.
Save arrjay/19db3a4acf206de0d3a87662c9374235 to your computer and use it in GitHub Desktop.
expect script to munge Zyxel poe status from telnet into a json blob
#!/usr/bin/env expect
#exp_internal 1
#log_user 1
# hi! we're hand-crafting JSON, fuckit
puts "{"
log_user 0
set timeout 5
set host [lindex $argv 0]
set port [lindex $argv 1]
set user [lindex $argv 2]
set pass [lindex $argv 3]
spawn telnet $host $port
expect "Username:"
send "$user\r"
expect "Password:"
send "$pass\r"
expect "#"
send "show power inline consumption\r"
## UNITS(?) ##
# example output for this section:
#Unit Power Status Nominal Allocated Consumed Available
# Power Power Power Power
#---- ----- ------ -------- --------------- -------- ---------
#1 On Normal 170Watts 6Watts ( 3%) 6Watts 163Watts
# handle switch units
expect "Unit*"
# grab the labels for our objects
set header [concat {*}[split $expect_out(0,string) " "]]
#puts $header
# match the separator line
# "Unit..er"
expect -re {\r\n----.*--\r\n}
# match integers...
puts "\"Units\": \["
set unit 0
expect -re {(\d+)} {
if {$unit > 0} {
puts ",\n"
}
set unit [expr $unit + 1]
# grab the index...
set instance [lindex $expect_out(buffer) end]
#puts $instance
# now find the *end* of that line and break it up
expect -re {\r\n}
# we cheat here and remove the "percent power used" by dropping the element (it didn't really get a header either)
set attrs [lreplace [concat {*}[split [string map { ( {} ) {} "\r\n" {} } $expect_out(buffer)] \S+]] 4 4]
set object [lmap k $header v [linsert $attrs 0 $instance] {list $k $v}]
#puts $object
# now print that
puts -nonewline "\{"
set attrct 0
foreach attr $object {
if {$attrct > 0} {
puts -nonewline ", "
}
set key [lindex $attr 0]
set value [lindex $attr 1]
set attrct [expr $attrct + 1]
# print key
puts -nonewline "\""
puts -nonewline $key
puts -nonewline "\": "
# print/modify value
# we cheated on unit and "Watts" values
if {$key == "Unit"} {
set matchWatts 0
} else {
set matchWatts [string first "Watts" $value]
}
if {$matchWatts >= 0} {
set value [string map { Watts {} } $value]
} else {
puts -nonewline "\""
}
puts -nonewline $value
if {$matchWatts < 0} {
puts -nonewline "\""
}
}
puts -nonewline "\}"
}
puts "\n\],"
## PORTS ##
# example output for this section:
#Port Power Limit (Admin) (mW) Power (mW) Voltage (mV) Current (mA)
#---- ------------------------ ---------- ------------ ------------
#1 0 (0 ) 0 0 0
#2 0 (0 ) 0 0 0
#3 0 (0 ) 0 0 0
#4 0 (0 ) 0 0 0
#5 0 (0 ) 0 0 0
#6 31200 (31200) 1800 53686 34
expect "\r\n" # advance the line
expect "Port*\r\n----*--\r\n" # match header and next line
# grab the labels for our objects
set header [lreplace [concat {*}[split [string map { "Limit" {} ( {} ) {} "mW" {} "mV" {} "mA" {} } [lindex [split $expect_out(0,string) "\r\n"] 0]]]] 1 1 "Limit"]
#puts $header
puts "\"Ports\": \["
# we get to handle pagination *and* output, gaaah
set port 0
expect {
# port statistic
-re {(\d)+} {
if {$port > 0} {
puts ","
}
set instance [lindex $expect_out(buffer) end]
expect -re {\r\n}
# puts $expect_out(buffer)
set attrs [concat {*}[split [string map { ( {} ) {} "\r\n" {} } $expect_out(buffer)] " "]]
set object [lmap k $header v [linsert $attrs 0 $instance] {list $k $v}]
#puts $object
set attrct 0
puts -nonewline "\{"
foreach attr $object {
# handle multiple attributes
if {$attrct > 0} {
puts -nonewline ", "
}
# key
puts -nonewline "\""
puts -nonewline [lindex $attr 0]
puts -nonewline "\": "
puts -nonewline [lindex $attr 1]
set attrct [expr $attrct + 1]
}
puts -nonewline "\}"
set port [expr $port + 1]
exp_continue
}
# handle paging
-- "--More--" {
send " "
expect "2K" # "\r\n\u001b\[A\u001b\[2K" seems to be the sequence used to rewrite lines after prompt
exp_continue
}
# handle prompt (we're done)
-- "#" {
set success 1
}
}
puts "]"
puts "}"
#interact
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment