reopen ttyACM0 after timeout
[svn42.git] / go / uc_sensor_node_zmq / main.go
1 // (c) Bernhard Tittelbach, 2013
2
3 package main
4
5 import (
6         "flag"
7         "time"
8
9         zmq "github.com/vaughan0/go-zmq"
10 )
11
12 // ---------- Main Code -------------
13
14 var (
15         tty_dev_      string
16         pub_addr      string
17         use_syslog_   bool
18         enable_debug_ bool
19         serial_speed_ uint
20 )
21
22 const exponential_backof_activation_threshold int64 = 4
23
24 func init() {
25         flag.StringVar(&pub_addr, "brokeraddr", "tcp://torwaechter.realraum.at:4243", "zmq address to send stuff to")
26         flag.StringVar(&tty_dev_, "ttydev", "/dev/ttyACM0", "path do tty uc device")
27         flag.UintVar(&serial_speed_, "serspeed", 0, "tty baudrate (0 to disable setting a baudrate e.g. in case of ttyACM)")
28         flag.BoolVar(&use_syslog_, "syslog", false, "log to syslog local1 facility")
29         flag.BoolVar(&enable_debug_, "debug", false, "debugging messages on")
30         flag.Parse()
31 }
32
33 func ConnectSerialToZMQ(pub_sock *zmq.Socket, timeout time.Duration) {
34         defer func() {
35                 if x := recover(); x != nil {
36                         Syslog_.Println(x)
37                 }
38         }()
39
40         serial_wr, serial_rd, err := OpenAndHandleSerial(tty_dev_, serial_speed_)
41         if err != nil {
42                 panic(err)
43         }
44         defer close(serial_wr)
45
46         t := time.NewTimer(timeout)
47         for {
48                 select {
49                 case incoming_ser_line, seropen := <-serial_rd:
50                         if !seropen {
51                                 return
52                         }
53                         t.Reset(timeout)
54                         Syslog_.Printf("%s", incoming_ser_line)
55                         if err := pub_sock.Send(incoming_ser_line); err != nil {
56                                 Syslog_.Println(err.Error())
57                         }
58
59                 case <-t.C:
60                         Syslog_.Print("Timeout, no message for 120 seconds")
61                 }
62         }
63 }
64
65 func main() {
66         zmqctx, pub_sock := ZmqsInit(pub_addr)
67         if pub_sock == nil {
68                 panic("zmq socket creation failed")
69         }
70         defer zmqctx.Close()
71         defer pub_sock.Close()
72
73         if enable_debug_ {
74                 LogEnableDebuglog()
75         } else if use_syslog_ {
76                 LogEnableSyslog()
77                 Syslog_.Print("started")
78         }
79
80         var backoff_exp uint32 = 0
81         for {
82                 start_time := time.Now().Unix()
83                 ConnectSerialToZMQ(pub_sock, time.Second*120)
84                 run_time := time.Now().Unix() - start_time
85                 if run_time > exponential_backof_activation_threshold {
86                         backoff_exp = 0
87                 }
88                 time.Sleep(150 * (1 << backoff_exp) * time.Millisecond)
89                 if backoff_exp < 12 {
90                         backoff_exp++
91                 }
92         }
93 }