--- /dev/null
+#/usr/bin/env tclsh
+#
+# URL=https://api.thingspeak.com/update
+# KEY=QXY49R9TYM0LYCB2
+# curl --data "key=$KEY&field1=$Temp0&field2=$Pressure0&field3=$Lux" $URL
+
+package require Tcl 8.6
+package require http
+package require tls
+package require autoproxy
+
+variable URL "http://api.thingspeak.com/update"
+variable KEY "1HWAT971G1N0RJ6U"
+
+proc OnHttpComplete {tok} {
+ puts "[http::status $tok] $tok"
+ http::cleanup $tok
+}
+
+proc avg {lst} {
+ set count [llength $lst]
+ foreach v $lst {
+ set sum [expr {$sum + $v}]
+ }
+ return [expr {$sum / double($count)}]
+}
+
+proc median {lst} {
+ set lst [lsort -real $lst]
+ set len [llength $lst]
+ if {$len & 1} {
+ # odd number of elements
+ return [lindex $lst [expr {($len-1)/2}]]
+ } else {
+ # for even number, interpolate center pair
+ set idx2 [expr {$len / 2}]
+ set idx1 [expr {$idx2-1}]
+ return [expr {([lindex $lst $idx1] + [lindex $lst $idx2]) / 2.0}]
+ }
+}
+
+proc upload {} {
+ variable URL
+ variable KEY
+ variable TEMPERATURES
+ variable HUMIDITIES
+ variable PRESSURES
+
+ set A [median $TEMPERATURES]
+ set B [set C 0]
+ if {[llength $HUMIDITIES] > 0} { set B [median $HUMIDITIES] }
+ if {[llength $PRESSURES] > 0} {set C [median $PRESSURES] }
+ set TEMPERATURES [set HUMIDITIES [set PRESSURES {}]]
+ set req [http::formatQuery api_key $KEY field1 $A field2 $B field3 $C]
+ set tok [http::geturl $URL -query $req -timeout 500 -command [list OnHttpComplete]]
+ http::wait $tok
+}
+
+proc main {port {baudrate 57600}} {
+ variable TEMPERATURES {}
+ variable HUMIDITIES {}
+ variable PRESSURES {}
+
+ http::register https 443 [list autoproxy::tls_socket -ssl2 0 -ssl3 0 -tls1 1]
+ autoproxy::init
+ puts "# proxy: [autoproxy::cget -proxy_host]"
+
+ set sio [open $port r]
+ fconfigure $sio -buffering line -encoding ascii -translation {auto crlf} -mode $baudrate,n,8,1
+ while {[gets $sio line] != -1} {
+ if {[string match "# *" $line]} { puts $line; continue }
+ set T {}
+ set H {}
+ set P {}
+ if {[catch {
+ foreach sensor [lrange [split $line "\["] 1 end] {
+ set sensor [string trim $sensor "\[\] "]
+ lassign $sensor id ts t h p
+ lappend T [expr {double($t)}]
+ if {$h != 0} {lappend H [expr {double($h)}]}
+ if {$p != 0} {lappend P [expr {double($p)}]}
+ }
+ set temperature [median $T]
+ lappend TEMPERATURES $temperature
+ if {[llength $H] > 0} {
+ set humidity [median $H]
+ lappend HUMIDITIES $humidity
+ } else {
+ set humidity -1
+ }
+ if {[llength $P]} {
+ set pressure [median $P]
+ lappend PRESSURES $pressure
+ } else {
+ set pressure -1
+ }
+ puts [format "%d %.2f %.2f %.2f : {$T} {$H} {$P}" \
+ [clock seconds] $temperature $humidity $pressure]
+ # every 5 minutes
+ if {[llength $TEMPERATURES] > (60 * 5)} {
+ upload
+ }
+ } err]} {
+ puts "! $line\n! $::errorInfo"
+ }
+ }
+ return 0
+}
+
+if {!$tcl_interactive} {
+ set r [catch [linsert $argv 0 main] err]
+ if {$r} {
+ puts stderr $::errorInfo
+ }
+ exit $r
+}