Files
sea/tcl/drivers/jumo.tcl
2022-08-18 15:04:28 +02:00

176 lines
3.9 KiB
Tcl

# rs485, 9600 baud / 8 bit / no parity / 1 stop
# modbus protocol, float order: words swapped (byte 0 is at pos. 2)
namespace eval jumo {} {
}
proc stdConfig::jumo {adr upperlimit} {
# timeout 5, try again 2
controller bin modbus-crc 5 2
prop read jumo::readfloat
prop write jumo::writefloat
prop startcmd "int1 4 3 int2 0 6 crc / skip code skip str12 crc"
obj JUMO rd
prop @adr $adr
prop adr 0x002a
kids "Jumo $adr" {
node set wr
prop adr 0x3100
prop upperlimit $upperlimit
node reg rd
prop adr 0x0035
node htr rd
prop scale 2
prop adr 0x0039
# node cool rd
# prop adr 0x003b
node pb wr
prop label "prop. band"
prop adr 0x3000
node rt wr
prop label "int t"
prop adr 0x3006
node td wr
prop label "deriv t"
prop adr 0x3004
#node y0 wr -int
#prop read jumo::readint
#prop write jumo::writeint
#prop adr 0x3017
node ramp wr
prop adr 0x004e
#node state rd -int
#prop read jumo::readint
#prop adr 0x0020
#node limitstate rd
#prop read jumo::readint
#prop adr 0x0024
node manual wr -int
prop write jumo::writemanual
prop read jumo::readmanual
prop update jumo::updatemanual
prop enum 1
node manual_output wr -int
prop read jumo::readint
prop write jumo::writeint
prop scale 2
prop adr 0x0041
node dump out -text
prop write jumo::dump
}
}
proc jumo::readfloat {} {
set cmd [format {int1 %d 3 int2 %d 2 crc} [sct @adr] [sct adr]]
sct send "$cmd / skip code skip float2 crc"
return jumo::update
}
proc jumo::readint {} {
set cmd [format {int1 %d 3 int2 %d 1 crc} [sct @adr] [sct adr]]
sct send "$cmd / skip code skip int2 crc"
return jumo::update
}
proc jumo::update {} {
sct update [expr [sct result] * [silent 1 sct scale]]
return idle
}
proc jumo::writefloat {} {
if {[sct target] > [silent [sct target] sct upperlimit]} {
error "[sct] [sct target] is above upper limit [sct upperlimit]"
}
set tg [expr [sct target] / double([silent 1 sct scale])]
set cmd [format {int1 %d 16 int2 %d 2 int1 4 float2 %g crc} [sct @adr] [sct adr] $tg]
sct send "$cmd / skip code skip4 crc"
return jumo::readfloat
}
proc jumo::writeint {} {
set tg [expr [sct target] / [silent 1 sct scale]]
set cmd [format {int1 %d 16 int2 %d 1 int1 2 int2 %d crc} [sct @adr] [sct adr] $tg]
sct send "$cmd / skip code skip4 crc"
return jumo::readint
}
proc jumo::writemanual {} {
if {[sct target]} {
set bitmap 4
} else {
set bitmap 8
}
set cmd [format {int1 %d 16 int2 %d 1 int1 2 int2 %d crc} [sct @adr] 0x0047 $bitmap]
sct send "$cmd / skip code skip4 crc"
return stdSct::completeUpdate
}
proc jumo::readmanual {} {
set cmd [format {int1 %d 3 int2 %d 1 crc} [sct @adr] 0x0020]
sct send "$cmd / skip code skip int2 crc"
return jumo::updatemanual
}
proc jumo::updatemanual {} {
sct update [expr ([sct result] >> 12) & 1]
return idle
}
proc jumo::result2string {} {
set string ""
foreach ch [sct result] {
if {$ch == 0} {
break
}
append string [format %c $ch]
}
return $string
}
proc jumo::dump {{adr 0} {wadr -1}} {
global jumo_fp
if {$wadr >= 0} {
if {$wadr == 0} {
set jumo_fp [open jumo_[sct target]_[sct @adr].dump w]
sct update [sct target]
}
set code [lindex [sct result] 0]
if {$code > 128} {
clientput "$wadr: error [expr $code - 128]"
} else {
for {set i 0} {$i < 16} {incr i} {
puts $jumo_fp "[format %4.4x [expr $wadr + $i]]: [lrange [sct result] [expr $i * 2 + 1] [expr $i * 2 + 2]]"
}
}
}
if {$wadr >= 0x3000} {
close $jumo_fp
return idle
}
set cmd [format {int1 %d 3 int2 %d 16 crc / skip int1 skip dump} [sct @adr] $adr]
clientput $cmd
sct send $cmd
set nextadr [expr $adr + 16]
if {$nextadr == 0x60} {
set nextadr 0x3000
}
return "jumo::dump $nextadr $adr"
}