Patch title: Release 94 bulk changes
Abstract:
File: /pliant/graphic/color/spectro.pli
Key:
    Removed line
    Added line
abstract
  [This program is handling the Minolta spectocolorimeter]

module "/pliant/language/unsafe.pli"
module "/pliant/language/context.pli"
module "/pliant/language/stream.pli"
module "/pliant/language/stream/serial.pli"
if os_api="linux"
  module "/pliant/admin/execute.pli"
  module "/pliant/linux/kernel/module.pli"
  module "/pliant/linux/kernel/device.pli"
module "spectrum.pli"

constant trace false
constant model "spectrolino" # "minolta"

gvar Stream spectro
gvar DateTime spectro_datetime
gvar Int spectro_counter := 0

function spectro_init
  if os_api="linux"
    execute "modprobe serial" quiet
    kernel_make_device "device:/ttyS0"
    spectro open "serial:0" "baud 9600" in+out+cr+lf
  else
    spectro open "serial:1" "baud 9600" in+out+cr+lf

function spectro_line -> s
  arg Str s
  s := spectro readline
  if trace
    console s eol
  if (s 0 1)="."
    s := "0"+s

function spectro_spectrum -> cs
  arg ColorSpectrum cs
  spectro writeline "MSC"
  cs set_step 10
  var Int w := 400
  var Str listing := ""
  while { var Str l := spectro_line ; listing += "[lf]"+l ; l<>"" }
    if (l parse (var Float f))
      cs set_measure w f*0.01
      w += 10
  if w<>710 or { var Str l := spectro_line ; listing += "[lf]"+l ; l<>"Yxy" }
    cs := var ColorSpectrum undefined_color_spectrum
    error error_id_unexpected "Unexpected answer from the spectrocolorimeter:"+listing
  spectro_line parse (var Float Y)
  spectro_line parse (var Float x)
  spectro_line parse (var Float y)
  if trace
    console "  Yxy fourni = " Y " " x " " y eol
    var ColorXYZn xyzn := cs XYZn illuminant
    var Float X2 := xyzn:Xn*illuminant:X/100
    var Float Y2 := xyzn:Yn*illuminant:Y/100
    var Float Z2 := xyzn:Zn*illuminant:Z/100
    var Float x2 := X2/(X2+Y2+Z2)
    var Float y2 := Y2/(X2+Y2+Z2)
    console "  Yxy calcul頽 " Y2 " " x2 " " y2 eol
function spectro_command s cmd -> a
  arg_rw Stream s ; arg Str cmd a
  s writeline "; "+cmd
  a := s readline
  console "; " cmd " -> " a eol

export spectro_init spectro_spectrum

function percent f -> s
  arg Float f ; arg Str s
  s := (string (cast f*1000 Int)/10)+"%"


if false
  # Spectrolino interface

  module "/pliant/language/stream.pli"
  module "/pliant/language/stream/serial.pli"
  module "/pliant/linux/kernel/device.pli"
  
  function spectro_command s cmd -> a
    arg_rw Stream s ; arg Str cmd a
    s writeline "; "+cmd
    a := s readline
    console "; " cmd " -> " a eol
  
  function test
    kernel_make_device:"device:/ttyS0"
    (var Stream s) open "serial:0" "speed 9600 flowcontrol [dq]none[dq]" in+out+safe+cr+lf
    if s=failure
      console "no serial device" eol
function spectro_init
  if os_api="linux"
    kernel_load_module "8250_pci"
    kernel_make_device "device:/ttyS0"
  spectro open "serial:"+(shunt os_api="linux" "0" "1") "speed 9600 flowcontrol [dq]none[dq]" in+out+safe+cr+lf
  spectro configure "timeout 30"
  if model="spectrolino"
    if not ((spectro_command spectro "208 36") parse ": 209" any) # output status
      spectro open "" in+out+safe
      return
    s configure "timeout 30"
    if not ((spectro_command s "208 36") parse ": 209" any) # output status
      console "serial device is not a spectrolino" eol
      return
    part init
      spectro_command s "208 10" # set device online
      spectro_command s "208 12" # hold paper
      spectro_command s "208 11" # init spectrolino connection
      spectro_command s "90 1 4 5" # reset the spectrolino
      spectro_command s "77 155" # reflectance measure
      spectro_command s "22 0 1 3 0" # colorimetric parameters: white base is absolute
    part calibrate
      spectro_command s "208 6 0" # move to white reference
      spectro_command s "208 4" # move down
      if (spectro_command s "34 9 7")<>": 37 19" # white calibration
        console "white calibration failed"
    if ((spectro_command spectro "208 5 0") parse ":" "209" "129" "0" "0" (var Int ix) (var Int iy) (var Int iz)) # query position
      spectro_command spectro "208 10" # set device online
      spectro_command spectro "208 12" # hold paper
      spectro_command spectro "208 11" # init spectrolino connection
      spectro_command spectro "90 1 4 5" # reset the spectrolino
      spectro_command spectro "77 155" # reflectance measure
      spectro_command spectro "22 0 1 3 0" # colorimetric parameters: white base is absolute
      spectro_command spectro "208 6 0" # move to white reference
      spectro_command spectro "208 4" # move down
      if (spectro_command spectro "34 9 7")<>": 37 19" # white calibration
        spectro open "" in+out+safe
        return
      spectro_command s "0" # query parameters: last should be 1 = no filter
      spectro_command s "208 3" # move up
    var Float x := 50 ; var Float y := 30
    if true
      if ((spectro_command s "208 7 "+(string x*10 "fixed 0")+" "+(string y*10 "fixed 0")) parse ":" "16" "9" "0" any:(var Str spec)) # move, down, measure, up
        var Int w := 380
        while (spec parse (var Float d) any:(var Str remain)) and w<=730
          console " " w ":" d
          w += 10 ; spec := remain
        console eol
      spectro_command spectro "0" # query parameters: last should be 1 = no filter
      spectro_command spectro "208 3" # move up
      spectro_command spectro "208 0 0 "+string:ix+" "+string:iy # move
      spectro_command spectro "208 13" # release paper
      spectro_command spectro "208 11" # set device offline
    else
      spectro_command s "208 0 0 "+(string x*10 "fixed 0")+" "+(string y*10 "fixed 0") # move
      # if ((spectro_command s "208 5 0") parse ":" "209" "129" "0" "0" (var Int ix) (var Int iy) (var Int iz)) # query position
      #   console ix/10 " " iy/10 eol
      spectro_command s "208 4" # move down
      spectro_command s "32" # measure and read
      # spectro_command s "208 7 "+(string x*10 "fixed 0")+" "+(string y*10 "fixed 0") # move, down, measure, up
      if ((spectro_command s "184 9 0") parse ":" "185" "9" "0" any:(var Str spec))# read spectrum
      spectro open "" in+out+safe

function spectro_spectrum -> cs
  arg ColorSpectrum cs
  cs := var ColorSpectrum no_spectrum
  if spectro:name=""
    if os_api="linux"
      kernel_load_module "8250_pci"
      kernel_make_device "device:/ttyS0"
    spectro open "serial:"+(shunt os_api="linux" "0" "1") "speed 9600 flowcontrol [dq]none[dq]" in+out+safe+cr+lf
    spectro configure "timeout 30"
  if model="minolta"
    spectro writeline "MSC"
    cs set_step 10
    var Int w := 400
    var Str listing := ""
    while { var Str l := spectro_line ; listing += "[lf]"+l ; l<>"" }
      if (l parse (var Float f))
        cs set_measure w f*0.01
        w += 10
    if w<>710 or { var Str l := spectro_line ; listing += "[lf]"+l ; l<>"Yxy" }
      cs := var ColorSpectrum undefined_color_spectrum
      error error_id_unexpected "Unexpected answer from the spectrocolorimeter:"+listing
    spectro_line parse (var Float Y)
    spectro_line parse (var Float x)
    spectro_line parse (var Float y)
    if trace
      console "  Yxy fourni = " Y " " x " " y eol
      var ColorXYZn xyzn := cs XYZn illuminant
      var Float X2 := xyzn:Xn*illuminant:X/100
      var Float Y2 := xyzn:Yn*illuminant:Y/100
      var Float Z2 := xyzn:Zn*illuminant:Z/100
      var Float x2 := X2/(X2+Y2+Z2)
      var Float y2 := Y2/(X2+Y2+Z2)
      console "  Yxy calcul頽 " Y2 " " x2 " " y2 eol
  eif model="spectrolino"
    if spectro_counter=0 or datetime:seconds-spectro_datetime:seconds>3600
      if ((spectro_command spectro "208 36") parse ": 209" any) # output status
        if ((spectro_command spectro "208 5 0") parse ":" "209" "129" "0" "0" (var Int ix) (var Int iy) (var Int iz)) # query position
          spectro_command spectro "208 16" # set device online
          spectro_command spectro "208 18" # hold paper
          spectro_command spectro "208 11" # init spectrolino connection
          spectro_command spectro "90 1 4 5" # reset the spectrolino
          spectro_command spectro "77 155" # reflectance measure
          spectro_command spectro "22 0 1 3 0" # colorimetric parameters: white base is absolute
          spectro_command spectro "208 6 0" # move to white reference
          spectro_command spectro "208 4" # move down
          if (spectro_command spectro "34 9 7")=": 37 19" # white calibration
            spectro_datetime := datetime
            spectro_counter := 30
          spectro_command spectro "0" # query parameters: last should be 1 = no filter
          spectro_command spectro "208 3" # move up
          spectro_command spectro "208 0 0 "+string:ix+" "+string:iy # move
          spectro_command spectro "208 19" # release paper
          spectro_command spectro "208 17" # set device offline
    if spectro_counter>0 and ((spectro_command spectro "208 5 0") parse ":" "209" "129" "0" "0" (var Int ix) (var Int iy) (var Int iz)) # query position
      spectro_command spectro "208 16" # set device online
      spectro_command spectro "208 18" # hold paper
      if ((spectro_command spectro "208 7 "+string:ix+" "+(string iy+230)) parse ":" "16" "9" "0" any:(var Str spec)) # move, down, measure, up
        cs set_step 10
        var Int w := 380
        while (spec parse (var Float d) any:(var Str remain)) and w<=730
          console " " w ":" d
          cs set_measure w d
          w += 10 ; spec := remain
        console eol
    part terminate
      spectro_command s "208 2" # move home
      spectro_command s "208 13" # release paper
      spectro_command s "208 11" # set device offline
    if s=failure
      console "broken stream" eol
  
  test
      spectro_command spectro "208 0 0 "+string:ix+" "+string:iy # move
      spectro_command spectro "208 19" # release paper
      spectro_command spectro "208 17" # set device offline
      spectro flush anytime
      spectro_counter -= 1
    

export spectro_init spectro_spectrum