more cosmetic changes
[svn42.git] / r3-webstatus-spaceapi / spaceapi / spaceapi.go
1 // spaceapi.go
2 package spaceapi
3
4 import (
5         "encoding/json"
6         "time"
7 )
8
9 const max_num_events int = 4
10
11 type SpaceInfo map[string]interface{}
12
13 type SpaceDoorLockSensor struct {
14         value       bool
15     location    string
16     name        string
17     description string
18 }
19
20 type SpaceDoorAjarSensor struct {
21         value       bool
22     location    string
23     name        string
24     description string
25 }
26
27 func MakeTempSensor(name, where, unit string, value float64) SpaceInfo {
28     listofwhats := make([]SpaceInfo, 1)
29     listofwhats[0] = SpaceInfo{
30                 "value":    value,
31                 "unit":     unit,
32                 "location": where,
33                 "name":     name,
34                 "description": ""}
35     return SpaceInfo{"temperature": listofwhats}
36 }
37
38 func MakeTempCSensor(name, where string, value float64) SpaceInfo {
39     return MakeTempSensor(name,where,"\u00b0C",value)
40 }
41
42 func MakeIlluminationSensor(name, where, unit string, value int64) SpaceInfo {
43     listofwhats := make([]SpaceInfo, 1)
44     listofwhats[0] = SpaceInfo{
45                 "value":    value,
46                 "unit":     unit,
47                 "location": where,
48                 "name":     name,
49                 "description": ""}
50     return SpaceInfo{"ext_illumination": listofwhats}
51 }
52
53 func MakePowerConsumptionSensor(name, where, unit string, value int64) SpaceInfo {
54     listofwhats := make([]SpaceInfo, 1)
55     listofwhats[0] = SpaceInfo{
56                 "value":    value,
57                 "unit":     unit,
58                 "location": where,
59                 "name":     name,
60                 "description": ""}
61     return SpaceInfo{"power_consumption": listofwhats}
62 }
63
64 func MakeNetworkConnectionsSensor(name, where, nettype string, value, machines int64) SpaceInfo {
65     listofwhats := make([]SpaceInfo, 1)
66     listofwhats[0] = SpaceInfo{
67                 "value":    value,
68         "type":     nettype,
69         "machines": machines,
70                 "location": where,
71                 "name":     name,
72                 "description": ""}
73     return SpaceInfo{"network_connections": listofwhats}
74 }
75
76 func MakeMemberCountSensor(name, where string, value int64) SpaceInfo {
77     listofwhats := make([]SpaceInfo, 1)
78     listofwhats[0] = SpaceInfo{
79                 "value":    value,
80                 "location": where,
81                 "name":     name,
82                 "description": ""}
83     return SpaceInfo{"total_member_count": listofwhats}
84 }
85
86 func MakeDoorLockSensor(name, where string, value bool) SpaceInfo {
87     listofwhats := make([]SpaceInfo, 1)
88     listofwhats[0] = SpaceInfo{
89                 "value":    value,
90                 "location": where,
91                 "name":     name,
92                 "description": ""}
93     return SpaceInfo{"door_locked": listofwhats}
94 }
95
96 func MakeDoorAjarSensor(name, where string, value bool) SpaceInfo {
97     listofwhats := make([]SpaceInfo, 1)
98     listofwhats[0] = SpaceInfo{
99                 "value":    value,
100                 "location": where,
101                 "name":     name,
102                 "description": ""}
103     return SpaceInfo{"ext_door_ajar": listofwhats}
104 }
105
106 func (nsi SpaceInfo) MergeInSensor(sensorinfo SpaceInfo) {
107     if nsi["sensors"] == nil {
108         nsi["sensors"] = SpaceInfo{}
109         //~ listofwhats := make([]SpaceInfo, 1)
110         //~ listofwhats[0] = sensortype.(SpaceInfo)
111                 //~ sensorobj := SpaceInfo{what: listofwhats}
112                 //~ nsi["sensors"] = sensorobj
113         }
114     sensorobj := nsi["sensors"].(SpaceInfo)
115     for what, subsensorobjlist := range sensorinfo {
116         if sensorobj[what] == nil {
117             sensorobj[what] = subsensorobjlist
118         } else {
119             existingsensorobjslist := sensorobj[what].([]SpaceInfo)
120             for _, newsensorobj := range subsensorobjlist.([]SpaceInfo) {
121                 foundandsubstituted := false
122                 for i:=0; i< len(existingsensorobjslist); i++ {
123                     if existingsensorobjslist[i]["name"] == newsensorobj["name"] {
124                         existingsensorobjslist[i] = newsensorobj
125                         foundandsubstituted = true
126                     }
127                 }
128                 if foundandsubstituted == false {
129                     sensorobj[what] = append(sensorobj[what].([]SpaceInfo), newsensorobj)
130                     //note that we do not change existingsensorobjslist here but directly sensorobj[what] !!
131                     //the implications being that, if we have several newsensorobj in the list:
132                     //  a) optimisation: we only check them against the existing ones and spare ourselves the work of checking a newsensorobj's name against a just added other newsensorobjs's name
133                     //  b) if the array sensorinfo[what] has several objects with the same name, nsi["sensors"] will also end up with these name conflicts
134                 }
135             }
136         }
137     }
138 }
139
140 func (nsi SpaceInfo) AddSpaceContactInfo(phone, irc, email, ml, jabber, issuemail string) SpaceInfo {
141         nsi["contact"] = SpaceInfo{
142                 "phone":  phone,
143                 "email":  email,
144                 "ml":     ml,
145                 "jabber": jabber,
146         "issue_mail": issuemail}
147     nsi["issue_report_channels"] = [3]string{"issue_mail","email","ml"}
148         return nsi
149 }
150
151 func (nsi SpaceInfo) AddSpaceFeed(feedtype, url string) SpaceInfo {
152         newfeed := SpaceInfo{"url": url}
153         if nsi["feeds"] == nil {
154         nsi["feeds"] = SpaceInfo{feedtype: newfeed}
155         } else {
156                 feedobj, ok := nsi["feeds"].(SpaceInfo) //type assertion (panics if false)
157                 if ok {
158             feedobj[feedtype] = newfeed
159                 } else {
160                         panic("Wrong Type of feedobj: Should never happen")
161                 }
162         }
163         return nsi
164 }
165
166 func (nsi SpaceInfo) AddSpaceEvent(name, eventtype, extra string) SpaceInfo {
167         newevent := SpaceInfo{"name": name, "type": eventtype, "timestamp": time.Now().Unix(), "extra": extra}
168         if nsi["events"] == nil {
169                 eventlist := make([]SpaceInfo, 1)
170                 eventlist[0] = newevent
171                 nsi["events"] = eventlist
172         } else {
173                 eventlist, ok := nsi["events"].([]SpaceInfo) //type assertion
174                 if ok {
175                         if len(eventlist) >= max_num_events {
176                                 eventlist = eventlist[1:]
177                         }
178                         nsi["events"] = append(eventlist, newevent)
179                 } else {
180                         panic("Wrong Type of eventlist: Should never happen")
181                 }
182         }
183         return nsi
184 }
185
186 func (nsi SpaceInfo) AddSpaceAddress(address string) SpaceInfo {
187         nsi["address"] = address
188     if nsi["location"] != nil {
189         location, ok := nsi["location"].(SpaceInfo)
190         if ok {
191             location["address"] = address
192         }
193     }
194         return nsi
195 }
196
197 func (nsi SpaceInfo) SetStatus(open bool, status string) {
198         nsi["status"] = status
199         nsi["open"] = open
200         nsi["lastchange"] = time.Now().Unix()
201     state, ok := nsi["state"].(SpaceInfo)
202     if ok {
203         state["message"] = status
204         state["open"] = open
205         state["lastchange"] = nsi["lastchange"]
206     }
207 }
208
209 func NewSpaceInfo(space string, url string, logo string, open_icon string, closed_icon string, lat float64, lon float64) SpaceInfo {
210         nsi := map[string]interface{}{
211                 "api":        "0.13",
212                 "space":      space,
213                 "url":        url,
214                 "logo":       logo,
215                 "open":       false,
216                 "lastchange": time.Now().Unix(),
217                 "icon":       SpaceInfo{
218             "open":     open_icon,
219             "closed":   closed_icon,
220         },
221         "state":       SpaceInfo{
222             "open":      false,
223             "lastchange":time.Now().Unix(),
224             "icon":     SpaceInfo{
225                 "open":     open_icon,
226                 "closed":   closed_icon},
227             },
228         "location":   SpaceInfo{
229             "lat":      lat,
230             "lon":      lon},
231         "contact" :   SpaceInfo {},
232     }
233         return nsi
234 }
235
236 func (data SpaceInfo) MakeJSON() ([]byte, error) {
237         msg, err := json.Marshal(data)
238         if err == nil {
239                 return msg, nil
240         }
241         return nil, err
242 }