# 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" }