Posted to tcl by crshults at Sun Nov 10 05:17:25 GMT 2013view pretty

# Specification for this device says it returns a 1-byte status and the bits
# are to be interpreted as follows:
set status {
    {"Heater On"          "Heater Off"         }
    {"Primary Motor On"   "Primary Motor Off"  }
    {"Secondary Motor On" "Secondary motor Off"}
    {"Object In Path"     "Object Not In Path" }
    {"Light On"           "Light Off"          }
    {"Reserved"           "Reserved"           }
    {"Fuel Low"           "Fuel Not Low"       }
    {"Reserved"           "Reserved"           }
}
# My goal is to read the status and print only what changed, so if bit 0 flips
# from 0 to 1, the output will be: {Heater Off}

set current_status "Unknown"

# This is just a dummy to give us a random status byte
proc get_device_response {} {
    return [subst "\\x[format %X [expr {int(rand()*256)}]]"]
}

# I feel like this proc is way too ugly
proc device_response_handling {} {
    set response [get_device_response]
    if {$response == $::current_status} return
    if {$::current_status != "Unknown"} {
        binary scan $::current_status B* current_status_bits
    } else {
        set current_status_bits xxxxxxxx
    }
    set ::current_status $response
    binary scan $::current_status B* new_status_bits
    set actual_changes_occurred no
    set result [lmap status_text $::status old [split $current_status_bits ""] new [split $new_status_bits ""] {
        if {[lindex $status_text $new] == "Reserved"} {
            continue
        } elseif {$old == $new} {
            continue
        } else {
            set actual_changes_occurred yes
            lindex $status_text $new
        }
    }]
    if {$actual_changes_occurred} {
        puts "New Device Status: $result"
    }
}

# repeated calls of [device_response_handling] should suffice to demonstrate