Sure!
Systemet är inte i drift längre, men jag har kvar filen.
Av någon anledning skrev jag mjukvaran i TCL.
Systemet kördes på en Asus WL500G Delux och någon tidig variant av OpenWRT.
I grund och botten är det ett system som utifrån configfiler för olika switchar sätter switcharnas status av/på.
Med menysystemet kan man ändra de schemalagda till/och frånslagen för switcharna - det var rätt praktiskt att med ett par knapptryckningar släcka alla akvarier i vardagsrummet när vi såg på film.
Systemet är "modulbaserat" dvs det finns en funktion för:
- varje "skärmbild" (en skärmbild var temperaturinfo, en skärmbild var schema för till/avslag, en skärmbild var för att ändra till/frånslag/ en skärmbild var för lite allmän info).
- Detektering av om någon knapp är tryckt
- Knapphantering. Knapparna skulle ju ge olika händelser beroende på vilken skärmbild som var aktiv och var i skärmbilden man var
- Till/frånslag av switchar
funktionen "button_action" och "skarm3" kan jag tänka mig att det är lite svårt att sätta sig in i....
Filerna är totalt okommenterade, jag hade nog inte i min vildaste fantasi kunnat gissa att någon skulle vilja se koden 5 år senare!
Kod: Markera allt
#!/usr/bin/tclsh
#include <tcl.h>
set timeout 20
set debug 0
set backlight 1
set 1wire "/mnt/1wire"
set LCDid "/mnt/1wire/uncached/FF.830200000100"
set root "/1wiresoft"
set configfiles "solspot.cfg terrarium.cfg akvarie1.cfg akvarie2.cfg"
set timelist "1 10 15 30 60 120 240"
set filesystem "/mnt/usb_stick"
set user "erik"
set version 1.2.0
set m1 1
set m2 0
set lastbutton 1
set todo 0
set done 0
set location 0
set i 0
set loop 59
set error -1
set odd 0
foreach cfg $configfiles {
set cfgfile [open "|tail -n 2 $root/$cfg" r]
set switch_name($i) [gets $cfgfile]
set switch_id($i) [gets $cfgfile]
close $cfgfile
set undantag($i) 0
set undantag_typ($i) 0
set next_event($i) 0
set next_event_typ($i) 0
incr i
}
set switch_name($i) "Alla"
proc errorhandler { } {
global odd root loop error m1 m2 switch_id switch_name
set m1 1
set m2 0
# if {$loop > 3} {
# set loop 0
# }
# if { $loop < 2 } {
writelcd "Switchfel! " 0
writelcd "$switch_name($error) ur" 1
writelcd "funkton! " 2
writelcd "($switch_id($error))" 3
# } else {
# writelcd "Tryck pa nagon knapp" 0
# writelcd "For att aterstalla!" 1
# writelcd "---------------------" 2
# writelcd "---------------------" 3
# }
}
proc check_lamps { } {
global debug switch_name switch_id error root configfiles 1wire undantag undantag_typ next_event next_event_typ
set i 0
set today_date [clock format [clock seconds] -format %d/%m]
foreach j $configfiles {
if { $undantag($i) < [clock seconds] } {
set undantag($i) 0
set data 0
set of2 [open "$root/$j" r]
set data [gets $of2]
while {![eof $of2]} {
if {[string match "*$today_date*" $data]} {
break
} else {
set data [gets $of2]
}
}
close $of2
if { ![string match $today_date [lindex $data 0]] } {
set of [open "|head -n 1 $root/$j" r]
set timeframe [gets $of]
close $of
} else {
set timeframe [string range $data 6 end]
}
if { [catch {set of [open "$1wire/$switch_id($i)/PIO.A" w]} err ]} {
set error $i
errorhandler
return
break
}
set next_event($i) [clock scan [lindex $timeframe 0]]
set next_event_typ($i) "1"
if { [clock scan [lindex $timeframe 0]] < [clock seconds] && [clock scan [lindex $timeframe 1]] > [clock seconds] } {
puts $of "1"
set next_event($i) [clock scan [lindex $timeframe 1]]
set next_event_typ($i) "0"
} else {
puts $of "0"
if {![clock seconds] > [clock scan [lindex $timeframe 0]]} {
set next_event($i) 0
}
}
close $of
} else {
set next_event($i) $undantag($i)
set next_event_typ($i) $undantag_typ($i)
}
incr i
}
}
proc backlight { backlight } {
global debug LCDid
if {![catch {set bl [open "$LCDid/backlight" w]} err ]} {
puts $bl $backlight
close $bl
}
}
proc get_temps { } {
global temp min max
set temp1 [open "/home/termo/ute.txt" r]
set temp [gets $temp1]
close $temp1
if { [catch {set of [open "/home/termo/minmax.txt" r]} err ]} {
set min "err"
set max "err"
} else {
set min [gets $of]
set min "[lindex $min 0]ßC [lindex $min 1]"
set max [gets $of]
set max "[lindex $max 0]ßC [lindex $max 1]"
close $of
}
}
proc get_temps2 { } {
global root user filesystem inne akv space mail
set of [open "/home/termo/lcd.txt"]
gets $of
set inne [gets $of]
set akv [gets $of]
# set of [open "|df -h $filesystem" r]
# gets $of
# gets $of
# set space [lindex [gets $of] 3]
# close $ofi
set space 0
# set of [open "|ls /home/$user/mail/new | wc -l" r]
# set of2 [open "|ls /home/$user/mail/cur | grep -v S | wc -l" r]
# set i [gets $of]
# set j [gets $of2]
# set mail [ expr $i + $j]
# close $of
#close $of2
set mail 0
}
proc checkbuttons { } {
global debug m1 m2 lastbutton LCDid
if {![catch {set buttons [open "$LCDid/counters.ALL" r]} err ]} {
if {[catch { set butt [gets $buttons] } err]} {
catch {close $buttons}
return 0
}
catch { close $buttons }
} else {
return 0
}
set butt [split [string map {" " ""} $butt] ","]
for { set k 0 } { $k < 4 } {incr k} {
if {[lindex $butt $k] > 0 } {
set i [expr floor([lindex $butt $k] / 2 ) ]
if { $i == 0 && $lastbutton == 0} {
set lastbutton 1
return 0
}
set lastbutton 0
if { $i != [expr [lindex $butt $k]/2]} {
return [expr $k +1][expr $i +1]
} else {
return [expr $k +1]$i
}
}
}
return 0
}
proc writelcd { data line } {
global LCDid
if {![catch {set lcd [open "$LCDid/line20.$line" w]} err ]} {
puts $lcd $data
close $lcd
}
}
proc correct_value { data } {
# puts $data
if {[string match "*n*" $data]} { return "NA" }
set i [string range $data [expr [string length $data] - 1] [string length $data] ]
set j 0
if { [string match "*-*" [string range $data 3 [string length $data]]] } {
set data [string range $data 0 6]
while { $j < $i } {
set data [expr $data / 10]
incr j
}
} else {
set data [string range $data 0 6]
while { $j < $i } {
set data [expr $data * 10]
incr j
}
}
return [string range $data 0 [expr [string first "." $data]+ 2]]
}
proc standard {} {
global temp min max
writelcd "Temperatur: $temp ßC" 0
writelcd "Max: $max" 1
writelcd "Min: $min" 2
writelcd "[clock format [clock seconds]]" 3
}
proc skarm2 {} {
global mail inne akv space
writelcd "Inne: $inne" 0
writelcd "Akvarium: $akv" 1
writelcd "Nya mail: ${mail}st" 2
writelcd "/gemensamt/ $space Free" 3
}
proc skarm3 {} {
global odd debug undantag undantag_typ switch_name next_event next_event_typ m2 location done todo andra tid timelist status
if { $m2 == 0 } {
for {set i 0} { $i <4 } {incr i} {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ($i) == 0 } { set msg "off" }
writelcd "$switch_name($i) [clock format $next_event($i) -format %H:%M] $msg" $i
}
} elseif { $m2 == 1 } {
if {$todo == 2} {
if { $location == 0 } {
set location 4
} else {
set location [expr $location -1 ]
}
} elseif {$todo == 1 } {
if {$location == 4} {
set location 0
} else {
incr location
}
}
set todo 0
for {set i 0} { $i <4 } {incr i} {
if {$location == 4} {
if { $i == 3 } {
if {$odd == 1 } {
writelcd " " $i
} else {
writelcd "ándra Alla" $i
}
} else {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ([expr $i + 1]) == 0 } { set msg "off" }
writelcd "$switch_name([expr $i +1]) [clock format $next_event([expr $i + 1]) -format %H:%M] $msg" $i
}
} else {
if {$location == $i && $odd == 1} {
writelcd " " $i
} else {
set msg "on"
if { [string match *e* $next_event_typ($i)] } { set msg "event" }
if { $next_event_typ($i) == 0 } { set msg "off" }
writelcd "$switch_name($i) [clock format $next_event($i) -format %H:%M] $msg" $i
}
}
}
} elseif {$m2 == 2 } {
writelcd $switch_name($location) 0
if { $done == 1} {
if {$andra == 0} {
incr andra
} else {
set_undantag $location [lindex $timelist $tid] $status
set done 0
set andra 0
return 0
}
set done 0
}
if {$andra == 0} {
if { $todo > 0 } {
if {[string match "*på*" $status] } {
set status "av"
} else {
set status "på"
}
set todo 0
}
if {$odd == 1} {
writelcd " " 1
} else {
writelcd "$status " 1
}
} else {
writelcd "$status " 1
}
if {$andra == 1 } {
if { $todo == 1 } {
if {$tid == 6 } {
set tid 0
} else {
incr tid
}
} elseif { $todo == 2 } {
if {$tid == 0 } {
set tid 6
} else {
set tid [expr $tid -1 ]
}
}
set todo 0
if {$odd == 1} {
writelcd " " 2
} else {
writelcd "[lindex $timelist $tid] Minuter " 2
}
} else {
writelcd "[lindex $timelist $tid] Minuter " 2
}
writelcd "-----------------------" 3
}
}
proc skarm4 {} {
global version
writelcd " Smart Home System" 0
writelcd " By elf98" 1
writelcd " version $version" 2
writelcd "--------------------" 3
}
proc set_undantag { id tid status } {
global 1wire root m1 m2 next_event error next_event_typ switch_name switch_id undantag undantag_typ
if { $id == 4 } {
set actionlist "0 1 2 3"
} else {
set actionlist "$id"
}
foreach id $actionlist {
set undantag($id) [expr [clock seconds] + [expr 60*$tid]]
if { [catch {set of [open "$1wire/$switch_id($id)/PIO.A" w]} err ]} {
set error $id
errorhandler
return
}
if {[string match "*på*" $status]} {
puts $of 1
set undantag_typ($id) 0e
} else {
puts $of 0
set undantag_typ($id) 1e
}
close $of
set next_event($id) $undantag($id)
set next_event_typ($id) $undantag_typ($id)
}
set m2 0
}
proc buttonaction { butt } {
global error debug m1 m2 todo loop undantag backlight andra tid status done
if { $butt < 1 || $butt > 100 } { return 0 }
set loop 0
if {$error >= 0 } {
set error -1
check_lamps
return
}
if { $m1 == 1 } {
if { $butt < 20 } {
for { set i 0 } { $i <4} {incr i} { set undantag($i) 0 }
check_lamps
backlight $backlight
} elseif { $butt < 30 } {
set m1 2
} elseif { $butt < 40 } {
set m1 4
} else {
if { $backlight == 0 } {
set backlight 1
} else {
set backlight 0
}
backlight $backlight
}
} elseif { $m1 == 2 || $m1 == 4} {
if { $butt < 20 } {
set m1 1
} elseif { $butt < 30 } {
if { $m1 == 4} {
set m1 1
} else {
set m1 3
}
set m2 0
} elseif { $butt <40 } {
if { $m1 == 4 } {
set m1 3
} else {
set m1 1
}
set m2 0
} else {
set m1 1
}
} elseif { $m1 == 3 } {
if { $m2 == 0 } {
if {$butt < 20 } {
set m1 1
} elseif { $butt < 30 } {
set m1 4
} elseif { $butt < 40 } {
set m1 2
} else {
set m2 1
}
} else {
if {$butt < 20 } {
set m2 [expr $m2 -1]
} elseif {$butt < 30} {
set todo 1
} elseif { $butt < 40 } {
set todo 2
} else {
if { $m2 == 2 } {
set done 1
} else {
set m2 2
set status "på"
set tid 0
set andra 0
}
}
}
}
return 1
}
if {![catch {set of [open "$LCDid/LCDon" w]} err ]} {
puts $of 1
close $of
}
get_temps
backlight $backlight
while {$loop <60} {
set state [buttonaction [checkbuttons]]
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
if {$state != 1} {
after $timeout
set state [buttonaction [checkbuttons]]
}
incr loop
if {$loop == 30 } {
set m1 1
set m2 0
}
if { $loop > 59 } {
set loop 0
get_temps
check_lamps
backlight $backlight
}
if {[string match "*.5" [expr $loop/2.0]] } {
set odd 0
} else {
set odd 1
}
if {[expr $undantag(0) + $undantag(1) + $undantag(2) + $undantag(3)] != 0 || $error >= 0 } {
backlight $odd
} else {
backlight $backlight
}
set error -1
if {$error >= 0 && $odd == 0} {
errorhandler
check_lamps
} elseif {$m1 == 1} {
standard
} elseif { $m1 == 2} {
if {$loop == 1} {
get_temps2
}
skarm2
} elseif {$m1 == 3 } {
skarm3
} elseif {$m1 == 4} {
skarm4
}
}
Ett exempel på hur en konfigfil kunde se ut:
Kod: Markera allt
12:00 18:30
27/01 10:02 23:59
Solspot
12.166B32000000
Den översta raden var standardinställningen.
Sedan följer X antal rader med datumspecifika till och frånslag.
Näst sista raden är aliaset för switchen
och sista raden är idnummer.