1) Поддержка сигнализации на 433МГц.
[weathermon.git] / weathermon.lua
1 #!/usr/bin/lua
2
3 function getConfig()
4
5   local uci=require("uci")
6   local cur=uci.cursor()
7   local config="weathermon"
8
9   web_url  = cur.get(config,"web","url")
10   web_user = cur.get(config,"web","user")
11   web_pass = cur.get(config,"web","password")
12   web_devid = cur.get(config,"web","devid")
13
14   web_iface = cur.get(config,"web","iface")
15
16   if web_iface then
17   
18     command = '/sbin/ifconfig '..web_iface..' | grep \'\\<inet\\>\' | sed -n \'1p\' | tr -s \' \' | cut -d \' \' -f3 | cut -d \':\' -f2'
19     f=io.popen(command,'r')
20     ip_addr=f:read()
21   
22   end
23
24   if not web_devid then
25   
26     if web_iface then
27       io.input("/sys/class/net/"..web_iface.."/address")
28     else
29       io.input("/sys/class/net/eth0/address")
30     end
31
32     mac = io.read("*line")
33     mac = mac:gsub(":","")
34     mac = mac:upper()
35
36     web_devid = mac
37
38   end
39
40   logging = cur.get(config,"logging","enabled") 
41
42   serial_port = cur.get(config,"serial","port")
43   serial_baud = cur.get(config,"serial","baud")
44
45   input_file = cur.get(config,"input","file")
46   input_exec = cur.get(config,"input","exec")
47   alarm_exec = cur.get(config,"alarm","exec")
48
49   if serial_port then
50
51     command = "stty -F  "..serial_port.." "..serial_baud
52     os.execute(command)
53
54   end
55
56   mqtt_host = cur.get(config,"mqtt","host")
57   mqtt_port = cur.get(config,"mqtt","port")
58   mqtt_id = cur.get(config,"mqtt","id")
59   mqtt_topic = cur.get(config,"mqtt","topic")
60   mqtt_alarm_topic = cur.get(config,"mqtt","alarm_topic")
61
62   if mqtt_host and not mqtt_id then
63     mqtt_id="weather-"..web_devid
64   end
65
66   if mqtt_host and not mqtt_port then
67     mqtt_port = 1883
68   end
69
70   if mqtt_host and not mqtt_topic then
71     mqtt_topic = 'weathermon/'..web_devid
72   end
73
74   if mqtt_host and not mqtt_alarm_topic then
75     mqtt_alarm_topic = 'alarm/'..web_devid
76   end
77
78 end
79
80 require "socket"
81
82 function sleep(sec)
83   socket.select(nil, nil, sec)
84 end
85
86 function splitStr(str,char)
87
88   local res = {}
89   local idx = 1
90
91
92   while str:len()>0 do
93     pos = str:find(char); 
94     if pos == nil then
95       res[idx]=str
96       str=""
97     else
98       res[idx]=str:sub(1,pos-1)
99       idx=idx+1
100       str=str:sub(pos+1)
101     end
102   end
103
104   return res
105
106 end
107
108 function printLog(str)
109   print(str)
110   if logging=="on" then
111     os.execute("logger -t weathermon "..str)
112   end 
113 end
114
115 function submitValue(type,id,param,val)
116
117   url = web_url.."?stype="..type.."&sid="..id.."&param="..param.."&value="..val
118
119   command = "curl"
120
121   if web_iface then
122     command = command.." --interface "..ip_addr
123   end
124
125   if web_user then
126     command = command.." -u "..web_user..":"..web_pass
127   end
128
129   command = command.." \""..url.."\""
130
131   os.execute(command)
132
133 end
134
135 function processLine(str)
136
137   msg=splitStr(line,':')
138   msg_type=msg[1] or nil
139   msg_body=msg[2] or nil
140   if msg_type=="STATUS" then
141     printLog("Status: "..msg_body)
142   elseif msg_type=="ERROR" then
143     printLog("Error: "..msg_body)  
144   elseif msg_type=="SENSOR" then
145     printLog("SENSOR: "..msg_body)  
146     sens = splitStr(msg_body,",")
147     sensor = {}
148     idx = 1
149     sensor_type = nil
150     sensor_id = web_devid
151     for i,rec in ipairs(sens) do
152       recrd=splitStr(rec,'=')
153       key=recrd[1] or nil
154       value=recrd[2] or nil
155       if value then
156         if key=="TYPE" then
157           sensor_type=value
158         elseif key=="ID" then
159           sensor_id=value
160         else
161           sensor[key]=value
162         end
163       end
164     end
165     mqtt_param = {}
166     for k,v in pairs(sensor) do
167       printLog("Type = "..sensor_type..", ID = "..sensor_id..", Param = "..k..", Value = "..v)
168       submitValue(sensor_type,sensor_id,k,v)
169       mqtt_param[k]=v
170     end
171     mqtt_msg = { type=sensor_type, id=sensor_id, data=mqtt_param }
172     if mqtt_client then
173       serializedString = json.encode(mqtt_msg)
174       mqtt_client:publish(mqtt_topic,serializedString)
175     end
176   elseif msg_type=="ALARM" then
177     printLog("ALARM: "..msg_body)  
178     sens = splitStr(msg_body,",")
179     sensor = {}
180     idx = 1
181     sensor_type = nil
182     sensor_id = web_devid
183     mqtt_param = {}
184     for i,rec in ipairs(sens) do
185       recrd=splitStr(rec,'=')
186       key=recrd[1] or nil
187       value=recrd[2] or nil
188       if value then
189         if key=="TYPE" then
190           alarm_type=value
191         elseif key=="ID" then
192           alarm_id=value
193         else
194           mqtt_param[key]=value
195         end
196       end
197     end
198     if mqtt_client then
199       mqtt_msg = { type = alarm_type, id = alarm_id, data = mqtt_param }
200       serializedString = json.encode(mqtt_msg)
201       mqtt_client:publish(mqtt_alarm_topic,serializedString)
202     end
203     if alarm_exec then
204       command=alarm_exec..
205         " \""..string.gsub(alarm_type,"\"","\\\"")..
206         "\" \""..string.gsub(alarm_id,"\"","\\\"")..
207         "\" \""..string.gsub(msg_body,"\"","\\\"").."\""
208       os.execute(command)
209     end
210   end
211
212 end
213
214 getConfig()
215
216 if mqtt_host then
217   MQTT = require "paho.mqtt"
218   mqtt_client = MQTT.client.create(mqtt_host, mqtt_port)
219   mqtt_client:connect(mqtt_id)
220   json = require( "json" )
221 end
222
223 if serial_port then
224   serialin=io.open(serial_port,"r")
225 elseif input_file == "-" then
226   serialin=io.stdin;
227 elseif input_file then
228   serialin=io.open(input_file,"r")
229 elseif input_exec then
230   serialin=io.popen(input_exec,"r")
231 else
232   printLog("No input selected")
233   return
234 end  
235 while 1 do
236   line=serialin:read()
237   print(line)
238   processLine(line)
239 end