more threads
authorBernhard Tittelbach <xro@realraum.at>
Sat, 24 Aug 2013 17:30:30 +0000 (17:30 +0000)
committerBernhard Tittelbach <xro@realraum.at>
Sat, 24 Aug 2013 17:30:30 +0000 (17:30 +0000)
r3-netstatus/brain/brain.go [new file with mode: 0644]
r3-netstatus/main.go
r3-netstatus/make_deploy.zsh
r3-netstatus/r3xmppbot/r3xmppbot.go
r3-netstatus/sockettoevent.go [new file with mode: 0644]
r3-netstatus/webstatus.go [new file with mode: 0644]
tuer_status.initscript

diff --git a/r3-netstatus/brain/brain.go b/r3-netstatus/brain/brain.go
new file mode 100644 (file)
index 0000000..c7c3940
--- /dev/null
@@ -0,0 +1,116 @@
+package brain
+
+import "errors"
+
+type informationtuple struct {
+    name string
+    value interface{}
+}
+
+type informationretrievalpath struct {
+    name string
+    returnpath chan interface{}
+}
+
+type hippocampus map[string]interface{}
+
+type Brain struct {
+    storeTuple chan informationtuple
+    retrieveValue chan informationretrievalpath
+    shutdown chan bool
+}
+
+func New() *Brain {
+    b := new(Brain)
+    b.storeTuple = make(chan informationtuple)
+    b.retrieveValue = make(chan informationretrievalpath)
+    go b.runBrain()
+    return b
+}
+
+func (b *Brain) runBrain() {
+    var h hippocampus = make(hippocampus)
+    for {
+        select {
+            case newtuple := <- b.storeTuple:
+                h[newtuple.name] = newtuple.value
+
+            case retrievvalue := <- b.retrieveValue:
+                v, e := h[retrievvalue.name]
+                if e {
+                    retrievvalue.returnpath <- v
+                } else {
+                    retrievvalue.returnpath <- nil
+                }
+                
+            case <- b.shutdown:
+                break
+        }
+    }
+}
+
+func (b *Brain) Shutdown() {
+    b.shutdown <- true
+}
+
+func (b *Brain) Oboite(name string, value interface{}) {
+    b.storeTuple <- informationtuple{name, value}
+}
+
+func (b *Brain) OmoiDashite(name string) (interface{}, error) {
+    rc := make(chan interface{})
+    b.retrieveValue <- informationretrievalpath{name, rc}
+    v := <- rc
+    if v == nil {
+        return v, errors.New("name not in brain")
+    }
+    return v, nil
+}
+
+func (b *Brain) OmoiDashiteBool(name string) (bool, error) {
+    v, e := b.OmoiDashite(name)
+    if e != nil {
+        return false, e
+    }
+    vc, ok := v.(bool)
+    if !ok {
+        return false, errors.New(name + " does not have type bool")
+    }
+    return vc, nil
+}
+
+func (b *Brain) OmoiDashiteInt(name string) (int, error) {
+    v, e := b.OmoiDashite(name)
+    if e != nil {
+        return 0, e
+    }
+    vc, ok := v.(int)
+    if !ok {
+        return 0, errors.New(name + " does not have type int")
+    }
+    return vc, nil
+}
+
+func (b *Brain) OmoiDashiteFloat(name string) (float64, error) {
+    v, e := b.OmoiDashite(name)
+    if e != nil {
+        return 0, e
+    }
+    vc, ok := v.(float64)
+    if !ok {
+        return 0, errors.New(name + " does not have type float64")
+    }
+    return vc, nil
+}
+
+func (b *Brain) OmoiDashiteString(name string) (string, error) {
+    v, e := b.OmoiDashite(name)
+    if e != nil {
+        return "", e
+    }
+    vc, ok := v.(string)
+    if !ok {
+        return "", errors.New(name + " does not have type string")
+    }
+    return vc, nil
+}
\ No newline at end of file
index 9fb1253..8851c74 100644 (file)
@@ -1,18 +1,12 @@
 package main
 
 import (
-       "./spaceapi"
     "./r3xmppbot"
-    //pubsub "github.com/tuxychandru/pubsub"
+    pubsub "github.com/tuxychandru/pubsub"
     "flag"
-       "bufio"
-       "fmt"
-       "net"
-       "net/http"
-       "net/url"
-       "regexp"
-       "time"
-    "strconv"
+    "time"
+    "fmt"
+    //~ "./brain"
 )
 
 type SpaceState struct {
@@ -23,166 +17,76 @@ type SpaceState struct {
 }
 
 var (
-       re_presence_    *regexp.Regexp     = regexp.MustCompile("Presence: (yes|no)(?:, (opened|closed), (.+))?")
-       re_status_      *regexp.Regexp     = regexp.MustCompile("Status: (closed|opened), (opening|waiting|closing|idle), (ajar|shut).*")
-       re_button_      *regexp.Regexp     = regexp.MustCompile("PanicButton|button\\d?")
-       re_temp_        *regexp.Regexp     = regexp.MustCompile("temp0: (\\d+\\.\\d+)")
-       re_photo_       *regexp.Regexp     = regexp.MustCompile("photo0: (\\d+)")
-       re_querystresc_ *regexp.Regexp     = regexp.MustCompile("[^\x30-\x39\x41-\x7E]")
-       spaceapidata    spaceapi.SpaceInfo = spaceapi.NewSpaceInfo("realraum", "http://realraum.at", "http://realraum.at/logo-red_250x250.png", "http://realraum.at/logo-re_open_100x100.png", "http://realraum.at/logo-re_empty_100x100.png",47.065779129, 15.442322614).AddSpaceAddress("Jakoministr. 16 ground level left, 8010 Graz, Austria")
-       statusstate     *SpaceState        = new(SpaceState)
     presence_socket_path_ string
        xmpp_presence_events_chan_     chan interface{}
     xmpp_login_ struct {jid string; pass string}
     xmpp_bot_authstring_ string
+    xmpp_state_save_dir_ string
 )
 
+//-------
 
-var flagvar int
 func init() {
        flag.StringVar(&xmpp_login_.jid, "xjid", "realrauminfo@realraum.at/Tuer", "XMPP Bot Login JID")
        flag.StringVar(&xmpp_login_.pass, "xpass", "", "XMPP Bot Login Password")
        flag.StringVar(&xmpp_bot_authstring_, "xbotauth", "", "String that user use to authenticate themselves to the bot")
        flag.StringVar(&presence_socket_path_,"presencesocket", "/var/run/tuer/presence.socket",  "Path to presence socket")
+       flag.StringVar(&xmpp_state_save_dir_,"xstatedir","/flash/var/lib/r3netstatus/",  "Directory to save XMPP bot state in")
     flag.Parse()
 }
 
-
 //-------
 
-func updateStatusString() {
-       var spacestatus string
-       if statusstate.present {
-               if statusstate.buttonpress_until > time.Now().Unix() {
-                       spacestatus = "Panic! Present&Bored"
-               } else {
-                       spacestatus = "Leute Anwesend"
-               }
-       } else {
-               spacestatus = "Keiner Da"
-       }
-       spaceapidata.SetStatus(statusstate.present, spacestatus)
-}
-
-func publishStateToWeb() {
-       updateStatusString()
-       jsondata_b, err := spaceapidata.MakeJSON()
-       if err != nil {
-               fmt.Println("Error:", err)
-               return
-       }
-       //jsondata_b := re_querystresc_.ReplaceAllFunc(jsondata_b, func(in []byte) []byte {
-       //      out := make([]byte, 4)
-       //      out[0] = '%'
-       //      copy(out[1:], []byte(strconv.FormatInt(int64(in[0]), 16)))
-       //      return out
-       //})
-       jsondata := url.QueryEscape(string(jsondata_b))
-       resp, err := http.Get("http://www.realraum.at/cgi/status.cgi?pass=jako16&set=" + jsondata)
-       if err != nil {
-               fmt.Println("Error publishing realraum info", err)
-               return
-       }
-       defer resp.Body.Close()
-}
-
-func parseSocketInputLine(line string) {
-       match_presence := re_presence_.FindStringSubmatch(line)
-       match_status := re_status_.FindStringSubmatch(line)
-       match_button := re_button_.FindStringSubmatch(line)
-       match_temp := re_temp_.FindStringSubmatch(line)
-       match_photo := re_photo_.FindStringSubmatch(line)
-
-       if match_presence != nil {
-               statusstate.present = (match_presence[1] == "yes")
-        statusstate.door_locked = (match_presence[2] == "closed")
-        //spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("Torwaechter", "Front Door", match_presence[2] == "closed"))
-        spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("TorwaechterLock", "Türschloß", statusstate.door_locked))
-               publishStateToWeb()
-        xmpp_presence_events_chan_ <- r3xmppbot.PresenceEvent{statusstate.present, statusstate.door_locked, statusstate.door_shut}
-       } else if match_status != nil {
-        statusstate.door_locked = (match_status[1] == "closed")
-        statusstate.door_shut = (match_status[3] == "shut")
-        spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("TorwaechterLock", "Türschloß", statusstate.door_locked))
-        spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("TorwaechterAjarSensor", "Türkontakt", statusstate.door_shut))
-        //spaceapidata.MergeInSensor(spaceapi.MakeDoorAjarSensor("Torwaechter", "Front Door", match_presence[3] == "shut"))
-        publishStateToWeb()
-        xmpp_presence_events_chan_ <- r3xmppbot.PresenceEvent{statusstate.present, statusstate.door_locked, statusstate.door_shut}
-       } else if match_button != nil {
-               statusstate.buttonpress_until = time.Now().Unix() + 3600
-               spaceapidata.AddSpaceEvent("PanicButton", "check-in", "The button has been pressed")
-               publishStateToWeb()
-        xmpp_presence_events_chan_ <- "The button has been pressed ! Propably someone is bored and need company ! ;-)"
-       } else if match_temp != nil {
-               newtemp, err := strconv.ParseFloat((match_temp[1]), 32)
-               if err == nil {
-            spaceapidata.MergeInSensor(spaceapi.MakeTempCSensor("Temp0","Decke",newtemp))
-               }
-       } else if match_photo != nil {
-               newphoto, err := strconv.ParseInt(match_photo[1], 10, 32)
-               if err == nil {
-                       spaceapidata.MergeInSensor(spaceapi.MakeIlluminationSensor("Photodiode","Decke","1024V/5V",newphoto))
-               }
-       }
-}
-
-func readFromUSocket(path string, c chan string) {
-ReOpenSocket:
-       for {
-               presence_socket, err := net.Dial("unix", path)
-               if err != nil {
-                       //Waiting on Socket
-                       time.Sleep(5 * time.Second)
-                       continue ReOpenSocket
-               }
-               presence_reader := bufio.NewReader(presence_socket)
-               for {
-                       line, err := presence_reader.ReadString('\n')
-                       if err != nil {
-                               //Socket closed
-                               presence_socket.Close()
-                               continue ReOpenSocket
-                       }
-                       c <- line
-               }
+func EventToXMPP(ps *pubsub.PubSub, xmpp_presence_events_chan_ chan <- interface{}) {
+    events := ps.Sub("presence","door","buttons")
+    var present, locked, shut bool
+    var who string = "Unknown"
+
+    for eventinterface := range(events) {
+        switch event := eventinterface.(type) {
+            case PresenceUpdate:
+                present = event.Present
+                xmpp_presence_events_chan_ <- r3xmppbot.XMPPPresenceEvent{Present: present, Who: who, DoorLock: locked, DoorShut: shut, Button: false}
+            case DoorCommandEvent:
+                who = event.Who
+                xmpp_presence_events_chan_ <- fmt.Sprintln("DoorCommandEvent",event)
+            case DoorStatusUpdate:
+                locked = event.Locked
+                shut = event.Shut
+                xmpp_presence_events_chan_ <- fmt.Sprintln("DoorStatusUpdate",event)
+            case ButtonPressUpdate:
+                xmpp_presence_events_chan_ <- r3xmppbot.XMPPPresenceEvent{Present: present, Who: who, DoorLock: locked, DoorShut: shut, Button: true}
+        }
        }
 }
 
 func main() {
-       spaceapidata.AddSpaceFeed("calendar", "http://grical.realraum.at/s/?query=!realraum&view=rss")
-       spaceapidata.AddSpaceFeed("blog", "https://plus.google.com/113737596421797426873")
-       spaceapidata.AddSpaceFeed("wiki", "http://realraum.at/wiki")
-       spaceapidata.AddSpaceContactInfo("+43780700888524", "irc://irc.oftc.net/#realraum", "realraum@realraum.at", "realraum@realraum.at", "realraum@realraum.at", "vorstand@realraum.at")
-
     var err error
     var bot *r3xmppbot.XmppBot
-    bot, xmpp_presence_events_chan_, err = r3xmppbot.NewStartedBot(xmpp_login_.jid, xmpp_login_.pass, xmpp_bot_authstring_, true)
+    bot, xmpp_presence_events_chan_, err = r3xmppbot.NewStartedBot(xmpp_login_.jid, xmpp_login_.pass, xmpp_bot_authstring_, xmpp_state_save_dir_, true)
     if err != nil {
         fmt.Println(err)
         return
     }
     defer bot.StopBot()
     
-    //~ presence_events <- PresenceEvent{true, true, true}
-    //~ presence_events <- PresenceEvent{true, true, false}
-    //~ presence_events <- PresenceEvent{true, false, false}    
-    
-
-    eventqueue := make(chan string)
-    defer close(eventqueue)
+    newlinequeue := make(chan string)
+    ps := pubsub.New(1)
+    //~ brn := brain.New()
+    defer close(newlinequeue)
+    defer ps.Shutdown()
+    //~ defer brn.Shutdown()
     
        ticker := time.NewTicker(time.Duration(7) * time.Minute)
-       go readFromUSocket(presence_socket_path_, eventqueue)
+       go ReadFromUSocket(presence_socket_path_, newlinequeue)
+    go EventToWeb(ps)
+    go EventToXMPP(ps, xmpp_presence_events_chan_)
        for {
                select {
-               case e := <-eventqueue:
-                       parseSocketInputLine(e)
+               case e := <-newlinequeue:
+                       ParseSocketInputLine(e, ps) //, brn)
                case <-ticker.C:
-                       publishStateToWeb()
+                       ps.Pub(TimeTick{time.Now().Unix()}, "publishjson")
                }
        }
 }
-
-/* TODO:
-* Read config from an .ini file
- */
index 5e2523f..35e93e5 100644 (file)
@@ -1,4 +1,6 @@
 #!/bin/zsh
-go-linux-386 build -ldflags "-s -d"
-strip ${PWD:t}
+go-linux-386 clean
+#go-linux-386 build
+#strip ${PWD:t}
+go-linux-386 build -ldflags "-s"
 rsync -v ${PWD:t} wuzzler.realraum.at:/flash/tuer/
\ No newline at end of file
index 465ee95..b73445b 100644 (file)
@@ -71,10 +71,12 @@ type JabberEvent struct {
     Wants    R3JIDDesire
 }
 
-type PresenceEvent struct {
+type XMPPPresenceEvent struct {
     Present bool
+    Who string
     DoorLock bool
-    DoorAjar bool
+    DoorShut bool
+    Button bool
 }
 
 type RealraumXmppNotifierConfig map[string]JidData
@@ -135,7 +137,6 @@ func init() {
 
 func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presence_events <- chan interface{}, jabber_events <- chan JabberEvent) {
     var msg, presence_str, lock_str, ajar_str string
-    last_presence := false
     var debug_msg bool
     
        for {
@@ -148,7 +149,8 @@ func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presenc
                     continue
                 case string:
                     msg = pec
-                case PresenceEvent:
+                    debug_msg = true
+                case XMPPPresenceEvent:
                     if pec.Present {
                         presence_str = "Somebody is present !"
                     } else {
@@ -159,16 +161,15 @@ func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presenc
                     } else {
                         lock_str = "unlocked"
                     }
-                    if pec.DoorAjar {
-                        ajar_str = "ajar"
-                    } else {
+                    if pec.DoorShut {
                         ajar_str = "shut"
+                    } else {
+                        ajar_str = "ajar"
                     }
-                    msg = fmt.Sprintf("%s (Door is %s and %s)", presence_str, lock_str, ajar_str)
-                    if last_presence == pec.Present {
-                        debug_msg = true
+                    if pec.Button {
+                        msg = "The button has been pressed ! Propably someone is bored and need company ! ;-)"
                     } else {
-                        last_presence = pec.Present
+                        msg = fmt.Sprintf("%s (Door is %s and %s and was last used by %s)", presence_str, lock_str, ajar_str, pec.Who)
                     }
                 default:
                     break
@@ -180,9 +181,7 @@ func (botdata *XmppBot) handleEventsforXMPP(xmppout chan <- xmpp.Stanza, presenc
                     }
                     if (jiddata.Wants == R3NoOfflineInfo && jiddata.Online) || jiddata.Wants > R3NoOfflineInfo {
                         xmppout <-  botdata.makeXMPPMessage(to, msg, nil)
-                    }  //else  {
-                        //~ fmt.Println("Not sending to ", to, jiddata)
-                    //~ }
+                    }
                 }
                 
                case je := <-jabber_events:
@@ -242,6 +241,8 @@ func (botdata *XmppBot) handleIncomingMessageDialog(inmsg xmpp.Message, xmppout
             case "bye", "Bye", "quit", "logout":
                 botdata.jid_lastauthtime_[inmsg.GetHeader().From] = 0
                 xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Bye Bye !" ,nil)
+            case "open","close":
+                xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, "Sorry, I can't operate the door for you." ,nil)
             default:
                 //~ auth_match = re_msg_auth_.FindStringSubmatch(inmsg.Body.Chardata)
                 xmppout <- botdata.makeXMPPMessage(inmsg.GetHeader().From, help_text_, "Available Commands")
@@ -282,9 +283,7 @@ func (botdata *XmppBot) handleIncomingXMPPStanzas(xmppin <- chan xmpp.Stanza, xm
     }
 }
 
-var default_state_save_dir_ string = "/flash/var/lib/r3netstatus/"
-
-func NewStartedBot(loginjid, loginpwd, password string, insecuretls bool) (*XmppBot, chan interface{}, error) {
+func NewStartedBot(loginjid, loginpwd, password, state_save_dir string, insecuretls bool) (*XmppBot, chan interface{}, error) {
     var err error
     botdata := new(XmppBot)
 
@@ -295,7 +294,7 @@ func NewStartedBot(loginjid, loginpwd, password string, insecuretls bool) (*Xmpp
     botdata.my_login_password_ = loginpwd
     botdata.auth_timeout_ = 1200
     
-    botdata.config_file_ = path.Join(default_state_save_dir_, "r3xmpp."+removeJIDResource(loginjid)+".json")
+    botdata.config_file_ = path.Join(state_save_dir, "r3xmpp."+removeJIDResource(loginjid)+".json")
     
     //~ log.Println(botdata.config_file_)
     
@@ -341,27 +340,3 @@ func (botdata *XmppBot) StopBot() {
         close(*botdata.presence_events_)
     }
 }
-
-//~ func main() {
-    //~ bot, presence_events, err := NewStartedBot("realrauminfo@realraum.at/Tuer", "d7ynC6Dg", "r3alraumOLGAXMPPInfos", true)
-    
-    //~ if err != nil {
-        //~ log.Println(err)
-        //~ os.Exit(1)    
-    //~ }
-    
-    //~ presence_events <- PresenceEvent{true, true, true}
-    //~ presence_events <- PresenceEvent{true, true, false}
-    //~ presence_events <- PresenceEvent{true, false, false}    
-    
-    //~ p := make([]byte, 1024)
-    //~ for
-    //~ {        
-        //~ nr, _ := os.Stdin.Read(p)
-        //~ if nr == 0 {
-            //~ break
-        //~ }
-    //~ }
-    
-    //~ bot.StopBot()
-//~ }
diff --git a/r3-netstatus/sockettoevent.go b/r3-netstatus/sockettoevent.go
new file mode 100644 (file)
index 0000000..7f0d20c
--- /dev/null
@@ -0,0 +1,123 @@
+package main
+
+import (
+    pubsub "github.com/tuxychandru/pubsub"
+    "regexp"
+    "strconv"
+    "bufio"
+    "time"
+    //~ "./brain"
+    "net"
+    )
+
+var (
+       re_presence_    *regexp.Regexp     = regexp.MustCompile("Presence: (yes|no)(?:, (opened|closed), (.+))?")
+       re_status_      *regexp.Regexp     = regexp.MustCompile("Status: (closed|opened), (opening|waiting|closing|idle), (ajar|shut).*")
+       re_command_      *regexp.Regexp     = regexp.MustCompile("(open|close|toggle) (Card |Phone )?([^ ]+) *")
+       re_button_      *regexp.Regexp     = regexp.MustCompile("PanicButton|button\\d?")
+       re_temp_        *regexp.Regexp     = regexp.MustCompile("temp0: (\\d+\\.\\d+)")
+       re_photo_       *regexp.Regexp     = regexp.MustCompile("photo0: (\\d+)")
+)
+
+
+type PresenceUpdate struct {
+    Present bool
+    Ts int64
+}
+
+type DoorStatusUpdate struct {
+    Locked bool
+    Shut bool
+    Ts int64
+}
+
+type DoorCommandEvent struct {
+    Command string
+    Using string
+    Who string
+    Ts int64
+}
+
+type ButtonPressUpdate struct {
+    Buttonindex int
+    Ts int64
+}
+
+type TempSensorUpdate struct {
+    Sensorindex int
+    Value float64
+    Ts int64
+}
+
+type IlluminationSensorUpdate struct {
+    Sensorindex int
+    Value int64
+    Ts int64
+}
+
+type TimeTick struct {
+    Ts int64
+}
+
+
+func ParseSocketInputLine(line string, ps *pubsub.PubSub) { //, brn *brain.Brain) {
+       match_presence := re_presence_.FindStringSubmatch(line)
+       match_status := re_status_.FindStringSubmatch(line)
+       match_command := re_command_.FindStringSubmatch(line)
+       match_button := re_button_.FindStringSubmatch(line)
+       match_temp := re_temp_.FindStringSubmatch(line)
+       match_photo := re_photo_.FindStringSubmatch(line)
+
+    var tidbit interface{}
+    ts := time.Now().Unix()
+       if match_presence != nil {
+        tidbit = PresenceUpdate{match_presence[1] == "yes", ts}
+        //~ brn.Oboite("presence", tidbit)
+        ps.Pub(tidbit, "presence")
+       } else if match_status != nil {
+        tidbit = DoorStatusUpdate{match_status[1] == "closed", match_status[3] == "shut", ts}
+        //~ brn.Oboite("door", tidbit)
+        ps.Pub(tidbit, "door")
+       } else if match_command != nil {
+        tidbit = DoorCommandEvent{match_status[1], match_status[2], match_status[3], ts}
+        //~ brn.Oboite("doorcmd", tidbit)
+        ps.Pub(tidbit, "door")
+       } else if match_button != nil {
+        //~ brn.Oboite("button0", ts)
+        ps.Pub(ButtonPressUpdate{0, ts}, "buttons")
+       } else if match_temp != nil {
+               newtemp, err := strconv.ParseFloat((match_temp[1]), 32)
+               if err == nil {
+            //~ brn.Oboite( "temp0", newtemp)
+            ps.Pub(TempSensorUpdate{0, newtemp, ts}, "sensors")
+               }
+       } else if match_photo != nil {
+               newphoto, err := strconv.ParseInt(match_photo[1], 10, 32)
+               if err == nil {
+            //~ brn.Oboite("photo0", newphoto)
+            ps.Pub(IlluminationSensorUpdate{0, newphoto, ts}, "sensors")
+               }
+       }
+}
+
+func ReadFromUSocket(path string, c chan string) {
+ReOpenSocket:
+       for {
+               presence_socket, err := net.Dial("unix", path)
+               if err != nil {
+                       //Waiting on Socket
+                       time.Sleep(5 * time.Second)
+                       continue ReOpenSocket
+               }
+               presence_reader := bufio.NewReader(presence_socket)
+               for {
+                       line, err := presence_reader.ReadString('\n')
+                       if err != nil {
+                               //Socket closed
+                               presence_socket.Close()
+                               continue ReOpenSocket
+                       }
+                       c <- line
+               }
+       }
+}
\ No newline at end of file
diff --git a/r3-netstatus/webstatus.go b/r3-netstatus/webstatus.go
new file mode 100644 (file)
index 0000000..40b9960
--- /dev/null
@@ -0,0 +1,95 @@
+package main
+
+import (
+    pubsub "github.com/tuxychandru/pubsub"
+    "./spaceapi"
+    "regexp"
+       "net/http"
+       "net/url"   
+    "log"
+    "time"
+    )
+
+
+type spaceState struct {
+       present           bool
+       buttonpress_until int64
+}
+
+var (
+       spaceapidata    spaceapi.SpaceInfo = spaceapi.NewSpaceInfo("realraum", "http://realraum.at", "http://realraum.at/logo-red_250x250.png", "http://realraum.at/logo-re_open_100x100.png", "http://realraum.at/logo-re_empty_100x100.png",47.065779129, 15.442322614).AddSpaceAddress("Jakoministr. 16 ground level left, 8010 Graz, Austria")
+       statusstate     *spaceState        = new(spaceState)
+       re_querystresc_ *regexp.Regexp     = regexp.MustCompile("[^\x30-\x39\x41-\x7E]")    
+)
+
+
+func init() {
+       spaceapidata.AddSpaceFeed("calendar", "http://grical.realraum.at/s/?query=!realraum&view=rss")
+       spaceapidata.AddSpaceFeed("blog", "https://plus.google.com/113737596421797426873")
+       spaceapidata.AddSpaceFeed("wiki", "http://realraum.at/wiki")
+       spaceapidata.AddSpaceContactInfo("+43780700888524", "irc://irc.oftc.net/#realraum", "realraum@realraum.at", "realraum@realraum.at", "realraum@realraum.at", "vorstand@realraum.at")
+}
+
+
+func updateStatusString() {
+       var spacestatus string
+       if statusstate.present {
+               if statusstate.buttonpress_until > time.Now().Unix() {
+                       spacestatus = "Panic! Present&Bored"
+               } else {
+                       spacestatus = "Leute Anwesend"
+               }
+       } else {
+               spacestatus = "Keiner Da"
+       }
+       spaceapidata.SetStatus(statusstate.present, spacestatus)
+}
+
+func publishStateToWeb() {
+       updateStatusString()
+       jsondata_b, err := spaceapidata.MakeJSON()
+       if err != nil {
+               log.Println("Error:", err)
+               return
+       }
+       //jsondata_b := re_querystresc_.ReplaceAllFunc(jsondata_b, func(in []byte) []byte {
+       //      out := make([]byte, 4)
+       //      out[0] = '%'
+       //      copy(out[1:], []byte(strconv.FormatInt(int64(in[0]), 16)))
+       //      return out
+       //})
+       jsondata := url.QueryEscape(string(jsondata_b))
+       resp, err := http.Get("http://www.realraum.at/cgi/status.cgi?pass=jako16&set=" + jsondata)
+       if err != nil {
+               log.Println("Error publishing realraum info", err)
+               return
+       }
+       resp.Body.Close()
+}
+
+func EventToWeb(ps *pubsub.PubSub) {
+    events := ps.Sub("presence","door","sensors","buttons","publishjson")
+
+    for eventinterface := range(events) {
+        switch event := eventinterface.(type) {
+            case TimeTick:
+                publishStateToWeb()
+            case PresenceUpdate:
+                statusstate.present = event.Present
+                publishStateToWeb()
+            case DoorStatusUpdate:
+                spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("TorwaechterLock", "Türschloß", event.Locked))
+                spaceapidata.MergeInSensor(spaceapi.MakeDoorLockSensor("TorwaechterAjarSensor", "Türkontakt", event.Shut))
+                publishStateToWeb()
+            case ButtonPressUpdate:
+                statusstate.buttonpress_until = event.Ts + 3600
+                spaceapidata.AddSpaceEvent("PanicButton", "check-in", "The button has been pressed")
+                publishStateToWeb()
+            case TempSensorUpdate:
+                spaceapidata.MergeInSensor(spaceapi.MakeTempCSensor("Temp0","Decke", event.Value))
+            case IlluminationSensorUpdate:
+                spaceapidata.MergeInSensor(spaceapi.MakeIlluminationSensor("Photodiode","Decke","1024V/5V", event.Value))
+        }
+       }
+}
+
index f90d2eb..d4cd7ff 100755 (executable)
@@ -9,24 +9,31 @@
 # Default-Stop:      0 1 6
 ### END INIT INFO
 
-EXE_UWEB=/flash/tuer/update-web-status.py
-EXE_XMPP=/flash/tuer/update-xmpp-status.py
-
-CFG_UWEB=/flash/tuer/update-web-status.cfg
-CFG_XMPP=/flash/tuer/update-xmpp-status.cfg
+EXE_UWEB=/flash/tuer/r3-netstatus
+STATE_DIR=/flash/var/lib/r3netstatus/
+CFG_UWEB=""
 
 . /etc/default/tuer
 
-PIDFILE_UWEB=${DIR_RUN}/update-web-status.pid
-PIDFILE_XMPP=${DIR_RUN}/update-xmpp-status.pid
+[ -n "$XMPPJID" ] && CFG_UWEB="$CFG_UWEB --xjid $XMPPJID"
+[ -n "$XMPPPASS" ] && CFG_UWEB="$CFG_UWEB --xpass $XMPPPASS"
+[ -n "$XMPPBOTAUTH" ] && CFG_UWEB="$CFG_UWEB --xbotauth $XMPPBOTAUTH"
+[ -n "$PRESENCE_SOCKET" ] && CFG_UWEB="$CFG_UWEB --presencesocket $PRESENCE_SOCKET"
+
+
+PIDFILE_UWEB=${DIR_RUN}/r3-netstatus.pid
 
 test -f $EXE_UWEB  || exit 1
-test -f $EXE_XMPP  || exit 1
 if [ ! -d $DIR_RUN ]; then
        mkdir -p $DIR_RUN || exit 2
        chown -R $DOOR_USR:$DOOR_GRP $DIR_RUN
 fi
 
+if [ ! -d $STATE_DIR ]; then
+       mkdir -p $STATE_DIR || exit 2
+       chown -R $DOOR_USR:$DOOR_GRP $STATE_DIR
+fi
+
 . /lib/lsb/init-functions
 
 # Read the system's locale and set cron's locale. This locale
@@ -38,17 +45,11 @@ start)
        log_daemon_msg "Starting door daemon" "update-web-status"
         start-stop-daemon --start --quiet --pidfile $PIDFILE_UWEB -b -m -c $DOOR_USR --startas $EXE_UWEB  -- $CFG_UWEB
         log_end_msg $? 
-       log_daemon_msg "Starting door daemon" "update-xmpp-status"
-        start-stop-daemon --start --quiet --pidfile $PIDFILE_XMPP -b -m -c $DOOR_USR --startas $EXE_XMPP  -- $CFG_XMPP
-        log_end_msg $? 
        ;;
 stop)
        log_daemon_msg "Stopping door daemon" "update-web-status"
         start-stop-daemon --stop --quiet --pidfile $PIDFILE_UWEB -m --retry TERM/1/TERM/1/KILL 
         log_end_msg $? 
-       log_daemon_msg "Stopping door daemon" "update-xmpp-status"
-        start-stop-daemon --stop --quiet --pidfile $PIDFILE_XMPP -m --retry TERM/1/TERM/1/KILL 
-        log_end_msg $? 
         ;;
 restart) 
        $0 stop