├── .gitignore
├── README.md
├── beidou
└── beidou.py
├── document
├── README.md
├── 作品说明书.docx
├── 创业计划书.docx
├── 基于物联网技术大气环境监测三维可视化的智能终端系统.zip
└── 空气监测报警系统.pptx
├── machinelearning
├── data.dat
├── demo
│ ├── demo1.py
│ ├── demo2.py
│ ├── foo.txt
│ ├── regression.py
│ └── workfile
└── getAirElement.py
├── sensor
├── arduino
│ ├── README.md
│ ├── sensor
│ │ └── sensor.ino
│ └── sensor_old
│ │ └── sensor_old.ino
├── hardware
│ └── FWB.ms14
└── raspberrypi
│ ├── GPIO.jpg
│ ├── README.md
│ ├── color.py
│ ├── dashboard.py
│ ├── sensor.py
│ ├── sensor_api.py
│ ├── sensor_api_old.py
│ ├── sensor_backup.py
│ ├── sensor_old.py
│ ├── shell.py
│ ├── test.py
│ ├── test1.py
│ ├── test_pygame.py
│ ├── test_tkinter.py
│ ├── wts11.ttf
│ ├── yeelink_api.py
│ ├── yeelink_config.py
│ ├── 仪表盘.png
│ ├── 仪表盘1.jpg
│ ├── 仪表盘2.jpg
│ └── 界面_0.png
├── server
└── weixin
│ ├── access_token.dat
│ ├── can_scanf
│ ├── index.php
│ ├── index_bak.php
│ ├── menu.php
│ ├── output_sqlite.sql
│ ├── sqlite
│ ├── sqlitedb.db
│ ├── sqlitedb_backup.db
│ ├── sqlitedb_bak1.db
│ ├── test.php
│ ├── test2.php
│ ├── test3.php
│ ├── test4.php
│ ├── test5.php
│ └── warningtemplate.php
└── sg90.py
/.gitignore:
--------------------------------------------------------------------------------
1 | *.xml
2 | *.pyc
3 | .idea/
4 | *.ms14 (Security copy)
5 | .vs/
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # air_monitor
2 |
3 |
4 |
--------------------------------------------------------------------------------
/beidou/beidou.py:
--------------------------------------------------------------------------------
1 | import serial
2 | import time
3 |
4 |
5 | # import _thread
6 | # from XOR_CheckSum import XOR_CheckSum_string
7 |
8 |
9 | def XOR_CheckSum_string(m_str, encoding="utf-8"):
10 | if str == type(m_str):
11 | try:
12 | m_str = bytes(m_str, encoding=encoding)
13 | except:
14 | # m_str = bytes(m_str)
15 | m_str = m_str.encode(encoding=encoding)
16 | sum = 0x0
17 | # print(m_str)
18 | # print(type(m_str))
19 | for c in m_str:
20 | try:
21 | sum = sum ^ c
22 | except:
23 | # print(c)
24 | sum = sum ^ ord(c)
25 | sum = sum ^ 0x0
26 | return sum
27 |
28 |
29 | def read_serial(serial, transfer_method=2, encoding="gb2312"):
30 | while True:
31 | line = serial.readline()
32 | print(line)
33 |
34 | if line[3:6] == b'TXR':
35 | tmp = line.split(b',')[-1]
36 | msg = tmp.split(b'*')[0]
37 | if transfer_method == '2' and msg[0:2] == b'A4':
38 | msg = msg[1:]
39 | try:
40 | # print("Receive message:",str(msg,encoding='utf-8'))
41 | print("Receive message:", msg.decode(encoding))
42 | except:
43 | print("Receive message:", str(msg))
44 |
45 |
46 | class TXA:
47 | def __init__(self, user_address, serial, sender_identifier='CC', communication_category='1', transfer_method='2',
48 | encoding="gb2312"):
49 | self.sender_identifier = sender_identifier
50 | self.user_address = user_address
51 | self.communication_category = communication_category
52 | self.transfer_method = transfer_method
53 | self.serial = serial
54 | self.encoding = encoding
55 |
56 | def message(self, content, address='', encoding=''):
57 | if address == '':
58 | address = self.user_address
59 | if encoding == '':
60 | encoding = self.encoding
61 |
62 | message_temp = self.sender_identifier + 'TXA' + ',' + \
63 | address + ',' + \
64 | self.communication_category + ',' + \
65 | self.transfer_method + ','
66 | message=bytes(message_temp,encoding)
67 | #if self.transfer_method=='2':
68 | # message=message+b'\xA4'
69 | message=message+bytes(content,encoding)
70 | #if self.transfer_method == 2:
71 | # message = 'A4' + message
72 | self.xor_checkSum = hex(XOR_CheckSum_string(message, encoding=encoding))[2:4]
73 | message = bytes('$',encoding) + message + bytes('*',encoding) + bytes(self.xor_checkSum,encoding) + bytes('\r\n',encoding)
74 | '''try:
75 | reslut = bytes(message, encoding=encoding)
76 | except:
77 | reslut = bytes(message)'''
78 |
79 | '''if self.transfer_method == 2:#'''
80 | # '''reslut = b'\xA4' + reslut'''
81 |
82 | #return reslut
83 | return message
84 |
85 | def send(self, message):
86 | self.serial.write(message)
87 |
88 | def read(self):
89 | try:
90 | import _thread
91 | _thread.start_new_thread(read_serial, (self.serial, self.transfer_method, self.encoding,))
92 | except:
93 | import thread
94 | thread.start_new_thread(read_serial, (self.serial, self.transfer_method, self.encoding,))
95 |
96 |
97 | def test():
98 | ser = serial.Serial('/dev/ttyUSB1', 115200)
99 | print(ser)
100 | _thread.start_new_thread(read_serial, (ser,))
101 | for i in range(5):
102 | # ser.write(b'$CCICA,0,00*7B\r\n')
103 | ser.write(b'$CCICI,0,00*73\r\n')
104 | # line = ser.readline()
105 | # print(line)
106 | time.sleep(1)
107 |
108 | for i in range(100):
109 | ser.write(b'$CCTXA,0247718,1,1,3132333435*70\r\n')
110 | time.sleep(80)
111 |
112 | ser.close()
113 |
114 |
115 | if __name__ == "__main__":
116 | '''print(hex(XOR_CheckSum_string('CCICA,0,00')))
117 | print(hex(XOR_CheckSum_string('CCICI,0,00')))
118 | print(hex(XOR_CheckSum_string('CCTXA,0247718,1,1,3132333435')))
119 |
120 | print(hex(XOR_CheckSum_string(b'CCICA,0,00')))
121 | print(hex(XOR_CheckSum_string(b'CCICI,0,00')))
122 | print(hex(XOR_CheckSum_string(b'CCTXA,0247718,1,1,3132333435')))
123 |
124 | print(hex(XOR_CheckSum_string(bytes('CCICA,0,00', encoding="utf-8"))))
125 | print(hex(XOR_CheckSum_string(bytes('CCICI,0,00', encoding="utf-8"))))
126 | print(hex(XOR_CheckSum_string(bytes('CCTXA,0247718,1,1,3132333435', encoding="utf-8"))))'''
127 |
128 | ser = serial.Serial('/dev/ttyUSB1', 115200)
129 | txa = TXA(user_address='0247718', serial=ser, transfer_method='2',encoding='gb2312')
130 | txa.read()
131 |
132 | '''test_msg=b'$CCTXA,0242407,1,2,A4B9E3D6DDBAA3C1C4BFC6BCBCD3D0CFDEB9ABCBBE*0F'
133 | print(test_msg)
134 | txa.send(message=test_msg)
135 | time.sleep(60)'''
136 |
137 | message = txa.message(content='3132333435')
138 | print(message)
139 | txa.send(message=message)
140 | time.sleep(60)
141 |
142 | message = txa.message(content='-3-132333435')
143 | print(message)
144 | txa.send(message=message)
145 | time.sleep(60)
146 |
147 | message = txa.message(content='-3--132333435')
148 | print(message)
149 | txa.send(message=message)
150 | time.sleep(60)
151 |
152 | message = txa.message(content='.3.132333435')
153 | print(message)
154 | txa.send(message=message)
155 | time.sleep(60)
156 |
157 | message = txa.message(content='.3..132333435')
158 | print(message)
159 | txa.send(message=message)
160 | time.sleep(60)
161 |
162 | message = txa.message(content='.-3.-13.2333435')
163 | print(message)
164 | txa.send(message=message)
165 | time.sleep(60)
166 |
167 | message = txa.message(content='.-3..--13.2333435')
168 | print(message)
169 | txa.send(message=message)
170 | time.sleep(60)
171 |
172 | message = txa.message(content='广州海聊科技..有限公--司12就3a给bc.-PM2.5-1.0CO-3.57')
173 | print(message)
174 | txa.send(message=message)
175 | time.sleep(60)
176 |
177 | # test()
178 | 8
179 |
--------------------------------------------------------------------------------
/document/README.md:
--------------------------------------------------------------------------------
1 | 以后添加子树时,要选择实目录
2 | 即目录中有文件的,最好在提交一下,可以不推送
3 | 否则光是一个空目录,git是不认为那里有目录的,就会各种找不到文件,很麻烦
4 |
--------------------------------------------------------------------------------
/document/作品说明书.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/document/作品说明书.docx
--------------------------------------------------------------------------------
/document/创业计划书.docx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/document/创业计划书.docx
--------------------------------------------------------------------------------
/document/基于物联网技术大气环境监测三维可视化的智能终端系统.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/document/基于物联网技术大气环境监测三维可视化的智能终端系统.zip
--------------------------------------------------------------------------------
/document/空气监测报警系统.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/document/空气监测报警系统.pptx
--------------------------------------------------------------------------------
/machinelearning/data.dat:
--------------------------------------------------------------------------------
1 | b'{"error":"You need to sign in or sign up before continuing."}'
2 |
--------------------------------------------------------------------------------
/machinelearning/demo/demo1.py:
--------------------------------------------------------------------------------
1 | import math
2 |
3 |
4 | def func(i, j):
5 | return 0.0015 * i - 0.99 * j + i / (i + j)
6 |
7 |
8 | num_node = 20
9 | with open('foo.txt', 'w') as f:
10 | for i in range(1, num_node):
11 | for j in range(1, num_node):
12 | ii = i * 1.0 / num_node
13 | jj = j * 1.0 / num_node
14 | print(ii, jj, func(ii, jj))
15 | print(ii, jj, func(ii, jj), file=f)
16 |
--------------------------------------------------------------------------------
/machinelearning/demo/demo2.py:
--------------------------------------------------------------------------------
1 | import regression
2 | from numpy import *
3 | import matplotlib.pyplot as plt
4 |
5 |
6 | def best_k(xArr, yArr):
7 | k_small = 0.01
8 | k_big = 2.0
9 | k = (k_big + k_small) / 2.0
10 | while True:
11 | yHat = regression.lwlrTest(xArr, xArr, yArr, k)
12 | yHat_small = regression.lwlrTest(xArr, xArr, yArr, k_small)
13 | yHat_big = regression.lwlrTest(xArr, xArr, yArr, k_big)
14 | re = regression.rssError(yArr, yHat)
15 | re_small = regression.rssError(yArr, yHat_small)
16 | re_big = regression.rssError(yArr, yHat_big)
17 | if re_small > re and re_big > re:
18 | k_big = k + (k_big - k) / 2.0
19 | k_small = k_small + (k - k_small) / 2.0
20 | elif re_small > re and re_big < re:
21 | k_small = k
22 | k = (k_big + k_small) / 2.0
23 | elif re_small < re and re_big > re:
24 | k_big = k
25 | k = (k_big + k_small) / 2.0
26 | else:
27 | k_big = k + (k_big - k) / 2.0
28 | k_small = k_small + (k - k_small) / 2.0
29 | if k_big - k_small < 0.01:
30 | k = k_small
31 | break
32 | return k
33 |
34 |
35 | start_count = 10
36 | sum_rate = 0.0
37 | count = 0
38 |
39 | mothed = 1
40 | if mothed == 0:
41 | xArr, yArr = regression.loadDataSet("foo.txt")
42 | k = best_k(xArr, yArr)
43 | yHat = regression.lwlrTest(xArr, xArr, yArr, k)
44 | print(k)
45 | else:
46 | xArr_origin, yArr_origin = regression.loadDataSet("foo.txt")
47 | # print(yArr_origin)
48 | xArr = []
49 | yArr = []
50 | m = (shape(xArr_origin))[0]
51 | yHat = zeros(m)
52 |
53 | xArr.append(xArr_origin[0][:])
54 | yArr.append(yArr_origin[0])
55 | yHat[0] = yArr_origin[0]
56 |
57 | for i in range(1, m):
58 | # k = best_k(xArr, yArr)
59 | k = 0.06830078125
60 | x = xArr_origin[i][:]
61 | y = regression.lwlr(x, xArr, yArr, k)
62 | # print(y.flatten().A[0][0])
63 | yHat[i] = y.flatten().A[0][0]
64 | while yHat[i] <= 0:
65 | k = k + 0.01
66 | y = regression.lwlr(x, xArr, yArr, k)
67 | yHat[i] = y.flatten().A[0][0]
68 | xArr.append(x)
69 | yArr.append(yArr_origin[i])
70 | print(i, k, yHat[i], yArr[i])
71 | with open('workfile', 'a') as f:
72 | f.write(str(i))
73 | f.write("\t")
74 | f.write(str(k))
75 | f.write("\t")
76 | f.write(str(yHat[i]))
77 | f.write("\t")
78 | f.write(str(yArr[i]))
79 | f.write("\t")
80 | rate = (yHat[i] * 1.0 - yArr[i] * 1.0) ** 2 / yArr[i]
81 | f.write(str(rate))
82 | f.write("\n")
83 | if i > sum_rate:
84 | sum_rate += rate
85 | count += 1
86 | # print(yArr) # k = best_k(xArr, yArr)
87 | # yHat = regression.lwlrTest(xArr, xArr, yArr, k)
88 | # print(yHat)
89 | # print(regression.rssError(yArr, yHat))
90 | print(sum_rate * 1.0 / count)
91 | # print(yArr)
92 | # print(yHat)
93 | xMat = mat(xArr)
94 | srtInd = xMat[:, 0].argsort(0)
95 | # print(srtInd)
96 | # print(yHat[srtInd])
97 | xSort = xMat[srtInd][:, 0, :]
98 | fig = plt.figure()
99 | ax = fig.add_subplot(111)
100 | ax.plot(xSort[:, 0], yHat[srtInd])
101 | ax.scatter(xMat[:, 0].flatten().A[0], mat(yArr).T.flatten().A[0], s=2, c="red")
102 | plt.show()
103 |
--------------------------------------------------------------------------------
/machinelearning/demo/foo.txt:
--------------------------------------------------------------------------------
1 | 1 41
2 | 2 41
3 | 3 42
4 | 4 46
5 | 5 43
6 | 6 42
7 | 7 42
8 | 8 42
9 | 9 44
10 | 10 44
11 | 11 42
12 | 12 38
13 | 13 35
14 | 14 33
15 | 15 33
16 | 16 33
17 | 17 32
18 | 18 32
19 | 19 33
20 | 20 34
21 | 21 35
22 | 22 38
23 | 23 39
24 | 24 39
25 | 25 41
26 | 26 42
27 | 27 42
28 | 28 46
29 | 29 44
30 | 30 43
31 | 31 43
32 | 32 43
33 | 33 44
34 | 34 44
35 | 35 42
36 | 36 38
37 | 37 34
38 | 38 32
39 | 39 32
40 | 40 32
41 | 41 32
42 | 42 32
43 | 43 34
44 | 44 34
45 | 45 35
46 | 46 38
47 | 47 39
48 | 48 40
49 | 49 40
50 | 50 41
51 | 51 41
52 | 52 45
53 | 53 43
54 | 54 41
55 | 55 41
56 | 56 41
57 | 57 43
58 | 58 43
59 | 59 40
60 | 60 36
61 | 61 33
62 | 62 31
63 | 63 31
64 | 64 31
65 | 65 31
66 | 66 32
67 | 67 33
68 | 68 33
69 | 69 34
70 | 70 37
71 | 71 39
72 | 72 39
73 | 73 39
74 | 74 39
75 | 75 39
76 | 76 43
77 | 77 41
78 | 78 40
79 | 79 40
80 | 80 40
81 | 81 41
82 | 82 41
83 | 83 39
84 | 84 35
85 | 85 32
86 | 86 30
87 | 87 29
88 | 88 29
89 | 89 31
90 | 90 31
91 | 91 32
92 | 92 32
93 | 93 34
94 | 94 37
95 | 95 38
96 | 96 38
97 | 97 38
98 | 98 38
99 | 99 38
100 | 100 42
101 | 101 40
102 | 102 39
103 | 103 39
104 | 104 39
105 | 105 41
106 | 106 41
107 | 107 38
108 | 108 35
109 | 109 31
110 | 110 29
111 | 111 29
112 | 112 29
113 | 113 29
114 | 114 30
115 | 115 31
116 | 116 31
117 | 117 32
118 | 118 35
119 | 119 36
120 | 120 37
121 | 121 36
122 | 122 37
123 | 123 37
124 | 124 41
125 | 125 38
126 | 126 37
127 | 127 37
128 | 128 37
129 | 129 39
130 | 130 39
131 | 131 37
132 | 132 33
133 | 133 30
134 | 134 28
135 | 135 27
136 | 136 27
137 | 137 27
138 | 138 30
139 | 139 31
140 | 140 31
141 | 141 31
142 | 142 34
143 | 143 35
144 | 144 35
145 | 145 36
146 | 146 37
147 | 147 38
148 | 148 41
149 | 149 39
150 | 150 38
151 | 151 38
152 | 152 38
153 | 153 40
154 | 154 40
155 | 155 38
156 | 156 33
157 | 157 30
158 | 158 28
159 | 159 27
160 | 160 27
161 | 161 27
162 | 162 26
163 | 163 27
164 | 164 27
165 | 165 29
166 | 166 32
167 | 167 34
168 | 168 35
169 | 169 37
170 | 170 38
171 | 171 39
172 | 172 42
173 | 173 41
174 | 174 39
175 | 175 39
176 | 176 39
177 | 177 41
178 | 178 41
179 | 179 39
180 | 180 34
181 | 181 30
182 | 182 28
183 | 183 28
184 | 184 28
185 | 185 27
186 | 186 27
187 | 187 27
188 | 188 28
189 | 189 29
190 | 190 33
191 | 191 35
192 | 192 36
193 | 193 38
194 | 194 39
195 | 195 40
196 | 196 43
197 | 197 41
198 | 198 40
199 | 199 40
200 | 200 40
201 | 201 41
202 | 202 41
203 | 203 39
204 | 204 33
205 | 205 30
206 | 206 27
207 | 207 27
208 | 208 27
209 | 209 27
210 | 210 27
211 | 211 28
212 | 212 28
213 | 213 30
214 | 214 34
215 | 215 35
216 | 216 36
217 | 217 36
218 | 218 38
219 | 219 39
220 | 220 42
221 | 221 40
222 | 222 39
223 | 223 39
224 | 224 39
225 | 225 40
226 | 226 40
227 | 227 38
228 | 228 34
229 | 229 30
230 | 230 28
231 | 231 27
232 | 232 27
233 | 233 28
234 | 234 27
235 | 235 27
236 | 236 27
237 | 237 29
238 | 238 33
239 | 239 34
240 | 240 35
241 | 241 37
242 | 242 38
243 | 243 39
244 | 244 42
245 | 245 40
246 | 246 39
247 | 247 38
248 | 248 38
249 | 249 40
250 | 250 40
251 | 251 38
252 | 252 33
253 | 253 30
254 | 254 28
255 | 255 27
256 | 256 27
257 | 257 28
258 | 258 27
259 | 259 27
260 | 260 28
261 | 261 29
262 | 262 33
263 | 263 35
264 | 264 36
265 | 265 36
266 | 266 37
267 | 267 37
268 | 268 41
269 | 269 39
270 | 270 38
271 | 271 38
272 | 272 37
273 | 273 39
274 | 274 40
275 | 275 37
276 | 276 33
277 | 277 29
278 | 278 27
279 | 279 27
280 | 280 27
281 | 281 28
282 | 282 27
283 | 283 28
284 | 284 28
285 | 285 29
286 | 286 32
287 | 287 34
288 | 288 34
289 | 289 35
290 | 290 36
291 | 291 37
292 | 292 40
293 | 293 39
294 | 294 37
295 | 295 37
296 | 296 37
297 | 297 39
298 | 298 39
299 | 299 37
300 | 300 33
301 | 301 29
302 | 302 27
303 | 303 26
304 | 304 27
305 | 305 27
306 | 306 27
307 | 307 28
308 | 308 28
309 | 309 29
310 | 310 32
311 | 311 33
312 | 312 34
--------------------------------------------------------------------------------
/machinelearning/demo/regression.py:
--------------------------------------------------------------------------------
1 | from numpy import *
2 |
3 |
4 | def loadDataSet(fileName):
5 | numFeat = len(open(fileName).readline().split('\t')) - 1
6 | dataMat = []
7 | labelMat = []
8 | fr = open(fileName)
9 | for line in fr.readlines():
10 | lineArr = []
11 | curLine = line.strip().split('\t')
12 | for i in range(numFeat):
13 | lineArr.append(float(curLine[i]))
14 | dataMat.append(lineArr)
15 | labelMat.append(float(curLine[-1]))
16 | return dataMat, labelMat
17 |
18 |
19 | def standRegress(xArr, yArr):
20 | xMat = mat(xArr)
21 | yMat = mat(yArr).T
22 | xTx = xMat.T * xMat
23 | if linalg.det(xTx) == 0.0:
24 | print("standRegress : This matrix is sigular, cannot do inverse")
25 | ws = xTx.I * (xMat.T * yMat)
26 | return ws
27 |
28 |
29 | def lwlr(testPoint, xArr, yArr, k=1.0):
30 | xMat = mat(xArr)
31 | yMat = mat(yArr).T
32 | m = shape(xMat)[0]
33 | weights = mat(eye((m)))
34 | for j in range(m):
35 | diffMat = testPoint - xMat[j, :]
36 | weights[j, j] = exp(diffMat * diffMat.T / (-2.0 * k ** 2))
37 | xTx = xMat.T * (weights * xMat)
38 | if linalg.det(xTx) == 0.0:
39 | print("lwlr : This matrix is singular,cannot do inverse")
40 | return
41 | ws = xTx.I * (xMat.T * (weights * yMat))
42 | return testPoint * ws
43 |
44 |
45 | def lwlrTest(testArr, xArr, yArr, k=1.0):
46 | m = shape(testArr)[0]
47 | yHat = zeros(m)
48 | #print(yHat)
49 | for i in range(m):
50 | yHat[i] = lwlr(testArr[i], xArr, yArr, k)
51 | return yHat
52 |
53 | def rssError(yArr,yHatArr):
54 | return ((yArr-yHatArr)**2).sum()
--------------------------------------------------------------------------------
/machinelearning/demo/workfile:
--------------------------------------------------------------------------------
1 | 1 1.0011132812499999 82.0 41.0 1.0
2 | 2 0.06830078125 61.5 42.0 0.464285714286
3 | 3 0.06830078125 56.0 46.0 0.217391304348
4 | 4 0.06830078125 57.5 43.0 0.337209302326
5 | 5 0.06830078125 51.6 42.0 0.228571428571
6 | 6 0.06830078125 49.0 42.0 0.166666666667
7 | 7 0.06830078125 48.0 42.0 0.142857142857
8 | 8 0.06830078125 47.25 44.0 0.0738636363636
9 | 9 0.06830078125 48.8888888889 44.0 0.111111111111
10 | 10 0.06830078125 48.4 42.0 0.152380952381
11 | 11 0.06830078125 45.8181818182 38.0 0.205741626794
12 | 12 0.06830078125 41.1666666667 35.0 0.17619047619
13 | 13 0.06830078125 37.6923076923 33.0 0.142191142191
14 | 14 0.06830078125 35.3571428571 33.0 0.0714285714286
15 | 15 0.06830078125 35.2 33.0 0.0666666666667
16 | 16 0.06830078125 35.0625 32.0 0.095703125
17 | 17 0.06830078125 33.8823529412 32.0 0.0588235294118
18 | 18 0.06830078125 33.7777777778 33.0 0.023569023569
19 | 19 0.06830078125 34.7368421053 34.0 0.0216718266254
20 | 20 0.06830078125 35.7 35.0 0.02
21 | 21 0.06830078125 36.6666666667 38.0 0.0350877192982
22 | 22 0.06830078125 39.7272727273 39.0 0.018648018648
23 | 23 0.06830078125 40.6956521739 39.0 0.0434782608696
24 | 24 0.06830078125 40.625 41.0 0.00914634146341
25 | 25 0.06830078125 42.64 42.0 0.0152380952381
26 | 26 0.06830078125 43.6153846154 42.0 0.0384615384615
27 | 27 0.06830078125 43.5555555556 46.0 0.0531400966184
28 | 28 0.06830078125 47.6428571429 44.0 0.0827922077922
29 | 29 0.06830078125 45.5172413793 43.0 0.0585404971933
30 | 30 0.06830078125 44.4333333333 43.0 0.0333333333333
31 | 31 0.06830078125 44.3870967742 43.0 0.0322580645161
32 | 32 0.06830078125 44.34375 44.0 0.0078125
33 | 33 0.06830078125 45.3333333333 44.0 0.030303030303
34 | 34 0.06830078125 45.2941176471 42.0 0.078431372549
35 | 35 0.06830078125 43.2 38.0 0.136842105263
36 | 36 0.06830078125 39.0555555556 34.0 0.148692810458
37 | 37 0.06830078125 34.9189189189 32.0 0.0912162162162
38 | 38 0.06830078125 32.8421052632 32.0 0.0263157894737
39 | 39 0.06830078125 32.8205128205 32.0 0.025641025641
40 | 40 0.06830078125 32.8 32.0 0.025
41 | 41 0.06830078125 32.7804878049 32.0 0.0243902439024
42 | 42 0.06830078125 32.7619047619 34.0 0.0364145658263
43 | 43 0.06830078125 34.7906976744 34.0 0.0232558139535
44 | 44 0.06830078125 34.7727272727 35.0 0.00649350649351
45 | 45 0.06830078125 35.7777777778 38.0 0.0584795321637
46 | 46 0.06830078125 38.8260869565 39.0 0.00445930880713
47 | 47 0.06830078125 39.829787234 40.0 0.00425531914894
48 | 48 0.06830078125 40.8333333333 40.0 0.0208333333333
49 | 49 0.06830078125 40.8163265306 41.0 0.00447984071677
50 | 50 0.06830078125 41.82 41.0 0.02
51 | 51 0.06830078125 41.8039215686 45.0 0.0710239651416
52 | 52 0.06830078125 45.8653846154 43.0 0.0666368515206
53 | 53 0.06830078125 43.8113207547 41.0 0.0685687988955
54 | 54 0.06830078125 41.7592592593 41.0 0.0185185185185
55 | 55 0.06830078125 41.7454545455 41.0 0.0181818181818
56 | 56 0.06830078125 41.7321428571 43.0 0.0294850498339
57 | 57 0.06830078125 43.7543859649 43.0 0.0175438596491
58 | 58 0.06830078125 43.7413793103 40.0 0.0935344827586
59 | 59 0.06830078125 40.6779661017 36.0 0.129943502825
60 | 60 0.06830078125 36.6 33.0 0.109090909091
61 | 61 0.06830078125 33.5409836066 31.0 0.0819672131148
62 | 62 0.06830078125 31.5 31.0 0.0161290322581
63 | 63 0.06830078125 31.4920634921 31.0 0.015873015873
64 | 64 0.06830078125 31.484375 31.0 0.015625
65 | 65 0.06830078125 31.4769230769 32.0 0.0163461538462
66 | 66 0.06830078125 32.4848484848 33.0 0.0156106519743
67 | 67 0.06830078125 33.4925373134 33.0 0.0149253731343
68 | 68 0.06830078125 33.4852941176 34.0 0.0151384083045
69 | 69 0.06830078125 34.4927536232 37.0 0.0677634155895
70 | 70 0.06830078125 37.5285714286 39.0 0.0377289377289
71 | 71 0.06830078125 39.5492957746 39.0 0.0140845070423
72 | 72 0.06830078125 39.5416666667 39.0 0.0138888888889
73 | 73 0.06830078125 39.5342465753 39.0 0.013698630137
74 | 74 0.06830078125 39.527027027 39.0 0.0135135135135
75 | 75 0.06830078125 39.52 43.0 0.0809302325581
76 | 76 0.06830078125 43.5657894737 41.0 0.0625802310655
77 | 77 0.06830078125 41.5324675325 40.0 0.0383116883117
78 | 78 0.06830078125 40.5128205128 40.0 0.0128205128205
79 | 79 0.06830078125 40.5063291139 40.0 0.0126582278481
80 | 80 0.06830078125 40.5 41.0 0.0121951219512
81 | 81 0.06830078125 41.5061728395 41.0 0.0123456790123
82 | 82 0.06830078125 41.5 39.0 0.0641025641026
83 | 83 0.06830078125 39.4698795181 35.0 0.127710843373
84 | 84 0.06830078125 35.4166666667 32.0 0.106770833333
85 | 85 0.06830078125 32.3764705882 30.0 0.0792156862745
86 | 86 0.06830078125 30.3488372093 29.0 0.046511627907
87 | 87 0.06830078125 29.3333333333 29.0 0.0114942528736
88 | 88 0.06830078125 29.3295454545 31.0 0.0538856304985
89 | 89 0.06830078125 31.3483146067 31.0 0.0112359550562
90 | 90 0.06830078125 31.3444444444 32.0 0.0204861111111
91 | 91 0.06830078125 32.3516483516 32.0 0.010989010989
92 | 92 0.06830078125 32.347826087 34.0 0.0485933503836
93 | 93 0.06830078125 34.3655913978 37.0 0.0712002324906
94 | 94 0.06830078125 37.3936170213 38.0 0.0159574468085
95 | 95 0.06830078125 38.4 38.0 0.0105263157895
96 | 96 0.06830078125 38.3958333333 38.0 0.0104166666667
97 | 97 0.06830078125 38.3917525773 38.0 0.0103092783505
98 | 98 0.06830078125 38.387755102 38.0 0.0102040816327
99 | 99 0.06830078125 38.3838383838 42.0 0.0860990860991
100 | 100 0.06830078125 42.42 40.0 0.0605
101 | 101 0.06830078125 40.396039604 39.0 0.035795887281
102 | 102 0.06830078125 39.3823529412 39.0 0.00980392156863
103 | 103 0.06830078125 39.3786407767 39.0 0.00970873786408
104 | 104 0.06830078125 39.375 41.0 0.0396341463415
105 | 105 0.06830078125 41.3904761905 41.0 0.00952380952381
106 | 106 0.06830078125 41.3867924528 38.0 0.0891261171797
107 | 107 0.06830078125 38.3551401869 35.0 0.0958611481976
108 | 108 0.06830078125 35.3240740741 31.0 0.139486260454
109 | 109 0.06830078125 31.2844036697 29.0 0.0787725403353
110 | 110 0.06830078125 29.2636363636 29.0 0.00909090909091
111 | 111 0.06830078125 29.2612612613 29.0 0.00900900900901
112 | 112 0.06830078125 29.2589285714 29.0 0.00892857142857
113 | 113 0.06830078125 29.2566371681 30.0 0.0247787610619
114 | 114 0.06830078125 30.2631578947 31.0 0.0237691001698
115 | 115 0.06830078125 31.2695652174 31.0 0.00869565217391
116 | 116 0.06830078125 31.2672413793 32.0 0.0228987068966
117 | 117 0.06830078125 32.2735042735 35.0 0.0778998778999
118 | 118 0.06830078125 35.2966101695 36.0 0.019538606403
119 | 119 0.06830078125 36.3025210084 37.0 0.0188507835567
120 | 120 0.06830078125 37.3083333333 36.0 0.0363425925926
121 | 121 0.06830078125 36.2975206612 37.0 0.0189859280768
122 | 122 0.06830078125 37.3032786885 37.0 0.00819672131148
123 | 123 0.06830078125 37.3008130081 41.0 0.0902240729724
124 | 124 0.06830078125 41.3306451613 38.0 0.0876485568761
125 | 125 0.06830078125 38.304 37.0 0.0352432432432
126 | 126 0.06830078125 37.2936507937 37.0 0.00793650793651
127 | 127 0.06830078125 37.2913385827 37.0 0.00787401574803
128 | 128 0.06830078125 37.2890625 39.0 0.0438701923077
129 | 129 0.06830078125 39.3023255814 39.0 0.0077519379845
130 | 130 0.06830078125 39.3 37.0 0.0621621621622
131 | 131 0.06830078125 37.2824427481 33.0 0.129770992366
132 | 132 0.06830078125 33.25 30.0 0.108333333333
133 | 133 0.06830078125 30.2255639098 28.0 0.0794844253491
134 | 134 0.06830078125 28.2089552239 27.0 0.044776119403
135 | 135 0.06830078125 27.2 27.0 0.00740740740741
136 | 136 0.06830078125 27.1985294118 27.0 0.00735294117647
137 | 137 0.06830078125 27.197080292 30.0 0.0934306569343
138 | 138 0.06830078125 30.2173913043 31.0 0.0252454417952
139 | 139 0.06830078125 31.2230215827 31.0 0.00719424460432
140 | 140 0.06830078125 31.2214285714 31.0 0.00714285714286
141 | 141 0.06830078125 31.219858156 34.0 0.0817688777639
142 | 142 0.06830078125 34.2394366197 35.0 0.0217303822938
143 | 143 0.06830078125 35.2447552448 35.0 0.00699300699301
144 | 144 0.06830078125 35.2430555556 36.0 0.0210262345679
145 | 145 0.06830078125 36.2482758621 37.0 0.0203168685927
146 | 146 0.06830078125 37.2534246575 38.0 0.0196467195386
147 | 147 0.06830078125 38.2585034014 41.0 0.0668657706985
148 | 148 0.06830078125 41.277027027 39.0 0.0583853083853
149 | 149 0.06830078125 39.2617449664 38.0 0.0332038149064
150 | 150 0.06830078125 38.2533333333 38.0 0.00666666666667
151 | 151 0.06830078125 38.2516556291 38.0 0.00662251655629
152 | 152 0.06830078125 38.25 40.0 0.04375
153 | 153 0.06830078125 40.2614379085 40.0 0.00653594771242
154 | 154 0.06830078125 40.2597402597 38.0 0.0594668489405
155 | 155 0.06830078125 38.2451612903 33.0 0.158944281525
156 | 156 0.06830078125 33.2115384615 30.0 0.107051282051
157 | 157 0.06830078125 30.1910828025 28.0 0.0782529572338
158 | 158 0.06830078125 28.1772151899 27.0 0.0436005625879
159 | 159 0.06830078125 27.1698113208 27.0 0.0062893081761
160 | 160 0.06830078125 27.16875 27.0 0.00625
161 | 161 0.06830078125 27.1677018634 26.0 0.044911610129
162 | 162 0.06830078125 26.1604938272 27.0 0.0310928212163
163 | 163 0.06830078125 27.1656441718 27.0 0.00613496932515
164 | 164 0.06830078125 27.1646341463 29.0 0.0632884777124
165 | 165 0.06830078125 29.1757575758 32.0 0.0882575757576
166 | 166 0.06830078125 32.1927710843 34.0 0.0531537916371
167 | 167 0.06830078125 34.2035928144 35.0 0.022754491018
168 | 168 0.06830078125 35.2083333333 37.0 0.0484234234234
169 | 169 0.06830078125 37.2189349112 38.0 0.020554344441
170 | 170 0.06830078125 38.2235294118 39.0 0.0199095022624
171 | 171 0.06830078125 39.2280701754 42.0 0.0659983291562
172 | 172 0.06830078125 42.2441860465 41.0 0.0303460011344
173 | 173 0.06830078125 41.2369942197 39.0 0.057358826145
174 | 174 0.06830078125 39.224137931 39.0 0.00574712643678
175 | 175 0.06830078125 39.2228571429 39.0 0.00571428571429
176 | 176 0.06830078125 39.2215909091 41.0 0.0433758314856
177 | 177 0.06830078125 41.2316384181 41.0 0.00564971751412
178 | 178 0.06830078125 41.2303370787 39.0 0.0571881302218
179 | 179 0.06830078125 39.217877095 34.0 0.153466973382
180 | 180 0.06830078125 34.1888888889 30.0 0.13962962963
181 | 181 0.06830078125 30.1657458564 28.0 0.0773480662983
182 | 182 0.06830078125 28.1538461538 28.0 0.00549450549451
183 | 183 0.06830078125 28.1530054645 28.0 0.00546448087432
184 | 184 0.06830078125 28.152173913 27.0 0.0426731078905
185 | 185 0.06830078125 27.1459459459 27.0 0.00540540540541
186 | 186 0.06830078125 27.1451612903 27.0 0.00537634408602
187 | 187 0.06830078125 27.1443850267 28.0 0.0305576776165
188 | 188 0.06830078125 28.1489361702 29.0 0.0293470286134
189 | 189 0.06830078125 29.1534391534 33.0 0.116562449896
190 | 190 0.06830078125 33.1736842105 35.0 0.0521804511278
191 | 191 0.06830078125 35.1832460733 36.0 0.022687609075
192 | 192 0.06830078125 36.1875 38.0 0.0476973684211
193 | 193 0.06830078125 38.1968911917 39.0 0.0205925335459
194 | 194 0.06830078125 39.2010309278 40.0 0.0199742268041
195 | 195 0.06830078125 40.2051282051 43.0 0.0649970184854
196 | 196 0.06830078125 43.2193877551 41.0 0.054131408661
197 | 197 0.06830078125 41.2081218274 40.0 0.0302030456853
198 | 198 0.06830078125 40.202020202 40.0 0.00505050505051
199 | 199 0.06830078125 40.2010050251 40.0 0.00502512562814
200 | 200 0.06830078125 40.2 41.0 0.019512195122
201 | 201 0.06830078125 41.2039800995 41.0 0.00497512437811
202 | 202 0.06830078125 41.202970297 39.0 0.0564864178726
203 | 203 0.06830078125 39.1921182266 33.0 0.187639946261
204 | 204 0.06830078125 33.1617647059 30.0 0.105392156863
205 | 205 0.06830078125 30.1463414634 27.0 0.116531165312
206 | 206 0.06830078125 27.1310679612 27.0 0.00485436893204
207 | 207 0.06830078125 27.1304347826 27.0 0.0048309178744
208 | 208 0.06830078125 27.1298076923 27.0 0.00480769230769
209 | 209 0.06830078125 27.1291866029 27.0 0.00478468899522
210 | 210 0.06830078125 27.1285714286 28.0 0.0311224489796
211 | 211 0.06830078125 28.1327014218 28.0 0.00473933649289
212 | 212 0.06830078125 28.1320754717 30.0 0.0622641509434
213 | 213 0.06830078125 30.1408450704 34.0 0.113504556752
214 | 214 0.06830078125 34.1588785047 35.0 0.0240320427236
215 | 215 0.06830078125 35.1627906977 36.0 0.0232558139535
216 | 216 0.06830078125 36.1666666667 36.0 0.00462962962963
217 | 217 0.06830078125 36.1658986175 38.0 0.048265825855
218 | 218 0.06830078125 38.1743119266 39.0 0.0211714890614
219 | 219 0.06830078125 39.1780821918 42.0 0.0671885192433
220 | 220 0.06830078125 42.1909090909 40.0 0.0547727272727
221 | 221 0.06830078125 40.1809954751 39.0 0.0302819352593
222 | 222 0.06830078125 39.1756756757 39.0 0.0045045045045
223 | 223 0.06830078125 39.1748878924 39.0 0.00448430493274
224 | 224 0.06830078125 39.1741071429 40.0 0.0206473214286
225 | 225 0.06830078125 40.1777777778 40.0 0.00444444444444
226 | 226 0.06830078125 40.1769911504 38.0 0.0572892408011
227 | 227 0.06830078125 38.1674008811 34.0 0.122570614149
228 | 228 0.06830078125 34.149122807 30.0 0.138304093567
229 | 229 0.06830078125 30.1310043668 28.0 0.0761072988147
230 | 230 0.06830078125 28.1217391304 27.0 0.0415458937198
231 | 231 0.06830078125 27.1168831169 27.0 0.004329004329
232 | 232 0.06830078125 27.1163793103 28.0 0.0315578817734
233 | 233 0.06830078125 28.1201716738 27.0 0.0414878397711
234 | 234 0.06830078125 27.1153846154 27.0 0.0042735042735
235 | 235 0.06830078125 27.114893617 27.0 0.00425531914894
236 | 236 0.06830078125 27.1144067797 29.0 0.0650204558738
237 | 237 0.06830078125 29.1223628692 33.0 0.117504155479
238 | 238 0.06830078125 33.1386554622 34.0 0.0253336628769
239 | 239 0.06830078125 34.1422594142 35.0 0.0245068738793
240 | 240 0.06830078125 35.1458333333 37.0 0.0501126126126
241 | 241 0.06830078125 37.153526971 38.0 0.0222756060275
242 | 242 0.06830078125 38.1570247934 39.0 0.0216147488875
243 | 243 0.06830078125 39.1604938272 42.0 0.0676072898295
244 | 244 0.06830078125 42.1721311475 40.0 0.0543032786885
245 | 245 0.06830078125 40.1632653061 39.0 0.0298273155416
246 | 246 0.06830078125 39.1585365854 38.0 0.030487804878
247 | 247 0.06830078125 38.1538461538 38.0 0.00404858299595
248 | 248 0.06830078125 38.1532258065 40.0 0.0461693548387
249 | 249 0.06830078125 40.1606425703 40.0 0.00401606425703
250 | 250 0.06830078125 40.16 38.0 0.0568421052632
251 | 251 0.06830078125 38.1513944223 33.0 0.156102861282
252 | 252 0.06830078125 33.130952381 30.0 0.104365079365
253 | 253 0.06830078125 30.1185770751 28.0 0.0756634669678
254 | 254 0.06830078125 28.1102362205 27.0 0.0411198600175
255 | 255 0.06830078125 27.1058823529 27.0 0.00392156862745
256 | 256 0.06830078125 27.10546875 28.0 0.0319475446429
257 | 257 0.06830078125 28.1089494163 27.0 0.0410722006053
258 | 258 0.06830078125 27.1046511628 27.0 0.00387596899225
259 | 259 0.06830078125 27.1042471042 28.0 0.0319911748483
260 | 260 0.06830078125 28.1076923077 29.0 0.0307692307692
261 | 261 0.06830078125 29.1111111111 33.0 0.117845117845
262 | 262 0.06830078125 33.1259541985 35.0 0.0535441657579
263 | 263 0.06830078125 35.1330798479 36.0 0.0240811153359
264 | 264 0.06830078125 36.1363636364 36.0 0.00378787878788
265 | 265 0.06830078125 36.1358490566 37.0 0.0233554309026
266 | 266 0.06830078125 37.1390977444 37.0 0.00375939849624
267 | 267 0.06830078125 37.138576779 41.0 0.0941810541701
268 | 268 0.06830078125 41.1529850746 39.0 0.0552047455033
269 | 269 0.06830078125 39.1449814126 38.0 0.0301310898063
270 | 270 0.06830078125 38.1407407407 38.0 0.0037037037037
271 | 271 0.06830078125 38.1402214022 37.0 0.0308167946544
272 | 272 0.06830078125 37.1360294118 39.0 0.0477941176471
273 | 273 0.06830078125 39.1428571429 40.0 0.0214285714286
274 | 274 0.06830078125 40.1459854015 37.0 0.0850266324719
275 | 275 0.06830078125 37.1345454545 33.0 0.125289256198
276 | 276 0.06830078125 33.1195652174 29.0 0.142053973013
277 | 277 0.06830078125 29.1046931408 27.0 0.0779515978072
278 | 278 0.06830078125 27.0971223022 27.0 0.00359712230216
279 | 279 0.06830078125 27.0967741935 27.0 0.00358422939068
280 | 280 0.06830078125 27.0964285714 28.0 0.0322704081633
281 | 281 0.06830078125 28.0996441281 27.0 0.0407275603005
282 | 282 0.06830078125 27.0957446809 28.0 0.0322948328267
283 | 283 0.06830078125 28.0989399293 28.0 0.00353356890459
284 | 284 0.06830078125 28.0985915493 29.0 0.0310830500243
285 | 285 0.06830078125 29.101754386 32.0 0.0905701754386
286 | 286 0.06830078125 32.1118881119 34.0 0.0555327025915
287 | 287 0.06830078125 34.118466899 34.0 0.00348432055749
288 | 288 0.06830078125 34.1180555556 35.0 0.0251984126984
289 | 289 0.06830078125 35.1211072664 36.0 0.0244136870434
290 | 290 0.06830078125 36.124137931 37.0 0.0236719478099
291 | 291 0.06830078125 37.1271477663 40.0 0.0718213058419
292 | 292 0.06830078125 40.1369863014 39.0 0.0291534949069
293 | 293 0.06830078125 39.133105802 37.0 0.0576515081635
294 | 294 0.06830078125 37.1258503401 37.0 0.00340136054422
295 | 295 0.06830078125 37.1254237288 37.0 0.00338983050847
296 | 296 0.06830078125 37.125 39.0 0.0480769230769
297 | 297 0.06830078125 39.1313131313 39.0 0.003367003367
298 | 298 0.06830078125 39.1308724832 37.0 0.0575911481952
299 | 299 0.06830078125 37.1237458194 33.0 0.124961994527
300 | 300 0.06830078125 33.11 29.0 0.141724137931
301 | 301 0.06830078125 29.096345515 27.0 0.0776424264796
302 | 302 0.06830078125 27.0894039735 26.0 0.0419001528273
303 | 303 0.06830078125 26.0858085809 27.0 0.0338589414497
304 | 304 0.06830078125 27.0888157895 27.0 0.00328947368421
305 | 305 0.06830078125 27.0885245902 27.0 0.00327868852459
306 | 306 0.06830078125 27.0882352941 28.0 0.0325630252101
307 | 307 0.06830078125 28.0912052117 28.0 0.00325732899023
308 | 308 0.06830078125 28.0909090909 29.0 0.0313479623824
309 | 309 0.06830078125 29.0938511327 32.0 0.0908171521036
310 | 310 0.06830078125 32.1032258065 33.0 0.0271749755621
311 | 311 0.06830078125 33.1061093248 34.0 0.026290902213
312 | 1 0.06830078125 82.0 41.0 1.0
313 | 2 0.06830078125 61.5 42.0 0.464285714286
314 | 3 0.06830078125 56.0 46.0 0.217391304348
315 | 4 0.06830078125 57.5 43.0 0.337209302326
316 | 5 0.06830078125 51.6 42.0 0.228571428571
317 | 6 0.06830078125 49.0 42.0 0.166666666667
318 | 7 0.06830078125 48.0 42.0 0.142857142857
319 | 8 0.06830078125 47.25 44.0 0.0738636363636
320 | 9 0.06830078125 48.8888888889 44.0 0.111111111111
321 | 10 0.06830078125 48.4 42.0 0.152380952381
322 | 11 0.06830078125 45.8181818182 38.0 0.205741626794
323 | 12 0.06830078125 41.1666666667 35.0 0.17619047619
324 | 13 0.06830078125 37.6923076923 33.0 0.142191142191
325 | 14 0.06830078125 35.3571428571 33.0 0.0714285714286
326 | 15 0.06830078125 35.2 33.0 0.0666666666667
327 | 16 0.06830078125 35.0625 32.0 0.095703125
328 | 17 0.06830078125 33.8823529412 32.0 0.0588235294118
329 | 18 0.06830078125 33.7777777778 33.0 0.023569023569
330 | 19 0.06830078125 34.7368421053 34.0 0.0216718266254
331 | 20 0.06830078125 35.7 35.0 0.02
332 | 21 0.06830078125 36.6666666667 38.0 0.0350877192982
333 | 22 0.06830078125 39.7272727273 39.0 0.018648018648
334 | 23 0.06830078125 40.6956521739 39.0 0.0434782608696
335 | 24 0.06830078125 40.625 41.0 0.00914634146341
336 | 25 0.06830078125 42.64 42.0 0.0152380952381
337 | 26 0.06830078125 43.6153846154 42.0 0.0384615384615
338 | 27 0.06830078125 43.5555555556 46.0 0.0531400966184
339 | 28 0.06830078125 47.6428571429 44.0 0.0827922077922
340 | 29 0.06830078125 45.5172413793 43.0 0.0585404971933
341 | 30 0.06830078125 44.4333333333 43.0 0.0333333333333
342 | 31 0.06830078125 44.3870967742 43.0 0.0322580645161
343 | 32 0.06830078125 44.34375 44.0 0.0078125
344 | 33 0.06830078125 45.3333333333 44.0 0.030303030303
345 | 34 0.06830078125 45.2941176471 42.0 0.078431372549
346 | 35 0.06830078125 43.2 38.0 0.136842105263
347 | 36 0.06830078125 39.0555555556 34.0 0.148692810458
348 | 37 0.06830078125 34.9189189189 32.0 0.0912162162162
349 | 38 0.06830078125 32.8421052632 32.0 0.0263157894737
350 | 39 0.06830078125 32.8205128205 32.0 0.025641025641
351 | 40 0.06830078125 32.8 32.0 0.025
352 | 41 0.06830078125 32.7804878049 32.0 0.0243902439024
353 | 42 0.06830078125 32.7619047619 34.0 0.0364145658263
354 | 43 0.06830078125 34.7906976744 34.0 0.0232558139535
355 | 44 0.06830078125 34.7727272727 35.0 0.00649350649351
356 | 45 0.06830078125 35.7777777778 38.0 0.0584795321637
357 | 46 0.06830078125 38.8260869565 39.0 0.00445930880713
358 | 47 0.06830078125 39.829787234 40.0 0.00425531914894
359 | 48 0.06830078125 40.8333333333 40.0 0.0208333333333
360 | 49 0.06830078125 40.8163265306 41.0 0.00447984071677
361 | 50 0.06830078125 41.82 41.0 0.02
362 | 51 0.06830078125 41.8039215686 45.0 0.0710239651416
363 | 52 0.06830078125 45.8653846154 43.0 0.0666368515206
364 | 53 0.06830078125 43.8113207547 41.0 0.0685687988955
365 | 54 0.06830078125 41.7592592593 41.0 0.0185185185185
366 | 55 0.06830078125 41.7454545455 41.0 0.0181818181818
367 | 56 0.06830078125 41.7321428571 43.0 0.0294850498339
368 | 57 0.06830078125 43.7543859649 43.0 0.0175438596491
369 | 58 0.06830078125 43.7413793103 40.0 0.0935344827586
370 | 59 0.06830078125 40.6779661017 36.0 0.129943502825
371 | 60 0.06830078125 36.6 33.0 0.109090909091
372 | 61 0.06830078125 33.5409836066 31.0 0.0819672131148
373 | 62 0.06830078125 31.5 31.0 0.0161290322581
374 | 63 0.06830078125 31.4920634921 31.0 0.015873015873
375 | 64 0.06830078125 31.484375 31.0 0.015625
376 | 65 0.06830078125 31.4769230769 32.0 0.0163461538462
377 | 66 0.06830078125 32.4848484848 33.0 0.0156106519743
378 | 67 0.06830078125 33.4925373134 33.0 0.0149253731343
379 | 68 0.06830078125 33.4852941176 34.0 0.0151384083045
380 | 69 0.06830078125 34.4927536232 37.0 0.0677634155895
381 | 70 0.06830078125 37.5285714286 39.0 0.0377289377289
382 | 71 0.06830078125 39.5492957746 39.0 0.0140845070423
383 | 72 0.06830078125 39.5416666667 39.0 0.0138888888889
384 | 73 0.06830078125 39.5342465753 39.0 0.013698630137
385 | 74 0.06830078125 39.527027027 39.0 0.0135135135135
386 | 75 0.06830078125 39.52 43.0 0.0809302325581
387 | 76 0.06830078125 43.5657894737 41.0 0.0625802310655
388 | 77 0.06830078125 41.5324675325 40.0 0.0383116883117
389 | 78 0.06830078125 40.5128205128 40.0 0.0128205128205
390 | 79 0.06830078125 40.5063291139 40.0 0.0126582278481
391 | 80 0.06830078125 40.5 41.0 0.0121951219512
392 | 81 0.06830078125 41.5061728395 41.0 0.0123456790123
393 | 82 0.06830078125 41.5 39.0 0.0641025641026
394 | 83 0.06830078125 39.4698795181 35.0 0.127710843373
395 | 84 0.06830078125 35.4166666667 32.0 0.106770833333
396 | 85 0.06830078125 32.3764705882 30.0 0.0792156862745
397 | 86 0.06830078125 30.3488372093 29.0 0.046511627907
398 | 87 0.06830078125 29.3333333333 29.0 0.0114942528736
399 | 88 0.06830078125 29.3295454545 31.0 0.0538856304985
400 | 89 0.06830078125 31.3483146067 31.0 0.0112359550562
401 | 90 0.06830078125 31.3444444444 32.0 0.0204861111111
402 | 91 0.06830078125 32.3516483516 32.0 0.010989010989
403 | 92 0.06830078125 32.347826087 34.0 0.0485933503836
404 | 93 0.06830078125 34.3655913978 37.0 0.0712002324906
405 | 94 0.06830078125 37.3936170213 38.0 0.0159574468085
406 | 95 0.06830078125 38.4 38.0 0.0105263157895
407 | 96 0.06830078125 38.3958333333 38.0 0.0104166666667
408 | 97 0.06830078125 38.3917525773 38.0 0.0103092783505
409 | 98 0.06830078125 38.387755102 38.0 0.0102040816327
410 | 99 0.06830078125 38.3838383838 42.0 0.0860990860991
411 | 100 0.06830078125 42.42 40.0 0.0605
412 | 101 0.06830078125 40.396039604 39.0 0.035795887281
413 | 102 0.06830078125 39.3823529412 39.0 0.00980392156863
414 | 103 0.06830078125 39.3786407767 39.0 0.00970873786408
415 | 104 0.06830078125 39.375 41.0 0.0396341463415
416 | 105 0.06830078125 41.3904761905 41.0 0.00952380952381
417 | 106 0.06830078125 41.3867924528 38.0 0.0891261171797
418 | 107 0.06830078125 38.3551401869 35.0 0.0958611481976
419 | 108 0.06830078125 35.3240740741 31.0 0.139486260454
420 | 109 0.06830078125 31.2844036697 29.0 0.0787725403353
421 | 110 0.06830078125 29.2636363636 29.0 0.00909090909091
422 | 111 0.06830078125 29.2612612613 29.0 0.00900900900901
423 | 112 0.06830078125 29.2589285714 29.0 0.00892857142857
424 | 113 0.06830078125 29.2566371681 30.0 0.0247787610619
425 | 114 0.06830078125 30.2631578947 31.0 0.0237691001698
426 | 115 0.06830078125 31.2695652174 31.0 0.00869565217391
427 | 116 0.06830078125 31.2672413793 32.0 0.0228987068966
428 | 117 0.06830078125 32.2735042735 35.0 0.0778998778999
429 | 118 0.06830078125 35.2966101695 36.0 0.019538606403
430 | 119 0.06830078125 36.3025210084 37.0 0.0188507835567
431 | 120 0.06830078125 37.3083333333 36.0 0.0363425925926
432 | 121 0.06830078125 36.2975206612 37.0 0.0189859280768
433 | 122 0.06830078125 37.3032786885 37.0 0.00819672131148
434 | 123 0.06830078125 37.3008130081 41.0 0.0902240729724
435 | 124 0.06830078125 41.3306451613 38.0 0.0876485568761
436 | 125 0.06830078125 38.304 37.0 0.0352432432432
437 | 126 0.06830078125 37.2936507937 37.0 0.00793650793651
438 | 127 0.06830078125 37.2913385827 37.0 0.00787401574803
439 | 128 0.06830078125 37.2890625 39.0 0.0438701923077
440 | 129 0.06830078125 39.3023255814 39.0 0.0077519379845
441 | 130 0.06830078125 39.3 37.0 0.0621621621622
442 | 131 0.06830078125 37.2824427481 33.0 0.129770992366
443 | 132 0.06830078125 33.25 30.0 0.108333333333
444 | 133 0.06830078125 30.2255639098 28.0 0.0794844253491
445 | 134 0.06830078125 28.2089552239 27.0 0.044776119403
446 | 135 0.06830078125 27.2 27.0 0.00740740740741
447 | 136 0.06830078125 27.1985294118 27.0 0.00735294117647
448 | 137 0.06830078125 27.197080292 30.0 0.0934306569343
449 | 138 0.06830078125 30.2173913043 31.0 0.0252454417952
450 | 139 0.06830078125 31.2230215827 31.0 0.00719424460432
451 | 140 0.06830078125 31.2214285714 31.0 0.00714285714286
452 | 141 0.06830078125 31.219858156 34.0 0.0817688777639
453 | 142 0.06830078125 34.2394366197 35.0 0.0217303822938
454 | 143 0.06830078125 35.2447552448 35.0 0.00699300699301
455 | 144 0.06830078125 35.2430555556 36.0 0.0210262345679
456 | 145 0.06830078125 36.2482758621 37.0 0.0203168685927
457 | 146 0.06830078125 37.2534246575 38.0 0.0196467195386
458 | 147 0.06830078125 38.2585034014 41.0 0.0668657706985
459 | 148 0.06830078125 41.277027027 39.0 0.0583853083853
460 | 149 0.06830078125 39.2617449664 38.0 0.0332038149064
461 | 150 0.06830078125 38.2533333333 38.0 0.00666666666667
462 | 151 0.06830078125 38.2516556291 38.0 0.00662251655629
463 | 152 0.06830078125 38.25 40.0 0.04375
464 | 153 0.06830078125 40.2614379085 40.0 0.00653594771242
465 | 154 0.06830078125 40.2597402597 38.0 0.0594668489405
466 | 155 0.06830078125 38.2451612903 33.0 0.158944281525
467 | 156 0.06830078125 33.2115384615 30.0 0.107051282051
468 | 157 0.06830078125 30.1910828025 28.0 0.0782529572338
469 | 158 0.06830078125 28.1772151899 27.0 0.0436005625879
470 | 159 0.06830078125 27.1698113208 27.0 0.0062893081761
471 | 160 0.06830078125 27.16875 27.0 0.00625
472 | 161 0.06830078125 27.1677018634 26.0 0.044911610129
473 | 162 0.06830078125 26.1604938272 27.0 0.0310928212163
474 | 163 0.06830078125 27.1656441718 27.0 0.00613496932515
475 | 164 0.06830078125 27.1646341463 29.0 0.0632884777124
476 | 165 0.06830078125 29.1757575758 32.0 0.0882575757576
477 | 166 0.06830078125 32.1927710843 34.0 0.0531537916371
478 | 167 0.06830078125 34.2035928144 35.0 0.022754491018
479 | 168 0.06830078125 35.2083333333 37.0 0.0484234234234
480 | 169 0.06830078125 37.2189349112 38.0 0.020554344441
481 | 170 0.06830078125 38.2235294118 39.0 0.0199095022624
482 | 171 0.06830078125 39.2280701754 42.0 0.0659983291562
483 | 172 0.06830078125 42.2441860465 41.0 0.0303460011344
484 | 173 0.06830078125 41.2369942197 39.0 0.057358826145
485 | 174 0.06830078125 39.224137931 39.0 0.00574712643678
486 | 175 0.06830078125 39.2228571429 39.0 0.00571428571429
487 | 176 0.06830078125 39.2215909091 41.0 0.0433758314856
488 | 177 0.06830078125 41.2316384181 41.0 0.00564971751412
489 | 178 0.06830078125 41.2303370787 39.0 0.0571881302218
490 | 179 0.06830078125 39.217877095 34.0 0.153466973382
491 | 180 0.06830078125 34.1888888889 30.0 0.13962962963
492 | 181 0.06830078125 30.1657458564 28.0 0.0773480662983
493 | 182 0.06830078125 28.1538461538 28.0 0.00549450549451
494 | 183 0.06830078125 28.1530054645 28.0 0.00546448087432
495 | 184 0.06830078125 28.152173913 27.0 0.0426731078905
496 | 185 0.06830078125 27.1459459459 27.0 0.00540540540541
497 | 186 0.06830078125 27.1451612903 27.0 0.00537634408602
498 | 187 0.06830078125 27.1443850267 28.0 0.0305576776165
499 | 188 0.06830078125 28.1489361702 29.0 0.0293470286134
500 | 189 0.06830078125 29.1534391534 33.0 0.116562449896
501 | 190 0.06830078125 33.1736842105 35.0 0.0521804511278
502 | 191 0.06830078125 35.1832460733 36.0 0.022687609075
503 | 192 0.06830078125 36.1875 38.0 0.0476973684211
504 | 193 0.06830078125 38.1968911917 39.0 0.0205925335459
505 | 194 0.06830078125 39.2010309278 40.0 0.0199742268041
506 | 195 0.06830078125 40.2051282051 43.0 0.0649970184854
507 | 196 0.06830078125 43.2193877551 41.0 0.054131408661
508 | 197 0.06830078125 41.2081218274 40.0 0.0302030456853
509 | 198 0.06830078125 40.202020202 40.0 0.00505050505051
510 | 199 0.06830078125 40.2010050251 40.0 0.00502512562814
511 | 200 0.06830078125 40.2 41.0 0.019512195122
512 | 201 0.06830078125 41.2039800995 41.0 0.00497512437811
513 | 202 0.06830078125 41.202970297 39.0 0.0564864178726
514 | 203 0.06830078125 39.1921182266 33.0 0.187639946261
515 | 204 0.06830078125 33.1617647059 30.0 0.105392156863
516 | 205 0.06830078125 30.1463414634 27.0 0.116531165312
517 | 206 0.06830078125 27.1310679612 27.0 0.00485436893204
518 | 207 0.06830078125 27.1304347826 27.0 0.0048309178744
519 | 208 0.06830078125 27.1298076923 27.0 0.00480769230769
520 | 209 0.06830078125 27.1291866029 27.0 0.00478468899522
521 | 210 0.06830078125 27.1285714286 28.0 0.0311224489796
522 | 211 0.06830078125 28.1327014218 28.0 0.00473933649289
523 | 212 0.06830078125 28.1320754717 30.0 0.0622641509434
524 | 213 0.06830078125 30.1408450704 34.0 0.113504556752
525 | 214 0.06830078125 34.1588785047 35.0 0.0240320427236
526 | 215 0.06830078125 35.1627906977 36.0 0.0232558139535
527 | 216 0.06830078125 36.1666666667 36.0 0.00462962962963
528 | 217 0.06830078125 36.1658986175 38.0 0.048265825855
529 | 218 0.06830078125 38.1743119266 39.0 0.0211714890614
530 | 219 0.06830078125 39.1780821918 42.0 0.0671885192433
531 | 220 0.06830078125 42.1909090909 40.0 0.0547727272727
532 | 221 0.06830078125 40.1809954751 39.0 0.0302819352593
533 | 222 0.06830078125 39.1756756757 39.0 0.0045045045045
534 | 223 0.06830078125 39.1748878924 39.0 0.00448430493274
535 | 224 0.06830078125 39.1741071429 40.0 0.0206473214286
536 | 225 0.06830078125 40.1777777778 40.0 0.00444444444444
537 | 226 0.06830078125 40.1769911504 38.0 0.0572892408011
538 | 227 0.06830078125 38.1674008811 34.0 0.122570614149
539 | 228 0.06830078125 34.149122807 30.0 0.138304093567
540 | 229 0.06830078125 30.1310043668 28.0 0.0761072988147
541 | 230 0.06830078125 28.1217391304 27.0 0.0415458937198
542 | 231 0.06830078125 27.1168831169 27.0 0.004329004329
543 | 232 0.06830078125 27.1163793103 28.0 0.0315578817734
544 | 233 0.06830078125 28.1201716738 27.0 0.0414878397711
545 | 234 0.06830078125 27.1153846154 27.0 0.0042735042735
546 | 235 0.06830078125 27.114893617 27.0 0.00425531914894
547 | 236 0.06830078125 27.1144067797 29.0 0.0650204558738
548 | 237 0.06830078125 29.1223628692 33.0 0.117504155479
549 | 238 0.06830078125 33.1386554622 34.0 0.0253336628769
550 | 239 0.06830078125 34.1422594142 35.0 0.0245068738793
551 | 240 0.06830078125 35.1458333333 37.0 0.0501126126126
552 | 241 0.06830078125 37.153526971 38.0 0.0222756060275
553 | 242 0.06830078125 38.1570247934 39.0 0.0216147488875
554 | 243 0.06830078125 39.1604938272 42.0 0.0676072898295
555 | 244 0.06830078125 42.1721311475 40.0 0.0543032786885
556 | 245 0.06830078125 40.1632653061 39.0 0.0298273155416
557 | 246 0.06830078125 39.1585365854 38.0 0.030487804878
558 | 247 0.06830078125 38.1538461538 38.0 0.00404858299595
559 | 248 0.06830078125 38.1532258065 40.0 0.0461693548387
560 | 249 0.06830078125 40.1606425703 40.0 0.00401606425703
561 | 250 0.06830078125 40.16 38.0 0.0568421052632
562 | 251 0.06830078125 38.1513944223 33.0 0.156102861282
563 | 252 0.06830078125 33.130952381 30.0 0.104365079365
564 | 253 0.06830078125 30.1185770751 28.0 0.0756634669678
565 | 254 0.06830078125 28.1102362205 27.0 0.0411198600175
566 | 255 0.06830078125 27.1058823529 27.0 0.00392156862745
567 | 256 0.06830078125 27.10546875 28.0 0.0319475446429
568 | 257 0.06830078125 28.1089494163 27.0 0.0410722006053
569 | 258 0.06830078125 27.1046511628 27.0 0.00387596899225
570 | 259 0.06830078125 27.1042471042 28.0 0.0319911748483
571 | 260 0.06830078125 28.1076923077 29.0 0.0307692307692
572 | 261 0.06830078125 29.1111111111 33.0 0.117845117845
573 | 262 0.06830078125 33.1259541985 35.0 0.0535441657579
574 | 263 0.06830078125 35.1330798479 36.0 0.0240811153359
575 | 264 0.06830078125 36.1363636364 36.0 0.00378787878788
576 | 265 0.06830078125 36.1358490566 37.0 0.0233554309026
577 | 266 0.06830078125 37.1390977444 37.0 0.00375939849624
578 | 267 0.06830078125 37.138576779 41.0 0.0941810541701
579 | 268 0.06830078125 41.1529850746 39.0 0.0552047455033
580 | 269 0.06830078125 39.1449814126 38.0 0.0301310898063
581 | 270 0.06830078125 38.1407407407 38.0 0.0037037037037
582 | 271 0.06830078125 38.1402214022 37.0 0.0308167946544
583 | 272 0.06830078125 37.1360294118 39.0 0.0477941176471
584 | 273 0.06830078125 39.1428571429 40.0 0.0214285714286
585 | 274 0.06830078125 40.1459854015 37.0 0.0850266324719
586 | 275 0.06830078125 37.1345454545 33.0 0.125289256198
587 | 276 0.06830078125 33.1195652174 29.0 0.142053973013
588 | 277 0.06830078125 29.1046931408 27.0 0.0779515978072
589 | 278 0.06830078125 27.0971223022 27.0 0.00359712230216
590 | 279 0.06830078125 27.0967741935 27.0 0.00358422939068
591 | 280 0.06830078125 27.0964285714 28.0 0.0322704081633
592 | 281 0.06830078125 28.0996441281 27.0 0.0407275603005
593 | 282 0.06830078125 27.0957446809 28.0 0.0322948328267
594 | 283 0.06830078125 28.0989399293 28.0 0.00353356890459
595 | 284 0.06830078125 28.0985915493 29.0 0.0310830500243
596 | 285 0.06830078125 29.101754386 32.0 0.0905701754386
597 | 286 0.06830078125 32.1118881119 34.0 0.0555327025915
598 | 287 0.06830078125 34.118466899 34.0 0.00348432055749
599 | 288 0.06830078125 34.1180555556 35.0 0.0251984126984
600 | 289 0.06830078125 35.1211072664 36.0 0.0244136870434
601 | 290 0.06830078125 36.124137931 37.0 0.0236719478099
602 | 291 0.06830078125 37.1271477663 40.0 0.0718213058419
603 | 292 0.06830078125 40.1369863014 39.0 0.0291534949069
604 | 293 0.06830078125 39.133105802 37.0 0.0576515081635
605 | 294 0.06830078125 37.1258503401 37.0 0.00340136054422
606 | 295 0.06830078125 37.1254237288 37.0 0.00338983050847
607 | 296 0.06830078125 37.125 39.0 0.0480769230769
608 | 297 0.06830078125 39.1313131313 39.0 0.003367003367
609 | 298 0.06830078125 39.1308724832 37.0 0.0575911481952
610 | 299 0.06830078125 37.1237458194 33.0 0.124961994527
611 | 300 0.06830078125 33.11 29.0 0.141724137931
612 | 301 0.06830078125 29.096345515 27.0 0.0776424264796
613 | 302 0.06830078125 27.0894039735 26.0 0.0419001528273
614 | 303 0.06830078125 26.0858085809 27.0 0.0338589414497
615 | 304 0.06830078125 27.0888157895 27.0 0.00328947368421
616 | 305 0.06830078125 27.0885245902 27.0 0.00327868852459
617 | 306 0.06830078125 27.0882352941 28.0 0.0325630252101
618 | 307 0.06830078125 28.0912052117 28.0 0.00325732899023
619 | 308 0.06830078125 28.0909090909 29.0 0.0313479623824
620 | 309 0.06830078125 29.0938511327 32.0 0.0908171521036
621 | 310 0.06830078125 32.1032258065 33.0 0.0271749755621
622 | 311 0.06830078125 33.1061093248 34.0 0.026290902213
623 | 1 0.06830078125 82.0 41.0 41.0
624 | 2 0.06830078125 61.5 42.0 9.05357142857
625 | 3 0.06830078125 56.0 46.0 2.17391304348
626 | 4 0.06830078125 57.5 43.0 4.88953488372
627 | 5 0.06830078125 51.6 42.0 2.19428571429
628 | 6 0.06830078125 49.0 42.0 1.16666666667
629 | 7 0.06830078125 48.0 42.0 0.857142857143
630 | 8 0.06830078125 47.25 44.0 0.240056818182
631 | 9 0.06830078125 48.8888888889 44.0 0.543209876543
632 | 10 0.06830078125 48.4 42.0 0.975238095238
633 | 11 0.06830078125 45.8181818182 38.0 1.60852544585
634 | 12 0.06830078125 41.1666666667 35.0 1.08650793651
635 | 13 0.06830078125 37.6923076923 33.0 0.667204590282
636 | 14 0.06830078125 35.3571428571 33.0 0.168367346939
637 | 15 0.06830078125 35.2 33.0 0.146666666667
638 | 16 0.06830078125 35.0625 32.0 0.293090820313
639 | 17 0.06830078125 33.8823529412 32.0 0.110726643599
640 | 18 0.06830078125 33.7777777778 33.0 0.0183314627759
641 | 19 0.06830078125 34.7368421053 34.0 0.0159687143555
642 | 20 0.06830078125 35.7 35.0 0.014
643 | 21 0.06830078125 36.6666666667 38.0 0.046783625731
644 | 22 0.06830078125 39.7272727273 39.0 0.0135621953804
645 | 23 0.06830078125 40.6956521739 39.0 0.0737240075614
646 | 24 0.06830078125 40.625 41.0 0.00342987804878
647 | 25 0.06830078125 42.64 42.0 0.00975238095238
648 | 26 0.06830078125 43.6153846154 42.0 0.0621301775148
649 | 27 0.06830078125 43.5555555556 46.0 0.129898013956
650 | 28 0.06830078125 47.6428571429 44.0 0.301600185529
651 | 29 0.06830078125 45.5172413793 43.0 0.1473605619
652 | 30 0.06830078125 44.4333333333 43.0 0.0477777777778
653 | 31 0.06830078125 44.3870967742 43.0 0.044745057232
654 | 32 0.06830078125 44.34375 44.0 0.002685546875
655 | 33 0.06830078125 45.3333333333 44.0 0.040404040404
656 | 34 0.06830078125 45.2941176471 42.0 0.258362168397
657 | 35 0.06830078125 43.2 38.0 0.711578947368
658 | 36 0.06830078125 39.0555555556 34.0 0.75172476398
659 | 37 0.06830078125 34.9189189189 32.0 0.266252739226
660 | 38 0.06830078125 32.8421052632 32.0 0.0221606648199
661 | 39 0.06830078125 32.8205128205 32.0 0.0210387902696
662 | 40 0.06830078125 32.8 32.0 0.02
663 | 41 0.06830078125 32.7804878049 32.0 0.0190362879239
664 | 42 0.06830078125 32.7619047619 34.0 0.0450847005469
665 | 43 0.06830078125 34.7906976744 34.0 0.0183883180097
666 | 44 0.06830078125 34.7727272727 35.0 0.00147579693034
667 | 45 0.06830078125 35.7777777778 38.0 0.129954515919
668 | 46 0.06830078125 38.8260869565 39.0 0.000775531966458
669 | 47 0.06830078125 39.829787234 40.0 0.000724309642372
670 | 48 0.06830078125 40.8333333333 40.0 0.0173611111111
671 | 49 0.06830078125 40.8163265306 41.0 0.000822827886755
672 | 50 0.06830078125 41.82 41.0 0.0164
673 | 51 0.06830078125 41.8039215686 45.0 0.2269981631
674 | 52 0.06830078125 45.8653846154 43.0 0.190940209165
675 | 53 0.06830078125 43.8113207547 41.0 0.192768887461
676 | 54 0.06830078125 41.7592592593 41.0 0.0140603566529
677 | 55 0.06830078125 41.7454545455 41.0 0.0135537190083
678 | 56 0.06830078125 41.7321428571 43.0 0.0373828310394
679 | 57 0.06830078125 43.7543859649 43.0 0.0132348414897
680 | 58 0.06830078125 43.7413793103 40.0 0.349947978597
681 | 59 0.06830078125 40.6779661017 36.0 0.60787130135
682 | 60 0.06830078125 36.6 33.0 0.392727272727
683 | 61 0.06830078125 33.5409836066 31.0 0.2082773448
684 | 62 0.06830078125 31.5 31.0 0.00806451612903
685 | 63 0.06830078125 31.4920634921 31.0 0.00781053162006
686 | 64 0.06830078125 31.484375 31.0 0.007568359375
687 | 65 0.06830078125 31.4769230769 32.0 0.00855029585799
688 | 66 0.06830078125 32.4848484848 33.0 0.00804185101706
689 | 67 0.06830078125 33.4925373134 33.0 0.00735130318556
690 | 68 0.06830078125 33.4852941176 34.0 0.00779182780379
691 | 69 0.06830078125 34.4927536232 37.0 0.169899578217
692 | 70 0.06830078125 37.5285714286 39.0 0.055515436944
693 | 71 0.06830078125 39.5492957746 39.0 0.00773656020631
694 | 72 0.06830078125 39.5416666667 39.0 0.00752314814815
695 | 73 0.06830078125 39.5342465753 39.0 0.00731844623757
696 | 74 0.06830078125 39.527027027 39.0 0.00712198685172
697 | 75 0.06830078125 39.52 43.0 0.281637209302
698 | 76 0.06830078125 43.5657894737 41.0 0.160567698129
699 | 77 0.06830078125 41.5324675325 40.0 0.0587114184517
700 | 78 0.06830078125 40.5128205128 40.0 0.00657462195924
701 | 79 0.06830078125 40.5063291139 40.0 0.00640922929018
702 | 80 0.06830078125 40.5 41.0 0.00609756097561
703 | 81 0.06830078125 41.5061728395 41.0 0.00624904740131
704 | 82 0.06830078125 41.5 39.0 0.160256410256
705 | 83 0.06830078125 39.4698795181 35.0 0.570852083031
706 | 84 0.06830078125 35.4166666667 32.0 0.364800347222
707 | 85 0.06830078125 32.3764705882 30.0 0.188253748558
708 | 86 0.06830078125 30.3488372093 29.0 0.0627366143862
709 | 87 0.06830078125 29.3333333333 29.0 0.00383141762452
710 | 88 0.06830078125 29.3295454545 31.0 0.090013496401
711 | 89 0.06830078125 31.3483146067 31.0 0.00391364726676
712 | 90 0.06830078125 31.3444444444 32.0 0.0134297839506
713 | 91 0.06830078125 32.3516483516 32.0 0.00386426760053
714 | 92 0.06830078125 32.347826087 34.0 0.0802846658512
715 | 93 0.06830078125 34.3655913978 37.0 0.187570504948
716 | 94 0.06830078125 37.3936170213 38.0 0.00967632412856
717 | 95 0.06830078125 38.4 38.0 0.00421052631579
718 | 96 0.06830078125 38.3958333333 38.0 0.00412326388889
719 | 97 0.06830078125 38.3917525773 38.0 0.00403868636412
720 | 98 0.06830078125 38.387755102 38.0 0.0039566847147
721 | 99 0.06830078125 38.3838383838 42.0 0.311348210338
722 | 100 0.06830078125 42.42 40.0 0.14641
723 | 101 0.06830078125 40.396039604 39.0 0.0499724763032
724 | 102 0.06830078125 39.3823529412 39.0 0.00374855824683
725 | 103 0.06830078125 39.3786407767 39.0 0.00367612404562
726 | 104 0.06830078125 39.375 41.0 0.0644054878049
727 | 105 0.06830078125 41.3904761905 41.0 0.00371882086168
728 | 106 0.06830078125 41.3867924528 38.0 0.301851661014
729 | 107 0.06830078125 38.3551401869 35.0 0.321627590682
730 | 108 0.06830078125 35.3240740741 31.0 0.603148922519
731 | 109 0.06830078125 31.2844036697 29.0 0.179948280216
732 | 110 0.06830078125 29.2636363636 29.0 0.00239669421488
733 | 111 0.06830078125 29.2612612613 29.0 0.00235370505641
734 | 112 0.06830078125 29.2589285714 29.0 0.0023118622449
735 | 113 0.06830078125 29.2566371681 30.0 0.018419609993
736 | 114 0.06830078125 30.2631578947 31.0 0.0175140738093
737 | 115 0.06830078125 31.2695652174 31.0 0.00234404536862
738 | 116 0.06830078125 31.2672413793 32.0 0.0167792248811
739 | 117 0.06830078125 32.2735042735 35.0 0.212393684189
740 | 118 0.06830078125 35.2966101695 36.0 0.0137432570462
741 | 119 0.06830078125 36.3025210084 37.0 0.0131480255059
742 | 120 0.06830078125 37.3083333333 36.0 0.0475482253086
743 | 121 0.06830078125 36.2975206612 37.0 0.0133372222027
744 | 122 0.06830078125 37.3032786885 37.0 0.00248589088955
745 | 123 0.06830078125 37.3008130081 41.0 0.333755717093
746 | 124 0.06830078125 41.3306451613 38.0 0.291926241853
747 | 125 0.06830078125 38.304 37.0 0.0459571891892
748 | 126 0.06830078125 37.2936507937 37.0 0.00233056185437
749 | 127 0.06830078125 37.2913385827 37.0 0.00229400458801
750 | 128 0.06830078125 37.2890625 39.0 0.0750591571514
751 | 129 0.06830078125 39.3023255814 39.0 0.0023436091581
752 | 130 0.06830078125 39.3 37.0 0.142972972973
753 | 131 0.06830078125 37.2824427481 33.0 0.555736845172
754 | 132 0.06830078125 33.25 30.0 0.352083333333
755 | 133 0.06830078125 30.2255639098 28.0 0.176897668446
756 | 134 0.06830078125 28.2089552239 27.0 0.0541323234573
757 | 135 0.06830078125 27.2 27.0 0.00148148148148
758 | 136 0.06830078125 27.1985294118 27.0 0.00145977508651
759 | 137 0.06830078125 27.197080292 30.0 0.261878629655
760 | 138 0.06830078125 30.2173913043 31.0 0.0197573022745
761 | 139 0.06830078125 31.2230215827 31.0 0.00160447181823
762 | 140 0.06830078125 31.2214285714 31.0 0.00158163265306
763 | 141 0.06830078125 31.219858156 34.0 0.227329078606
764 | 142 0.06830078125 34.2394366197 35.0 0.0165273330122
765 | 143 0.06830078125 35.2447552448 35.0 0.00171157513815
766 | 144 0.06830078125 35.2430555556 36.0 0.0159156914438
767 | 145 0.06830078125 36.2482758621 37.0 0.0152726805283
768 | 146 0.06830078125 37.2534246575 38.0 0.0146677563678
769 | 147 0.06830078125 38.2585034014 41.0 0.183312282935
770 | 148 0.06830078125 41.277027027 39.0 0.132944925175
771 | 149 0.06830078125 39.2617449664 38.0 0.0418947463248
772 | 150 0.06830078125 38.2533333333 38.0 0.00168888888889
773 | 151 0.06830078125 38.2516556291 38.0 0.00166659357046
774 | 152 0.06830078125 38.25 40.0 0.0765625
775 | 153 0.06830078125 40.2614379085 40.0 0.00170874449998
776 | 154 0.06830078125 40.2597402597 38.0 0.134379632671
777 | 155 0.06830078125 38.2451612903 33.0 0.833688392773
778 | 156 0.06830078125 33.2115384615 30.0 0.343799309665
779 | 157 0.06830078125 30.1910828025 28.0 0.171458708844
780 | 158 0.06830078125 28.1772151899 27.0 0.0513272445655
781 | 159 0.06830078125 27.1698113208 27.0 0.00106799572802
782 | 160 0.06830078125 27.16875 27.0 0.0010546875
783 | 161 0.06830078125 27.1677018634 26.0 0.0524433708339
784 | 162 0.06830078125 26.1604938272 27.0 0.0261026153421
785 | 163 0.06830078125 27.1656441718 27.0 0.00101622191276
786 | 164 0.06830078125 27.1646341463 29.0 0.116157510923
787 | 165 0.06830078125 29.1757575758 32.0 0.249260789715
788 | 166 0.06830078125 32.1927710843 34.0 0.0960610692237
789 | 167 0.06830078125 34.2035928144 35.0 0.018121840152
790 | 168 0.06830078125 35.2083333333 37.0 0.0867586336336
791 | 169 0.06830078125 37.2189349112 38.0 0.0160542808651
792 | 170 0.06830078125 38.2235294118 39.0 0.0154591429332
793 | 171 0.06830078125 39.2280701754 42.0 0.182942736959
794 | 172 0.06830078125 42.2441860465 41.0 0.0377560711789
795 | 173 0.06830078125 41.2369942197 39.0 0.128311362532
796 | 174 0.06830078125 39.224137931 39.0 0.00128814902893
797 | 175 0.06830078125 39.2228571429 39.0 0.00127346938776
798 | 176 0.06830078125 39.2215909091 41.0 0.0771399730397
799 | 177 0.06830078125 41.2316384181 41.0 0.00130869162757
800 | 178 0.06830078125 41.2303370787 39.0 0.127548807293
801 | 179 0.06830078125 39.217877095 34.0 0.800771805242
802 | 180 0.06830078125 34.1888888889 30.0 0.584893004115
803 | 181 0.06830078125 30.1657458564 28.0 0.167516254083
804 | 182 0.06830078125 28.1538461538 28.0 0.000845308537616
805 | 183 0.06830078125 28.1530054645 28.0 0.000836095434322
806 | 184 0.06830078125 28.152173913 27.0 0.0491668416999
807 | 185 0.06830078125 27.1459459459 27.0 0.000788897005113
808 | 186 0.06830078125 27.1451612903 27.0 0.000780437044745
809 | 187 0.06830078125 27.1443850267 28.0 0.0261456065168
810 | 188 0.06830078125 28.1489361702 29.0 0.0249761945646
811 | 189 0.06830078125 29.1534391534 33.0 0.448364555948
812 | 190 0.06830078125 33.1736842105 35.0 0.0952979817966
813 | 191 0.06830078125 35.1832460733 36.0 0.0185301937995
814 | 192 0.06830078125 36.1875 38.0 0.0864514802632
815 | 193 0.06830078125 38.1968911917 39.0 0.0165380450757
816 | 194 0.06830078125 39.2010309278 40.0 0.0159587894569
817 | 195 0.06830078125 40.2051282051 43.0 0.181658333716
818 | 196 0.06830078125 43.2193877551 41.0 0.120138585549
819 | 197 0.06830078125 41.2081218274 40.0 0.0364889587467
820 | 198 0.06830078125 40.202020202 40.0 0.00102030405061
821 | 199 0.06830078125 40.2010050251 40.0 0.00101007550314
822 | 200 0.06830078125 40.2 41.0 0.0156097560976
823 | 201 0.06830078125 41.2039800995 41.0 0.00101482636568
824 | 202 0.06830078125 41.202970297 39.0 0.124437900759
825 | 203 0.06830078125 39.1921182266 33.0 1.16188873128
826 | 204 0.06830078125 33.1617647059 30.0 0.333225201845
827 | 205 0.06830078125 30.1463414634 27.0 0.3666468372
828 | 206 0.06830078125 27.1310679612 27.0 0.000636252238665
829 | 207 0.06830078125 27.1304347826 27.0 0.000630119722747
830 | 208 0.06830078125 27.1298076923 27.0 0.000624075443787
831 | 209 0.06830078125 27.1291866029 27.0 0.000618117717085
832 | 210 0.06830078125 27.1285714286 28.0 0.0271209912536
833 | 211 0.06830078125 28.1327014218 28.0 0.000628916691
834 | 212 0.06830078125 28.1320754717 30.0 0.116304734781
835 | 213 0.06830078125 30.1408450704 34.0 0.43803166972
836 | 214 0.06830078125 34.1588785047 35.0 0.0202138677115
837 | 215 0.06830078125 35.1627906977 36.0 0.019469983775
838 | 216 0.06830078125 36.1666666667 36.0 0.000771604938272
839 | 217 0.06830078125 36.1658986175 38.0 0.0885244179275
840 | 218 0.06830078125 38.1743119266 39.0 0.017481046014
841 | 219 0.06830078125 39.1780821918 42.0 0.189600478961
842 | 220 0.06830078125 42.1909090909 40.0 0.120002066116
843 | 221 0.06830078125 40.1809954751 39.0 0.0357628285189
844 | 222 0.06830078125 39.1756756757 39.0 0.000791331872413
845 | 223 0.06830078125 39.1748878924 39.0 0.00078425063846
846 | 224 0.06830078125 39.1741071429 40.0 0.017052475287
847 | 225 0.06830078125 40.1777777778 40.0 0.00079012345679
848 | 226 0.06830078125 40.1769911504 38.0 0.12471817024
849 | 227 0.06830078125 38.1674008811 34.0 0.510800885395
850 | 228 0.06830078125 34.149122807 30.0 0.573840668924
851 | 229 0.06830078125 30.1310043668 28.0 0.16218498612
852 | 230 0.06830078125 28.1217391304 27.0 0.0466036546944
853 | 231 0.06830078125 27.1168831169 27.0 0.000505987518974
854 | 232 0.06830078125 27.1163793103 28.0 0.0278851972567
855 | 233 0.06830078125 28.1201716738 27.0 0.0464735029196
856 | 234 0.06830078125 27.1153846154 27.0 0.000493096646943
857 | 235 0.06830078125 27.114893617 27.0 0.000488909008601
858 | 236 0.06830078125 27.1144067797 29.0 0.122602130779
859 | 237 0.06830078125 29.1223628692 33.0 0.455638476308
860 | 238 0.06830078125 33.1386554622 34.0 0.0218210121419
861 | 239 0.06830078125 34.1422594142 35.0 0.0210205403567
862 | 240 0.06830078125 35.1458333333 37.0 0.0929171358859
863 | 241 0.06830078125 37.153526971 38.0 0.0188556997079
864 | 242 0.06830078125 38.1570247934 39.0 0.0182206974093
865 | 243 0.06830078125 39.1604938272 42.0 0.1919713168
866 | 244 0.06830078125 42.1721311475 40.0 0.117953843053
867 | 245 0.06830078125 40.1632653061 39.0 0.0346970813443
868 | 246 0.06830078125 39.1585365854 38.0 0.0353212373587
869 | 247 0.06830078125 38.1538461538 38.0 0.000622858922454
870 | 248 0.06830078125 38.1532258065 40.0 0.0852643730489
871 | 249 0.06830078125 40.1606425703 40.0 0.000645150884663
872 | 250 0.06830078125 40.16 38.0 0.122778947368
873 | 251 0.06830078125 38.1513944223 33.0 0.804147408916
874 | 252 0.06830078125 33.130952381 30.0 0.326762093726
875 | 253 0.06830078125 30.1185770751 28.0 0.160298886541
876 | 254 0.06830078125 28.1102362205 27.0 0.0456527579722
877 | 255 0.06830078125 27.1058823529 27.0 0.000415224913495
878 | 256 0.06830078125 27.10546875 28.0 0.0285780770438
879 | 257 0.06830078125 28.1089494163 27.0 0.0455469928891
880 | 258 0.06830078125 27.1046511628 27.0 0.000405624661979
881 | 259 0.06830078125 27.1042471042 28.0 0.0286561875089
882 | 260 0.06830078125 28.1076923077 29.0 0.0274556213018
883 | 261 0.06830078125 29.1111111111 33.0 0.458286569398
884 | 262 0.06830078125 33.1259541985 35.0 0.100344219035
885 | 263 0.06830078125 35.1330798479 36.0 0.0208764041695
886 | 264 0.06830078125 36.1363636364 36.0 0.00051652892562
887 | 265 0.06830078125 36.1358490566 37.0 0.0201826176479
888 | 266 0.06830078125 37.1390977444 37.0 0.000522923850981
889 | 267 0.06830078125 37.138576779 41.0 0.363672909548
890 | 268 0.06830078125 41.1529850746 39.0 0.118854993117
891 | 269 0.06830078125 39.1449814126 38.0 0.0344995377708
892 | 270 0.06830078125 38.1407407407 38.0 0.000521262002744
893 | 271 0.06830078125 38.1402214022 37.0 0.0351379688126
894 | 272 0.06830078125 37.1360294118 39.0 0.0890868295848
895 | 273 0.06830078125 39.1428571429 40.0 0.0183673469388
896 | 274 0.06830078125 40.1459854015 37.0 0.267492544492
897 | 275 0.06830078125 37.1345454545 33.0 0.518014124718
898 | 276 0.06830078125 33.1195652174 29.0 0.585200606219
899 | 277 0.06830078125 29.1046931408 27.0 0.164064193219
900 | 278 0.06830078125 27.0971223022 27.0 0.00034936079913
901 | 279 0.06830078125 27.0967741935 27.0 0.000346860908776
902 | 280 0.06830078125 27.0964285714 28.0 0.0291586188047
903 | 281 0.06830078125 28.0996441281 27.0 0.0447858225369
904 | 282 0.06830078125 27.0957446809 28.0 0.0292027743646
905 | 283 0.06830078125 28.0989399293 28.0 0.000349611057698
906 | 284 0.06830078125 28.0985915493 29.0 0.0280185239656
907 | 285 0.06830078125 29.101754386 32.0 0.262494613727
908 | 286 0.06830078125 32.1118881119 34.0 0.104851955942
909 | 287 0.06830078125 34.118466899 34.0 0.00041277665141
910 | 288 0.06830078125 34.1180555556 35.0 0.0222236000882
911 | 289 0.06830078125 35.1211072664 36.0 0.021457012142
912 | 290 0.06830078125 36.124137931 37.0 0.0207333611852
913 | 291 0.06830078125 37.1271477663 40.0 0.206331998914
914 | 292 0.06830078125 40.1369863014 39.0 0.0331471243462
915 | 293 0.06830078125 39.133105802 37.0 0.12297676656
916 | 294 0.06830078125 37.1258503401 37.0 0.000428062381415
917 | 295 0.06830078125 37.1254237288 37.0 0.000425165182419
918 | 296 0.06830078125 37.125 39.0 0.0901442307692
919 | 297 0.06830078125 39.1313131313 39.0 0.000442131755263
920 | 298 0.06830078125 39.1308724832 37.0 0.122719392966
921 | 299 0.06830078125 37.1237458194 33.0 0.515311502515
922 | 300 0.06830078125 33.11 29.0 0.582486206897
923 | 301 0.06830078125 29.096345515 27.0 0.16276535252
924 | 302 0.06830078125 27.0894039735 26.0 0.0456461929807
925 | 303 0.06830078125 26.0858085809 27.0 0.0309535537345
926 | 304 0.06830078125 27.0888157895 27.0 0.000292157202216
927 | 305 0.06830078125 27.0885245902 27.0 0.000290244557915
928 | 306 0.06830078125 27.0882352941 28.0 0.0296898171033
929 | 307 0.06830078125 28.0912052117 28.0 0.000297085380216
930 | 308 0.06830078125 28.0909090909 29.0 0.0284981476204
931 | 309 0.06830078125 29.0938511327 32.0 0.263928163718
932 | 310 0.06830078125 32.1032258065 33.0 0.0243698167944
933 | 311 0.06830078125 33.1061093248 34.0 0.0235011923319
934 |
--------------------------------------------------------------------------------
/machinelearning/getAirElement.py:
--------------------------------------------------------------------------------
1 | import pycurl
2 | import json
3 | import sqlite3
4 | from io import BytesIO
5 |
6 | buffer = BytesIO()
7 |
8 | mycurl = pycurl.Curl()
9 | mycurl.setopt(pycurl.URL, 'http://www.pm25.in/api/querys/all_cities.json')
10 | mycurl.setopt(pycurl.WRITEDATA, buffer)
11 | try:
12 | mycurl.perform()
13 | except Exception as e:
14 | print(Exception, ":", e)
15 | print("")
16 | mycurl.close()
17 |
18 | print("mycurl.perform() over")
19 |
20 | body = buffer.getvalue()
21 | with open("data.dat", "w") as f:
22 | print(body, file=f)
23 |
24 | print(body)
25 |
--------------------------------------------------------------------------------
/sensor/arduino/README.md:
--------------------------------------------------------------------------------
1 | # ThingSpeak平台:
2 | https://cn.mathworks.com/help/thingspeak/get-a-channel-feed.html
3 | ==================================================================
4 | ### 读取例子:
5 | https://api.thingspeak.com/channels/205195.json
6 | https://api.thingspeak.com/channels/205195/feeds.json?results=2
7 | https://api.thingspeak.com/channels/205195/feeds.json?start=2016-12-20%2010:36:17&end=2016-12-20%2021:06:46
8 | https://api.thingspeak.com/channels/205195/feeds/last.json
9 |
--------------------------------------------------------------------------------
/sensor/arduino/sensor/sensor.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define pm25_RX 10
4 | #define pm25_TX 11
5 | #define CO A0
6 | #define SO2 A1
7 | #define O3 A2
8 | #define HCHO A3
9 | #define MQ2 A4
10 |
11 | SoftwareSerial mySerial_pm(pm25_RX, pm25_TX);
12 | float A = 800.0;
13 |
14 | float value_pm25 = 0.0;
15 | float value_CO = 0.0;
16 | float value_SO2 = 0.0;
17 | float value_O3 = 0.0;
18 | float value_HCHO = 0.0;
19 | float value_MQ2 = 0.0;
20 |
21 | void setup() {
22 | // put your setup code here, to run once:
23 | Serial.begin(9600);
24 | mySerial_pm.begin(2400);
25 | pinMode(CO, INPUT);
26 | pinMode(SO2, INPUT);
27 | pinMode(O3, INPUT);
28 | pinMode(HCHO, INPUT);
29 | pinMode(MQ2, INPUT);
30 | }
31 |
32 | void loop() {
33 | // put your main code here, to run repeatedly:
34 | //Serial.println("start");
35 | int temp;
36 | temp = read_pm(pm25_RX, pm25_TX);
37 | if (temp > 0) {
38 | value_pm25 = temp;
39 | }
40 | Serial.print("PM2.5:"); Serial.println(value_pm25);
41 |
42 | value_CO = map(analogRead(CO), 0, 1023, 0, 1000);
43 | Serial.print("CO:"); Serial.println(value_CO);
44 |
45 | value_SO2 = map(analogRead(SO2), 0, 1023, 0, 500);
46 | Serial.print("SO2:"); Serial.println(value_SO2);
47 |
48 | value_O3 = map(analogRead(O3), 0, 1023, 0, 1000);
49 | Serial.print("O3:"); Serial.println(value_O3);
50 |
51 | value_HCHO = map(analogRead(HCHO), 0, 1023, 0, 1000);
52 | Serial.print("HCHO:"); Serial.println(value_HCHO);
53 |
54 | value_MQ2 = map(analogRead(MQ2), 0, 1023, 0, 1000);
55 | Serial.print("MQ2:"); Serial.println(value_MQ2);
56 |
57 | //Serial.println("");
58 | //delay(500);
59 | }
60 |
61 | float read_pm(int RX, int TX) {
62 | int Vout_H, Vout_L, Vret_H, Vret_L, check, temp;
63 | float Vout, Ud = 0.0;
64 |
65 |
66 | int count = 0;
67 | int need_read = mySerial_pm.available();
68 | //Serial.print("need_read : "); Serial.println(need_read);
69 | for (int i = 0; i < need_read; i++) {
70 | temp = mySerial_pm.read();
71 | if (temp == -1) {
72 | continue;
73 | }
74 | //Serial.print(temp);
75 | if (count == 0) {
76 | if (temp != 170) {
77 | continue;
78 | }
79 | count++;
80 | }
81 | else if (count == 1) {
82 | Vout_H = temp;
83 | count++;
84 | }
85 | else if (count == 2) {
86 | Vout_L = temp;
87 | count++;
88 | }
89 | else if (count == 3) {
90 | Vret_H = temp;
91 | count++;
92 | }
93 | else if (count == 4) {
94 | Vret_L = temp;
95 | count++;
96 | }
97 | else if (count == 5) {
98 | check = temp;
99 | count++;
100 | }
101 | else if (count == 6) {
102 | if (temp == 255) {
103 | if (check == (Vout_H + Vout_L + Vret_H + Vret_L) % 256) {
104 | Vout = (Vout_H * 256 + Vout_L) * 1.0 / 1024 * 8;
105 | Ud = 1.0 * A * Vout;
106 | if (Ud > 0) {
107 | break;
108 | }
109 | else {
110 | count = 0;
111 | }
112 | }
113 | }
114 | }
115 | }
116 | return Ud;
117 |
118 | /*
119 | SoftwareSerial mySerial_pm(RX, TX);
120 | mySerial_pm.begin(2400);
121 | //mySerial_pm.flush();
122 | //Serial.println("read_pm");
123 | while (true) {
124 | temp = -1;
125 | while (temp == -1) {
126 | temp = mySerial_pm.read();
127 | Serial.print(temp);
128 | }
129 | Serial.println(temp);
130 | if (temp == 170) {
131 | //Serial.println(temp);
132 | temp = -1;
133 | while (temp == -1) {
134 | temp = mySerial_pm.read();
135 | }
136 | Vout_H = temp;
137 |
138 | temp = -1;
139 | while (temp == -1) {
140 | temp = mySerial_pm.read();
141 | }
142 | Vout_L = temp;
143 |
144 | temp = -1;
145 | while (temp == -1) {
146 | temp = mySerial_pm.read();
147 | }
148 | Vret_H = temp;
149 |
150 | temp = -1;
151 | while (temp == -1) {
152 | temp = mySerial_pm.read();
153 | }
154 | Vret_L = temp;
155 |
156 | temp = -1;
157 | while (temp == -1) {
158 | temp = mySerial_pm.read();
159 | }
160 | check = temp;
161 |
162 | temp = -1;
163 | while (temp == -1) {
164 | temp = mySerial_pm.read();
165 | }
166 | if (temp == 255) {
167 | //Serial.print(Vout_H);Serial.print(" ");Serial.print(Vout_L);Serial.print(" ");Serial.print(Vret_H);Serial.print(" ");Serial.print(Vret_L);Serial.print(" ");Serial.println(check);
168 | if (check == (Vout_H + Vout_L + Vret_H + Vret_L) % 256) {
169 | Vout = (Vout_H * 256 + Vout_L) * 1.0 / 1024 * 8;
170 | Ud = 1.0 * A * Vout;
171 | //Serial.println(Ud);
172 | if (Ud > 0) {
173 | //Serial.println("Ud>0");
174 | //Serial.print(Vout_H);Serial.print(" ");Serial.print(Vout_L);Serial.print(" ");Serial.print(Vret_H);Serial.print(" ");Serial.print(Vret_L);Serial.print(" ");Serial.println(check);
175 | break;
176 | }
177 | }
178 | }
179 | temp = -1;
180 | }
181 | }
182 | return Ud;
183 | */
184 | }
185 |
--------------------------------------------------------------------------------
/sensor/arduino/sensor_old/sensor_old.ino:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #define LED 12
4 | #define CO A0
5 |
6 | int Vout_H, Vout_L, Vret_H, Vret_L, check, temp;
7 | float Vout, Ud;
8 |
9 | int A = 1000;
10 |
11 | SoftwareSerial mySerial(10, 11);
12 |
13 | void setup() {
14 | // put your setup code here, to run once:
15 | Serial.begin(9600);
16 | mySerial.begin(2400);
17 | pinMode(LED, OUTPUT);
18 | pinMode(CO, INPUT);
19 | }
20 |
21 | void loop() {
22 | // put your main code here, to run repeatedly:
23 | temp = -1;
24 | while (temp == -1) {
25 | temp = mySerial.read();
26 | }
27 | if (temp == 170) {
28 | temp = -1;
29 | while (temp == -1) {
30 | temp = mySerial.read();
31 | }
32 | Vout_H = temp;
33 |
34 | temp = -1;
35 | while (temp == -1) {
36 | temp = mySerial.read();
37 | }
38 | Vout_L = temp;
39 |
40 | temp = -1;
41 | while (temp == -1) {
42 | temp = mySerial.read();
43 | }
44 | Vret_H = temp;
45 |
46 | temp = -1;
47 | while (temp == -1) {
48 | temp = mySerial.read();
49 | }
50 | Vret_L = temp;
51 |
52 | temp = -1;
53 | while (temp == -1) {
54 | temp = mySerial.read();
55 | }
56 | check = temp;
57 |
58 | temp = -1;
59 | while (temp == -1) {
60 | temp = mySerial.read();
61 | }
62 | if (temp == 255) {
63 | if (check == (Vout_H + Vout_L + Vret_H + Vret_L) % 256) {
64 | Vout = (Vout_H * 256 + Vout_L) * 1.0 / 1024 * 8;
65 | Ud = 1.0 * A * Vout;
66 | if (Ud > 0) {
67 | Serial.print("pm2.5 : ");
68 | Serial.print(Ud); Serial.println("ppm");
69 |
70 | Serial.print("CO : ");
71 | Serial.print(map(analogRead(CO), 0, 255, 10, 1000));
72 | Serial.println("ppm");
73 |
74 | Serial.println("");
75 | delay(500);
76 | }
77 | }
78 | }
79 | temp = -1;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/sensor/hardware/FWB.ms14:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/hardware/FWB.ms14
--------------------------------------------------------------------------------
/sensor/raspberrypi/GPIO.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/GPIO.jpg
--------------------------------------------------------------------------------
/sensor/raspberrypi/README.md:
--------------------------------------------------------------------------------
1 | # air_monitor
2 | ## 树莓派
3 | ### 要点:
4 | 1. 树莓派的串口是默认当调试口的,所以一定要关闭后才能正常使用该串口:http://blog.csdn.net/xukai871105/article/details/22713925
5 | 2. sudo apt-get install python-pycurl
6 | 3. sudo pip install --upgrade --trusted-host wxpython.org --pre -f http://wxpython.org/Phoenix/snapshot-builds/ wxPython_Phoenix
7 | import wx
8 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/color.py:
--------------------------------------------------------------------------------
1 | import pygame
2 |
3 | white = pygame.Color(255, 255, 255)
4 | black = pygame.Color(0, 0, 0)
5 | grey = pygame.Color(120, 120, 120)
6 | red = pygame.Color(255, 0, 0)
7 | green = pygame.Color(0, 255, 0)
8 | blue = pygame.Color(0, 0, 255)
9 | pink = pygame.Color(255, 0, 156)
10 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/dashboard.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 |
3 | import pygame
4 | import color
5 | import math
6 |
7 | if ~pygame.font.get_init():
8 | pygame.font.init()
9 |
10 |
11 | class DASHBOARD(pygame.sprite.Sprite):
12 | def __init__(self, surface, position, radius, name, color_bg, least, highest):
13 | pygame.sprite.Sprite.__init__(self)
14 | self.surface = surface
15 | self.radius = radius
16 | self.line_width = int(math.ceil(self.radius / 9.0))
17 | self.gap = int(max(math.ceil(self.line_width / 5.0), 2))
18 | self.arc_width = self.line_width
19 | self.position = position
20 | self.name = name.decode('utf-8', 'ignore').encode('gbk')
21 | # print self.name
22 | self.font_width = int(self.arc_width * 1.5)
23 | # self.font = pygame.font.SysFont('楷体', self.font_width)
24 | self.font = pygame.font.Font(None, self.font_width)
25 | self.rect = (self.position[0] - self.radius, self.position[1] - self.radius, self.radius * 2, self.radius * 2)
26 | self.color_bg = color_bg
27 | self.least = least
28 | self.highest = int(highest / 10.0 * 12)
29 | self.scale_gap = int(self.gap / 4.0 * 3)
30 | self.needle_length = self.radius - self.line_width - self.arc_width - self.font_width - (self.gap) * 5
31 | self.needle_width = int(max(self.arc_width / 2.0, 4))
32 | self.origin_radius = int(self.arc_width / 2.0)
33 | self.origin_gap = int(self.scale_gap / 2.0)
34 | self.color_start = color.green
35 | self.color_end = color.red
36 |
37 | def draw(self, value):
38 | self.draw_blendcolor_arc(self.radius, self.line_width, color.grey, color.grey, 0, 360, 20)
39 | self.draw_blendcolor_arc(self.radius - self.line_width - self.gap, self.arc_width, self.color_end,
40 | self.color_start, -60,
41 | 232, 10)
42 | self.draw_scale(self.least, self.highest, self.line_width, self.color_bg, color.white)
43 | self.draw_needle(value, color.red)
44 |
45 | temp_distance = 0
46 | temp_pos = 0
47 | old_font_width = self.font_width
48 | # print self.name
49 | if (self.name == '甲醛'):
50 | # print self.name
51 | # self.font_width = self.font_width / 4 * 3
52 | self.font = pygame.font.Font('wts11.ttf', self.font_width)
53 | temp_distance = self.font_width / 3
54 | temp_pos = 0
55 | elif (self.name == '易燃气体'):
56 | self.font = pygame.font.Font('wts11.ttf', self.font_width)
57 | temp_distance = self.font_width / 3
58 | temp_pos = self.font_width / 2
59 | text_name = self.font.render(self.name.decode('utf-8', 'ignore'), True, color.white)
60 | distance_text_name = self.radius - self.line_width - self.gap - self.font_width - temp_distance
61 | self.surface.blit(text_name, (
62 | self.position[0] - len(self.name) * self.font_width / 5 + temp_pos, self.position[1] + distance_text_name))
63 | temp_distance = 0
64 | temp_pos = 0
65 | self.font_width = old_font_width
66 | self.font = pygame.font.Font(None, self.font_width)
67 |
68 | self.font_width = old_font_width / 2 * 3
69 | self.font = pygame.font.Font(None, self.font_width)
70 | str_value = "%.2f" % value
71 | color_gap = (self.color_end.r - self.color_start.r, self.color_end.g - self.color_start.g,
72 | self.color_end.b - self.color_start.b)
73 | text_color = [self.color_start[0], self.color_start[1], self.color_start[2]]
74 | text_color[0] = int(
75 | self.color_start[0] + (self.color_end[0] - self.color_start[0]) * 1.0 / (self.highest - self.least) * (
76 | value - self.least))
77 | if (text_color[0] < 0):
78 | text_color[0] = 0
79 | elif (text_color[0] > 255):
80 | text_color[0] = 255
81 | text_color[1] = int(
82 | self.color_start[1] + (self.color_end[1] - self.color_start[1]) * 1.0 / (self.highest - self.least) * (
83 | value - self.least))
84 | if (text_color[1] < 0):
85 | text_color[1] = 0
86 | elif (text_color[1] > 255):
87 | text_color[1] = 255
88 | text_color[2] = int(
89 | self.color_start[2] + (self.color_end[2] - self.color_start[2]) * 1.0 / (self.highest - self.least) * (
90 | value - self.least))
91 | if (text_color[2] < 0):
92 | text_color[2] = 0
93 | elif (text_color[2] > 255):
94 | text_color[2] = 255
95 | # print text_color[0], text_color[1], text_color[2], self.name, value, self.least
96 | temp_color = pygame.Color(text_color[0], text_color[1], text_color[2])
97 | text_value = self.font.render(str_value, True, temp_color)
98 | # distance_text_value = self.radius - self.line_width - self.arc_width - self.font_width * 2 - (self.gap) * 6
99 | distance_text_value = self.radius - self.line_width - self.arc_width - self.font_width / 6 * 9 - (self.gap) * 6
100 | # self.surface.blit(text_value, (self.position[0] - self.font_width, self.position[1] + distance_text_value))
101 | self.surface.blit(text_value, (
102 | self.position[0] - len(str_value) * self.font_width / 6, self.position[1] + distance_text_value))
103 | self.font_width = old_font_width
104 | self.font = pygame.font.Font(None, self.font_width)
105 |
106 | def draw_blendcolor_arc(self, radius, width, color_start, color_end, degree_start, degree_stop, step):
107 | color_gap = (color_end.r - color_start.r, color_end.g - color_start.g, color_end.b - color_start.b)
108 | color_i = [color_start[0], color_start[1], color_start[2]]
109 | rect = (self.position[0] - radius, self.position[1] - radius, radius * 2, radius * 2)
110 | for degree in range(degree_start, degree_stop + 1):
111 | color_i[0] = int(
112 | color_start[0] + color_gap[0] * 1.0 / (degree_stop - degree_start) * (degree - degree_start))
113 | color_i[1] = int(
114 | color_start[1] + color_gap[1] * 1.0 / (degree_stop - degree_start) * (degree - degree_start))
115 | color_i[2] = int(
116 | color_start[2] + color_gap[2] * 1.0 / (degree_stop - degree_start) * (degree - degree_start))
117 | pygame.draw.arc(self.surface, color_i, rect, math.radians(degree), math.radians(degree + step), width)
118 |
119 | def draw_scale(self, least, highest, width, color_bg, color_number):
120 | step = (highest - least) / 12
121 | gap_number = [self.font_width / 3 * 1, self.font_width / 3 * 1, 0, self.font_width / 12 * 1,
122 | self.font_width / 20 * 1, self.font_width / 20, self.font_width / 8 * 5, self.font_width / 2 * 2,
123 | self.font_width / 4 * 5, self.font_width / 3 * 4, self.font_width / 4 * 4]
124 | degree_offset_number = [-3, -2, -3, -3, 3, 6, 5, 8, 3, -2, -8]
125 | for i in range(0, 11):
126 | degree = 240 + i * (-30)
127 | rate_cos = math.cos(math.radians(degree))
128 | rate_sin = math.sin(math.radians(degree))
129 | pygame.draw.line(self.surface, color_bg,
130 | (self.position[0] + rate_cos * self.radius, self.position[1] - rate_sin * self.radius), (
131 | self.position[0] + rate_cos * (self.radius - width),
132 | self.position[1] - rate_sin * (self.radius - width)), self.scale_gap)
133 | number = i * step + least
134 | rate_cos = math.cos(math.radians(degree + degree_offset_number[i]))
135 | rate_sin = math.sin(math.radians(degree + degree_offset_number[i]))
136 | text_number = self.font.render(str(number), True, color_number)
137 | radius_number = self.radius - self.line_width - self.arc_width - (self.gap) * 2 - gap_number[i]
138 | self.surface.blit(text_number, (
139 | self.position[0] + rate_cos * radius_number, self.position[1] - rate_sin * radius_number))
140 |
141 | def draw_needle(self, value, color_needle):
142 | degree = 240 - (value - self.least) * 1.0 / (self.highest - self.least) * 360
143 | rate_cos = math.cos(math.radians(degree))
144 | rate_sin = math.sin(math.radians(degree))
145 | position_end = (
146 | int(self.position[0] + rate_cos * self.needle_length),
147 | int(self.position[1] - rate_sin * self.needle_length))
148 | pygame.draw.line(self.surface, color_needle, self.position, position_end, self.needle_width)
149 | pygame.draw.circle(self.surface, color_needle, position_end, int(self.needle_width / 24.0 * 14), 0)
150 | pygame.draw.circle(self.surface, color.white, self.position, self.origin_radius, 0)
151 | pygame.draw.circle(self.surface, self.color_bg, self.position, self.origin_radius - self.origin_gap, 1)
152 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/sensor.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import time
3 | import sensor_api
4 | import yeelink_config
5 | import yeelink_api
6 |
7 | import pygame
8 | import sys
9 | from pygame.locals import *
10 | import dashboard
11 | import color
12 | import random
13 | from time import time
14 |
15 | import pycurl
16 |
17 | _DEBUG_ = False
18 |
19 | MYID = 0
20 | yeelink_config.init(MYID)
21 | device_id = yeelink_config.device_id()
22 | apikey = yeelink_config.apikey()
23 |
24 | time_old = time()
25 |
26 | pygame.init()
27 | pygame.display.set_caption("Demo")
28 | clock = pygame.time.Clock()
29 |
30 | # count = 0
31 |
32 | try:
33 | import wx
34 |
35 | size = wx.GetDisplaySize()
36 | except:
37 | print "Can't find wxpython."
38 | size = pygame.display.list_modes()[len(pygame.display.list_modes()) / 2]
39 |
40 | gap = (int(size[0] / 14), int(size[1] / 9))
41 | radius = min(gap[0], gap[1]) * 2
42 | size = (2 * gap[0] + 6 * radius, gap[1] + 4 * radius)
43 |
44 | # print size
45 |
46 | screen = pygame.display.set_mode(size, FULLSCREEN | HWSURFACE)
47 |
48 | color_bg = color.black
49 |
50 | x_mydashboard = 3
51 | y_mydashboard = 2
52 | mydashboard = {}
53 | values = {}
54 | names = ['PM2.5', 'CO', 'SO2', 'O3', '甲醛'.decode('gbk', 'ignore').encode('utf-8'),
55 | '易燃气体'.decode('gbk', 'ignore').encode('utf-8')]
56 | values_range = {}
57 | values_range[names[0]] = (0, 500)
58 | values_range[names[1]] = (0, 200)
59 | values_range[names[2]] = (0, 100)
60 | values_range[names[3]] = (0, 100)
61 | values_range[names[4]] = (0, 1000)
62 | values_range[names[5]] = (0, 1000)
63 |
64 | for y in range(0, y_mydashboard):
65 | for x in range(0, x_mydashboard):
66 | position = (radius + x * (gap[0] + 2 * radius), radius + y * (gap[1] + 2 * radius))
67 | # mydashboard.append(dashboard.DASHBOARD(screen, position, radius, names[x + y * x_mydashboard], color_bg, 0, 1000))
68 | mydashboard[names[x + y * x_mydashboard]] = dashboard.DASHBOARD(screen, position, radius,
69 | names[x + y * x_mydashboard], color_bg,
70 | values_range[names[x + y * x_mydashboard]][0],
71 | values_range[names[x + y * x_mydashboard]][1])
72 | values[names[x + y * x_mydashboard]] = 0.0
73 |
74 | # values['甲醛'.decode('gbk', 'ignore').encode('utf-8')] = 0.06
75 | # values['易燃气体'.decode('gbk', 'ignore').encode('utf-8')] = 1.35
76 |
77 | pygame.mouse.set_visible(False)
78 |
79 | while True:
80 | for event in pygame.event.get():
81 | if event.type == pygame.QUIT:
82 | sys.exit()
83 | elif event.type == KEYUP:
84 | if event.key == K_ESCAPE:
85 | sys.exit()
86 |
87 | value_pm25 = sensor_api.read_value('PM2.5')
88 | if value_pm25 > 0:
89 | # print "pm2.5 :", value_pm25
90 | values['PM2.5'] = value_pm25
91 |
92 | value_CO = sensor_api.read_value('CO')
93 | if value_CO > 0:
94 | # print "CO :", value_CO
95 | values['CO'] = value_CO
96 |
97 | value_SO2 = sensor_api.read_value('SO2')
98 | if value_SO2 > 0:
99 | # print "SO2 :", value_SO2
100 | values['SO2'] = value_SO2
101 |
102 | value_O3 = sensor_api.read_value('O3')
103 | if value_O3 > 0:
104 | # print "O3 :", value_O3
105 | values['O3'] = value_O3
106 | # values['O3'] = 0
107 |
108 | value_HCHO = sensor_api.read_value('HCHO')
109 | if value_HCHO > 0:
110 | values['甲醛'.decode('gbk', 'ignore').encode('utf-8')] = value_HCHO
111 |
112 | value_MQ2 = sensor_api.read_value('MQ2')
113 | if value_MQ2 > 0:
114 | values['易燃气体'.decode('gbk', 'ignore').encode('utf-8')] = value_MQ2
115 |
116 | time_now = time()
117 | if time_now - time_old > 10:
118 | # print "tick", time_now - time_old
119 | time_old = time_now
120 |
121 | if not _DEBUG_:
122 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_pm25_id(), values['PM2.5'])
123 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_CO_id(), values['CO'])
124 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_SO2_id(), values['SO2'])
125 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_O3_id(), values['O3'])
126 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_HCHO_id(),
127 | values['甲醛'.decode('gbk', 'ignore').encode('utf-8')])
128 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_MQ2_id(),
129 | values['易燃气体'.decode('gbk', 'ignore').encode('utf-8')])
130 |
131 | mycurl = pycurl.Curl()
132 | mycurl.setopt(mycurl.URL, 'http://www.zhangshengdong.com/weixin/warningtemplate.php')
133 | try:
134 | mycurl.perform()
135 | except Exception, e:
136 | print Exception, ":", e
137 | # print ""
138 | mycurl.close()
139 |
140 | # print ""
141 |
142 | screen.fill(color_bg)
143 |
144 | for y in range(0, y_mydashboard):
145 | for x in range(0, x_mydashboard):
146 | mydashboard[names[x + y * x_mydashboard]].draw(values[names[x + y * x_mydashboard]])
147 |
148 | pygame.display.flip()
149 | clock.tick(10)
150 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/sensor_api.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 | import RPi.GPIO as GPIO
3 | import serial
4 | import smbus
5 |
6 | _DEBUG_ = False
7 |
8 |
9 | class SENSOR_CONFIG():
10 | serial_0 = serial.Serial("/dev/ttyUSB0", 9600)
11 | value_pm = -1
12 | value_CO = -1
13 | value_SO2 = -1
14 | value_O3 = -1
15 | value_HCHO = -1
16 | value_MQ2 = -1
17 |
18 |
19 | GPIO.setmode(GPIO.BOARD)
20 |
21 | sensor_config = SENSOR_CONFIG()
22 |
23 |
24 | def read_value(sensor_name):
25 | waitlen = sensor_config.serial_0.inWaiting()
26 | if waitlen != 0:
27 | recv = sensor_config.serial_0.read(waitlen)
28 | recv = bytes(recv)
29 | #print(recv)
30 | try:
31 | recv_split = recv.split('\n')
32 | except:
33 | recv_split = recv.split(b'\n')
34 | #print(recv_split)
35 | for message in recv_split:
36 | try:
37 | message_split = message.split(':')
38 | except:
39 | message_split = message.split(b':')
40 | #print(message_split)
41 | if len(message_split) > 1:
42 | name = message_split[0]
43 | value_str = message_split[1]
44 | try:
45 | value = float(value_str.strip())
46 | # print name, "--", value
47 | except:
48 | continue
49 | #print(sensor_name,name,value)
50 | if value > 0:
51 | if name == b"PM2.5":
52 | sensor_config.value_pm = value
53 | if sensor_name == "PM2.5":
54 | return sensor_config.value_pm
55 | elif name == b"CO":
56 | sensor_config.value_CO = value
57 | if sensor_name == "CO":
58 | return sensor_config.value_CO
59 | elif name == b"SO2":
60 | sensor_config.value_SO2 = value
61 | if sensor_name == "SO2":
62 | return sensor_config.value_SO2
63 | elif name == b"O3":
64 | sensor_config.value_O3 = value
65 | if sensor_name == "O3":
66 | return sensor_config.value_O3
67 | elif name == b"HCHO":
68 | sensor_config.value_HCHO = value
69 | if sensor_name == "HCHO":
70 | return sensor_config.value_HCHO
71 | elif name == b"MQ2":
72 | sensor_config.value_MQ2 = value
73 | if sensor_name == "MQ2":
74 | return sensor_config.value_MQ2
75 | if sensor_name == "PM2.5":
76 | return sensor_config.value_pm
77 | elif sensor_name == "CO":
78 | return sensor_config.value_CO
79 | elif sensor_name == "SO2":
80 | return sensor_config.value_SO2
81 | elif sensor_name == "O3":
82 | return sensor_config.value_O3
83 | elif sensor_name == "HCHO":
84 | return sensor_config.value_HCHO
85 | else:
86 | return sensor_config.value_MQ2
87 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/sensor_api_old.py:
--------------------------------------------------------------------------------
1 | # -*- coding:utf-8 -*-
2 |
3 | import RPi.GPIO as GPIO
4 | import serial
5 | import smbus
6 |
7 | _DEBUG_ = False
8 |
9 |
10 | class SENSOR_CONFIG():
11 | serial_0 = serial.Serial("/dev/ttyS0", 2400)
12 | A = 1200
13 |
14 | address = 0x48
15 | # 元件上的标号是反的,A0应该在A2的位置,另外A3貌似没用
16 | #A0 = 0x40
17 | #A1 = 0x41
18 | #A2 = 0x42
19 | #A3 = 0x43
20 | A0 = 0x00
21 | A1 = 0x01
22 | A2 = 0x02
23 | A3 = 0x03
24 |
25 | bus = smbus.SMBus(1)
26 |
27 |
28 | GPIO.setmode(GPIO.BOARD)
29 |
30 | sensor_config = SENSOR_CONFIG()
31 |
32 |
33 | def read_pm25():
34 | result = -1
35 | Vout_H = 0
36 | Vout_L = 0
37 | Vret_H = 0
38 | Vret_L = 0
39 | check = 0
40 | waitlen = sensor_config.serial_0.inWaiting()
41 | if _DEBUG_:
42 | print "waitlen : sensor_api", waitlen
43 | if waitlen != 0:
44 | recv = sensor_config.serial_0.read(waitlen)
45 | listhex = [ord(i) for i in recv]
46 | if _DEBUG_:
47 | print listhex
48 | count = 0
49 | old_i = 0
50 | i = 0
51 | while i < len(listhex) - 1:
52 | # for i in range(len(listhex)):
53 | if count == 0:
54 | if listhex[i] == 170:
55 | old_i = i
56 | count += 1
57 | Vout_H = 0
58 | Vout_L = 0
59 | Vret_H = 0
60 | Vret_L = 0
61 | check = 0
62 | else:
63 | count += 1
64 | if count == 2:
65 | Vout_H = listhex[i]
66 | elif count == 3:
67 | Vout_L = listhex[i]
68 | elif count == 4:
69 | Vret_H = listhex[i]
70 | elif count == 5:
71 | Vret_L = listhex[i]
72 | elif count == 6:
73 | check = listhex[i]
74 | elif count == 7:
75 | count = 0
76 | if _DEBUG_:
77 | print Vout_H, Vout_L, Vret_H, Vret_L, check, listhex[i]
78 | if listhex[i] == 255:
79 | if check == (Vout_H + Vout_L + Vret_H + Vret_L) % 256:
80 | Vout = (Vout_H * 256 + Vout_L) * 1.0 / 1024 * 5
81 | Ud = 1.0 * sensor_config.A * Vout
82 | if _DEBUG_:
83 | print Vout, Ud
84 | if Ud > 0:
85 | result = Ud
86 | break
87 | i = old_i
88 | i += 1
89 | return result
90 |
91 |
92 | def read_CO():
93 | sensor_config.bus.write_byte(sensor_config.address, sensor_config.A0)
94 | value_CO = sensor_config.bus.read_byte(sensor_config.address) * 1.0 / 256 * 1000
95 | if value_CO > 0:
96 | return value_CO
97 | else:
98 | return -1
99 |
100 |
101 | def read_SO2():
102 | sensor_config.bus.write_byte(sensor_config.address, sensor_config.A1)
103 | value_SO2 = sensor_config.bus.read_byte(sensor_config.address) * 1.0 / 256 * 500
104 | if value_SO2 > 0:
105 | return value_SO2
106 | else:
107 | return -1
108 |
109 |
110 | def read_O3():
111 | sensor_config.bus.write_byte(sensor_config.address, sensor_config.A2)
112 | value_O3 = sensor_config.bus.read_byte(sensor_config.address) * 1.0 / 256 * 1000
113 | if value_O3 > 0:
114 | return value_O3
115 | else:
116 | return -1
117 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/sensor_backup.py:
--------------------------------------------------------------------------------
1 | import time
2 | import sensor_api
3 | import yeelink_config
4 | import yeelink_api
5 |
6 | _DEBUG_ = True
7 |
8 | MYID = 1
9 | yeelink_config.init(MYID)
10 | device_id = yeelink_config.device_id()
11 | apikey = yeelink_config.apikey()
12 |
13 | while True:
14 | value_pm25 = sensor_api.read_pm25()
15 | if value_pm25 > 0:
16 | print "pm2.5 :", value_pm25
17 | if not _DEBUG_:
18 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_pm25_id(), value_pm25)
19 |
20 | value_CO = sensor_api.read_CO()
21 | if value_CO > 0:
22 | print "CO :", value_CO
23 | if not _DEBUG_:
24 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_CO_id(), value_CO)
25 |
26 | value_SO2 = sensor_api.read_SO2()
27 | if value_SO2 > 0:
28 | print "SO2 :", value_SO2
29 | if not _DEBUG_:
30 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_SO2_id(), value_SO2)
31 |
32 | value_O3 = sensor_api.read_O3()
33 | if value_O3 > 0:
34 | print "O3 :", value_O3
35 | if not _DEBUG_:
36 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_O3_id(), value_O3)
37 |
38 | print ""
39 |
40 | # print "sleep"
41 | time.sleep(15)
42 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/sensor_old.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import time
3 | import sensor_api
4 | import yeelink_config
5 | import yeelink_api
6 |
7 | import pygame
8 | import sys
9 | from pygame.locals import *
10 | import dashboard
11 | import color
12 | import random
13 | from time import time
14 |
15 | import pycurl
16 |
17 | import RPi.GPIO as GPIO
18 | # BOARD编号方式,基于插座引脚编号
19 | GPIO.setmode(GPIO.BOARD)
20 | # 输出模式
21 | GPIO.setup(17,GPIO.OUT)
22 | GPIO.setup(18,GPIO.OUT)
23 | GPIO.output(17,GPIO.HIGH)
24 | GPIO.output(18,GPIO.LOW)
25 |
26 | _DEBUG_ = True
27 |
28 | MYID = 0
29 | yeelink_config.init(MYID)
30 | device_id = yeelink_config.device_id()
31 | apikey = yeelink_config.apikey()
32 |
33 | time_old = time()
34 |
35 | pygame.init()
36 | pygame.display.set_caption("Demo")
37 | clock = pygame.time.Clock()
38 |
39 | try:
40 | import wx
41 |
42 | size = wx.GetDisplaySize()
43 | except:
44 | print "Can't find wxpython."
45 | size = pygame.display.list_modes()[len(pygame.display.list_modes()) / 2]
46 |
47 | gap = (int(size[0] / 14), int(size[1] / 9))
48 | radius = min(gap[0], gap[1]) * 2
49 | size = (2 * gap[0] + 6 * radius, gap[1] + 4 * radius)
50 |
51 | # print size
52 |
53 | screen = pygame.display.set_mode(size, FULLSCREEN | HWSURFACE)
54 |
55 | color_bg = color.black
56 |
57 | x_mydashboard = 3
58 | y_mydashboard = 2
59 | mydashboard = {}
60 | values = {}
61 | names = ['PM2.5', 'CO', 'SO2', 'O3', '甲醛'.decode('gbk', 'ignore').encode('utf-8'),
62 | '易燃气体'.decode('gbk', 'ignore').encode('utf-8')]
63 | values_range = {}
64 | values_range[names[0]] = (0, 500)
65 | values_range[names[1]] = (0, 200)
66 | values_range[names[2]] = (0, 50)
67 | values_range[names[3]] = (0, 50)
68 | values_range[names[4]] = (0, 1000)
69 | values_range[names[5]] = (0, 1000)
70 |
71 | for y in range(0, y_mydashboard):
72 | for x in range(0, x_mydashboard):
73 | position = (radius + x * (gap[0] + 2 * radius), radius + y * (gap[1] + 2 * radius))
74 | # mydashboard.append(dashboard.DASHBOARD(screen, position, radius, names[x + y * x_mydashboard], color_bg, 0, 1000))
75 | mydashboard[names[x + y * x_mydashboard]] = dashboard.DASHBOARD(screen, position, radius,
76 | names[x + y * x_mydashboard], color_bg,
77 | values_range[names[x + y * x_mydashboard]][0],
78 | values_range[names[x + y * x_mydashboard]][1])
79 | values[names[x + y * x_mydashboard]] = 0.0
80 |
81 | values['甲醛'.decode('gbk', 'ignore').encode('utf-8')] = 0.06
82 | values['易燃气体'.decode('gbk', 'ignore').encode('utf-8')] = 1.35
83 |
84 | while True:
85 | for event in pygame.event.get():
86 | if event.type == pygame.QUIT:
87 | sys.exit()
88 | elif event.type == KEYUP:
89 | if event.key == K_ESCAPE:
90 | sys.exit()
91 |
92 | value_pm25 = sensor_api.read_pm25()
93 | if value_pm25 > 0:
94 | # print "pm2.5 :", value_pm25
95 | values['PM2.5'] = value_pm25
96 |
97 | value_CO = sensor_api.read_CO()
98 | if value_CO > 0:
99 | # print "CO :", value_CO
100 | values['CO'] = value_CO
101 |
102 | value_SO2 = sensor_api.read_SO2()
103 | if value_SO2 > 0:
104 | # print "SO2 :", value_SO2
105 | values['SO2'] = value_SO2
106 |
107 | value_O3 = sensor_api.read_O3()
108 | if value_O3 > 0:
109 | # print "O3 :", value_O3
110 | values['O3'] = value_O3
111 | # values['O3'] = 0
112 |
113 | time_now = time()
114 | if time_now - time_old > 15:
115 | # print "tick", time_now - time_old
116 | time_old = time_now
117 |
118 | if not _DEBUG_:
119 | print "send value", values['CO'], values['SO2']
120 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_pm25_id(), values['PM2.5'])
121 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_CO_id(), values['CO'])
122 | yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_SO2_id(), values['SO2'])
123 | # yeelink_api.send_value(apikey, device_id, yeelink_config.sensor_O3_id(), values['O3'])
124 |
125 | mycurl = pycurl.Curl()
126 | mycurl.setopt(mycurl.URL, 'http://www.zhangshengdong.com/weixin/warningtemplate.php')
127 | try:
128 | mycurl.perform()
129 | except Exception, e:
130 | print Exception, ":", e
131 | mycurl.close()
132 |
133 | # print ""
134 |
135 | screen.fill(color_bg)
136 |
137 | for y in range(0, y_mydashboard):
138 | for x in range(0, x_mydashboard):
139 | mydashboard[names[x + y * x_mydashboard]].draw(values[names[x + y * x_mydashboard]])
140 |
141 | pygame.display.flip()
142 | clock.tick(10)
143 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/shell.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import sensor_api
3 | from time import time as time_func
4 | import time
5 | import os
6 | import sys
7 | import serial
8 |
9 | path_BEIDOU = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), "beidou")
10 | sys.path.append(path_BEIDOU)
11 | from beidou import TXA
12 |
13 | serial_BEIDOU = serial.Serial("/dev/ttyUSB1", 115200)
14 | txa = TXA(user_address='0247718', serial=serial_BEIDOU, transfer_method='1')
15 | txa.read()
16 |
17 | _DEBUG_ = False
18 |
19 | time_old = time_func()
20 |
21 | values = {}
22 | names = ['PM2.5', 'CO', 'SO2', 'O3', 'HCHO', 'MQ2']
23 |
24 | txa.send(b"$CCICI,0,00*73\r\n")
25 |
26 | while True:
27 |
28 | value_pm25 = sensor_api.read_value('PM2.5')
29 | if value_pm25 > 0:
30 | # print("\t\tpm2.5 :", value_pm25)
31 | values['PM25'] = value_pm25
32 |
33 | value_CO = sensor_api.read_value('CO')
34 | if value_CO > 0:
35 | # print("\t\tCO :", value_CO)
36 | values['CO'] = value_CO
37 |
38 | value_SO2 = sensor_api.read_value('SO2')
39 | if value_SO2 > 0:
40 | # print("\t\tSO2 :", value_SO2)
41 | values['SO2'] = value_SO2
42 |
43 | value_O3 = sensor_api.read_value('O3')
44 | if value_O3 > 0:
45 | # print("\t\tO3 :", value_O3)
46 | values['O3'] = value_O3
47 |
48 | value_HCHO = sensor_api.read_value('HCHO')
49 | if value_HCHO > 0:
50 | # print("\t\tHCHO :", value_HCHO)
51 | values['HCHO'] = value_HCHO
52 |
53 | value_MQ2 = sensor_api.read_value('MQ2')
54 | if value_MQ2 > 0:
55 | # print("\t\tMQ2 :", value_MQ2)
56 | values['MQ2'] = value_MQ2
57 |
58 | time_now = time_func()
59 | if time_now - time_old > 60:
60 | time_old = time_now
61 | '''content = "PM2.5:" + values['PM25'] + ",CO:" + values['CO'] + ",SO2:" + values['SO2'] + ",O3:" + values[
62 | 'O3'] + ",HCHO:" + values['HCHO'] + ",MQ2:" + values['MQ2']'''
63 | content = "PM25" + str(value_pm25) + "CO" + str(value_CO) + "SO2" + str(value_SO2) + "O3" + str(
64 | value_O3) + "HCHO" + str(value_HCHO) + "MQ2" + str(value_MQ2)
65 | '''content = "PM2.5-" + str(values['PM25']) + "--CO-" + str(values['CO']) + "--SO2-" + str(values['SO2']) + "--O3-" + str(
66 | values['O3']) + "--HCHO-" + str(value_HCHO) + "--MQ2-" + str(value_MQ2)'''
67 | message = txa.message(content=content)
68 | print("\t\t", message)
69 | txa.send(message=message)
70 |
71 | time.sleep(1)
72 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/test.py:
--------------------------------------------------------------------------------
1 | import serial
2 | import time
3 |
4 | serial_0 = serial.Serial("/dev/ttyUSB0", 9600)
5 |
6 | while True:
7 | waitlen = serial_0.inWaiting()
8 | if waitlen != 0:
9 | recv = serial_0.read(waitlen)
10 | recv_split = recv.split('\n')
11 | for message in recv_split:
12 | message_split = message.split(':')
13 | if len(message_split) > 1:
14 | name = message_split[0]
15 | value_str = message_split[1]
16 | try:
17 | value = float(value_str)
18 | print name, "--", value
19 | except:
20 | pass
21 | time.sleep(0.1)
22 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/test1.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 |
3 | def XOR_CheckSum_string(m_str, encoding="ascii"):
4 | if str == type(m_str):
5 | try:
6 | m_str = bytes(m_str, encoding=encoding)
7 | except:
8 | # m_str = bytes(m_str)
9 | m_str = m_str.encode(encoding=encoding)
10 | sum = 0x0
11 | # print(m_str)
12 | # print(type(m_str))
13 | for c in m_str:
14 | try:
15 | sum = sum ^ c
16 | except:
17 | # print(c)
18 | sum = sum ^ ord(c)
19 | sum = sum ^ 0x0
20 | return sum
21 |
22 | msg = b'\xb3\xb1\xb3\xb2\xb3\xb3\xb3\xb4\xb3\xb5'
23 | print(msg)
24 | print(str(msg))
25 | print(msg.decode('GB18030').encode('utf-8'))
26 | print(msg.decode('GBK'))
27 | print(msg.decode('GB2312'))
28 | print(msg.decode('utf-16'))
29 | # print(msg.decode('utf-8'))
30 |
31 | msg = b'\xB9\xE3\xD6\xDD\xBA\xA3\xC1\xC4\xBF\xC6\xBC\xBC\xD3\xD0\xCF\xDE\xB9\xAB\xCB\xBE'
32 | print(msg.decode('GB2312'))
33 |
34 | print("广州海聊科技有限公司".encode(encoding="gb2312"))
35 | print(bytes("广州海聊科技有限公司", 'gb2312'))
36 | print(b'\xA4' + bytes("广州海聊科技..有限公--司12就3a给bc.-", 'gb2312'))
37 | print((b'\xA4' + bytes("广州海聊科技..有限公--司12就3a给bc.-", 'gb2312'))[1:])
38 |
39 | # msg=b'\xb9\xe3\xd6\xdd\xba\xa3\xc1\xc4\xbf\xc6\xbc\xbc..\xd3\xd0\xcf\xde\xb9\xab--\xcb\xbe12\xbe\xcd3a\xb8\xf8bc.-'
40 | msg = (b'\xA4' + bytes("广州海聊科技..有限公--司12就3a给bc.-", 'gb2312'))[1:]
41 | print(msg.decode('GB2312'))
42 |
43 | print(bytes("\xA4广州海聊科技有限公司", 'gb2312'))
44 |
45 | test_msg=bytes("CCTXA,0242407,1,2,",'gb2312')+b'\xA4'+bytes("广州海聊科技有限公司", 'gb2312')
46 | #test_msg=b'$CCTXA,0242407,1,2,A4B9E3D6DDBAA3C1C4BFC6BCBCD3D0CFDEB9ABCBBE*0F'
47 | print(test_msg)
48 | print(hex(XOR_CheckSum_string(test_msg)))
49 |
50 | print(hex(XOR_CheckSum_string(bytes("CCTXA,0242407,1,2,",'utf-8')+bytes("0123456789ABCDEF", 'utf-8'))))
51 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/test_pygame.py:
--------------------------------------------------------------------------------
1 | # coding=utf-8
2 | import pygame
3 | import sys
4 | from pygame.locals import *
5 | import dashboard
6 | import color
7 | import random
8 | from time import time
9 |
10 | time_old = time()
11 |
12 | pygame.init()
13 | pygame.display.set_caption("Demo")
14 | clock = pygame.time.Clock()
15 |
16 | try:
17 | import wx
18 |
19 | size = wx.GetDisplaySize()
20 | except:
21 | print "Can't find wxpython."
22 | size = pygame.display.list_modes()[len(pygame.display.list_modes()) / 2]
23 |
24 | gap = (int(size[0] / 14), int(size[1] / 9))
25 | radius = min(gap[0], gap[1]) * 2
26 | size = (2 * gap[0] + 6 * radius, gap[1] + 4 * radius)
27 |
28 | # print size
29 |
30 | screen = pygame.display.set_mode(size, FULLSCREEN | HWSURFACE)
31 |
32 | color_bg = color.black
33 |
34 | x_mydashboard = 3
35 | y_mydashboard = 2
36 | mydashboard = []
37 |
38 | names = ['PM2.5', 'CO', 'SO2', 'O3', '甲醛'.decode('gbk', 'ignore').encode('utf-8'), '易燃气体'.decode('gbk', 'ignore').encode('utf-8')]
39 |
40 | for y in range(0, y_mydashboard):
41 | for x in range(0, x_mydashboard):
42 | position = (radius + x * (gap[0] + 2 * radius), radius + y * (gap[1] + 2 * radius))
43 | mydashboard.append(
44 | dashboard.DASHBOARD(screen, position, radius, names[x + y * x_mydashboard], color_bg, 0, 1000))
45 |
46 | while True:
47 | for event in pygame.event.get():
48 | if event.type == pygame.QUIT:
49 | sys.exit()
50 | elif event.type == KEYUP:
51 | if event.key == K_ESCAPE:
52 | sys.exit()
53 |
54 | time_now = time()
55 | if time_now - time_old > 15:
56 | print "tick", time_now - time_old
57 | time_old = time_now
58 |
59 | screen.fill(color_bg)
60 |
61 | for i in range(0, x_mydashboard * y_mydashboard):
62 | mydashboard[i].draw(random.uniform(0, 1000))
63 |
64 | pygame.display.flip()
65 | # pygame.time.delay(100)
66 | clock.tick(5)
67 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/test_tkinter.py:
--------------------------------------------------------------------------------
1 | from Tkinter import *
2 |
3 | class Application(Frame):
4 | def say_hi(self):
5 | print "hi there, everyone!"
6 |
7 | def print_contents(self, event):
8 | print "hi. contents of entry is now ---->", self.contents.get()
9 |
10 | def createWidgets(self):
11 | self.QUIT = Button(self)
12 | self.QUIT["text"] = "QUIT"
13 | self.QUIT["fg"] = "red"
14 | self.QUIT["command"] = self.quit
15 | self.QUIT.pack({"side": "left"})
16 |
17 | self.hi_there = Button(self)
18 | self.hi_there["text"] = "Hello",
19 | self.hi_there["command"] = self.say_hi
20 | self.hi_there.pack({"side": "left"})
21 |
22 | self.contents = StringVar()
23 | self.contents.set("this is a variable")
24 |
25 | self.entrythingy = Entry()
26 | self.entrythingy.pack()
27 | self.entrythingy["textvariable"] = self.contents
28 | self.entrythingy.bind('',self.print_contents) #Enter
29 |
30 | def __init__(self, master=None):
31 | Frame.__init__(self, master)
32 | self.pack()
33 | self.createWidgets()
34 |
35 |
36 |
37 |
38 |
39 | root = Tk()
40 | app = Application(master=root)
41 | app.master.title("My Do-Nothing Application")
42 | app.master.maxsize(1000, 400)
43 | print "loop start"
44 | app.mainloop()
45 | print "loop end"
46 | try:
47 | root.destroy()
48 | except:
49 | print "end"
50 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/wts11.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/wts11.ttf
--------------------------------------------------------------------------------
/sensor/raspberrypi/yeelink_api.py:
--------------------------------------------------------------------------------
1 | import pycurl
2 | import json
3 | import thread
4 |
5 |
6 | # import StringIO
7 |
8 | def send_value_raw(apikey, device_id, sensor_id, value):
9 | # print device_id, sensor_id, value
10 | mycurl = pycurl.Curl()
11 | mycurl.setopt(mycurl.URL,
12 | 'http://api.yeelink.net/v1.0/device/' + device_id + '/sensor/' + sensor_id + '/datapoints')
13 | mycurl.setopt(mycurl.HTTPHEADER, ["U-ApiKey:" + apikey])
14 | mycurl.setopt(mycurl.POSTFIELDS, json.dumps({"value": value}))
15 | try:
16 | mycurl.perform()
17 | except Exception, e:
18 | print Exception, ":", e
19 | # print ""
20 | mycurl.close()
21 | # thread.exit_thread()
22 |
23 | def send_value(apikey, device_id, sensor_id, value):
24 | thread.start_new_thread(send_value_raw,(apikey, device_id, sensor_id, value))
25 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/yeelink_config.py:
--------------------------------------------------------------------------------
1 | class MYCONFIG():
2 | device_id = ''
3 | sensor_pm25_id = ''
4 | sensor_CO_id = ''
5 | sensor_SO2_id = ''
6 | sensor_O3_id = ''
7 | sensor_HCHO_id = ''
8 | sensor_MQ2_id = ''
9 | apikey = "779bfd896876dc377d3ed78d0fa1dbf4"
10 |
11 |
12 | myconfig = MYCONFIG()
13 |
14 |
15 | def init(myid):
16 | if myid == 0:
17 | myconfig.device_id = '353097'
18 | myconfig.sensor_pm25_id = '397985'
19 | myconfig.sensor_CO_id = '398391'
20 | myconfig.sensor_SO2_id = '400110'
21 | myconfig.sensor_O3_id = '400118'
22 | myconfig.sensor_HCHO_id = '403705'
23 | myconfig.sensor_MQ2_id = '403706'
24 | elif myid == 1:
25 | myconfig.device_id = '354298'
26 | myconfig.sensor_pm25_id = '400108'
27 | myconfig.sensor_CO_id = '400109'
28 | myconfig.sensor_SO2_id = '400111'
29 | myconfig.sensor_O3_id = '400119'
30 | myconfig.sensor_HCHO_id = '403707'
31 | myconfig.sensor_MQ2_id = '403708'
32 |
33 |
34 | def apikey():
35 | return myconfig.apikey
36 |
37 |
38 | def device_id():
39 | return myconfig.device_id
40 |
41 |
42 | def sensor_pm25_id():
43 | return myconfig.sensor_pm25_id
44 |
45 |
46 | def sensor_CO_id():
47 | return myconfig.sensor_CO_id
48 |
49 |
50 | def sensor_SO2_id():
51 | return myconfig.sensor_SO2_id
52 |
53 |
54 | def sensor_O3_id():
55 | return myconfig.sensor_O3_id
56 |
57 |
58 | def sensor_HCHO_id():
59 | return myconfig.sensor_HCHO_id
60 |
61 |
62 | def sensor_MQ2_id():
63 | return myconfig.sensor_MQ2_id
64 |
--------------------------------------------------------------------------------
/sensor/raspberrypi/仪表盘.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/仪表盘.png
--------------------------------------------------------------------------------
/sensor/raspberrypi/仪表盘1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/仪表盘1.jpg
--------------------------------------------------------------------------------
/sensor/raspberrypi/仪表盘2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/仪表盘2.jpg
--------------------------------------------------------------------------------
/sensor/raspberrypi/界面_0.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/sensor/raspberrypi/界面_0.png
--------------------------------------------------------------------------------
/server/weixin/access_token.dat:
--------------------------------------------------------------------------------
1 | 1486728855
--------------------------------------------------------------------------------
/server/weixin/can_scanf:
--------------------------------------------------------------------------------
1 | 1
--------------------------------------------------------------------------------
/server/weixin/index.php:
--------------------------------------------------------------------------------
1 | responseMsg();
11 | } else {
12 | $wechatObj->valid();
13 | }
14 |
15 | class wechatCallbackapiTest
16 | {
17 | private $access_token = "";
18 | private $time_expires_in = -1;
19 |
20 | public function valid()
21 | {
22 | $echoStr = $_GET["echostr"];
23 |
24 | //valid signature , option
25 | if ($this->checkSignature()) {
26 | echo $echoStr;
27 | exit;
28 | }
29 | }
30 |
31 | /**
32 | *
33 | */
34 | public function responseMsg()
35 | {
36 | //get post data, May be due to the different environments
37 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
38 |
39 | //extract post data
40 | if (!empty($postStr)) {
41 | /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
42 | the best way is to check the validity of xml by yourself */
43 | libxml_disable_entity_loader(true);
44 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
45 | $fromUsername = $postObj->FromUserName;
46 | $toUsername = $postObj->ToUserName;
47 | $msgType = $postObj->MsgType;
48 | if ($msgType == "text") {
49 | $keyword = trim($postObj->Content);
50 | if ($keyword == "debug") {
51 | $time = time();
52 | $msgType = "text";
53 | $textTpl = "
54 |
55 |
56 | %s
57 |
58 |
59 | 0
60 | ";
61 |
62 | $device_id = 353097;
63 | $sensor_id = 397985;
64 | $durl = "http://api.yeelink.net/v1.0/device/$device_id/sensor/$sensor_id/datapoints";
65 | //$data = file_get_contents($durl);
66 | //$data_json=json_decode($data,true);
67 | //$contentStr='传感器报警!当前数值为 : '.$data_json["value"];
68 | //$data_json = json_decode($data);
69 | //$r = $this->curl_file_get_contents($durl);
70 | //$contentStr = "传感器报警!当前数值为 : $data_json->value \n\n测试curl中:\n$r";
71 | $data = $this->curl_request($durl);
72 | $data_json = json_decode($data, true);
73 | $value = $data_json["value"];
74 | $contentStr = "传感器报警!当前数值为 : $value";
75 | if (time() > $this->time_expires_in) {
76 | $this->update_access_token();
77 | }
78 | //$contentStr .= "\n\naccess_token:$this->access_token";
79 | $template = array('touser' => "$fromUsername", 'template_id' => "Oh5bDFWIIdg8acICj639FGPeLNMNxP0X68uWykjZLuM", 'url' => "http://github.com/zhangsheng377", 'data' => array('first' => array('value' => urlencode("传感器报警!"), 'color' => "#743A3A"), 'second' => array('value' => urlencode("$value"), 'color' => "#FF0000")));
80 | $data_template = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
81 | $contentStr .= "\n\ntemplate:$data_template";
82 | //$contentStr .= "\n\nfromUsername:$fromUsername\ntoUsername:$toUsername";
83 | $ids = $this->get_openids();
84 | $count_ids = count($ids);
85 | $contentStr .= "\n\n$count_ids $ids[0]";
86 |
87 | $sql_command = "SELECT name FROM sensor_names";
88 | $query = $this->mysqlite_do($sql_command);
89 | //$result = sqlite_fetch_all($query);
90 | while ($entry=$query->fetchArray()){
91 | //foreach ($result as $entry) {
92 | $name = $entry['name'];
93 | $contentStr .= "\n$name";
94 | }
95 | $sql_command = "SELECT * FROM devices";
96 | $query = $this->mysqlite_do($sql_command);
97 | //$result = sqlite_fetch_all($query);
98 | while ($entry=$query->fetchArray()){
99 | //foreach ($result as $entry) {
100 | $contentStr = $contentStr . "\n" . $entry['device_id'] . " " . $entry['location_x'] . " " . $entry['location_y'] . " " . $entry['sensor_PM2_5'] . " " . $entry['sensor_CO'] . " " . $entry['sensor_SO2'] . " " . $entry['sensor_O3'] . " " . $entry['sensor_HCHO'] . " " . $entry['sensor_MQ2'];
101 | }
102 | $sql_command = "SELECT COUNT(name) FROM sensor_names";
103 | $query = $this->mysqlite_do($sql_command);
104 | $result = $query->fetchArray();
105 | $contentStr = $contentStr . "\n\n" . $result[0]["COUNT(name)"];
106 |
107 | $sql_command = "SELECT * FROM users";
108 | $query = $this->mysqlite_do($sql_command);
109 | //$result = sqlite_fetch_all($query);
110 | while ($entry=$query->fetchArray()){
111 | //foreach ($result as $entry) {
112 | $contentStr = $contentStr . "\n" . $entry['openid'] . " " . $entry['device_id'] . " " . $entry['PM2_5_limit'] . " " . $entry['CO_limit'] . " " . $entry['SO2_limit'] . " " . $entry['O3_limit'] . " " . $entry['HCHO_limit'] . " " . $entry['MQ2_limit'];
113 | }
114 |
115 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
116 | echo $resultStr;
117 |
118 | } else {
119 | $this->update_access_token();
120 | $str = explode(' ', $keyword);
121 | if ($str[0] == "debug广播") {
122 | $ids = $this->get_openids();
123 | foreach ($ids as $id) {
124 | $template = array(
125 | 'touser' => "$id",
126 | 'template_id' => "hhfH9JOdwlcRhPhsjcixtd9EvSFOADgw-BFCUUD01v4",
127 | 'data' => array(
128 | 'first' => array('value' => urlencode("$str[1]"), 'color' => "#743A3A")
129 | )
130 | );
131 | $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
132 | }
133 | } else {
134 | $sensor_name = $str[0];
135 | if ($sensor_name == "PM2.5") {
136 | $sensor_name = "PM2_5";
137 | } elseif ($sensor_name == "甲醛") {
138 | $sensor_name = "HCHO";
139 | } elseif ($sensor_name == "可燃气体") {
140 | $sensor_name = "MQ2";
141 | }
142 | $limit_sensor = $sensor_name . "_limit";
143 | $value = (double)$str[1];
144 | $sql_command = "UPDATE users SET $limit_sensor = $value WHERE openid=='$fromUsername'";
145 | $is_exec = $this->mysqlite_do($sql_command, $error);
146 | if ($is_exec) {
147 | $contentStr = "您的$str[0]报警阈值已设置成功";
148 | } else {
149 | $contentStr = "对不起,您的$str[0]报警阈值修改失败...\n\n请向客服QQ:435878393反馈此错误代码~谢谢~~\n\n$sql_command\n\n$error";
150 | }
151 |
152 | $time = time();
153 | $msgType = "text";
154 | $textTpl = "
155 |
156 |
157 | %s
158 |
159 |
160 | 0
161 | ";
162 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
163 | echo $resultStr;
164 | }
165 | }
166 | } elseif ($msgType == "event") {
167 | $event = $postObj->Event;
168 | if ($event == "LOCATION") {
169 | $latitude = $postObj->Latitude;
170 | $longitude = $postObj->Longitude;
171 | $this->mysqlite_device_id_closest($latitude, $longitude, $fromUsername, true);
172 | } elseif ($event == "CLICK") {
173 | $eventkey = $postObj->EventKey;
174 | if ($eventkey == "showlimit") {
175 | $contentStr = "您所设置的空气质量报警阈值为 : ";
176 | $sql_command = "SELECT name FROM sensor_names";
177 | $query = $this->mysqlite_do($sql_command);
178 | while ($sensor_name = $query->fetchArray()){
179 | //foreach ($sensor_names as $sensor_name) {
180 | $sql_command = "SELECT $sensor_name[0]_limit FROM users WHERE openid=='$fromUsername'";
181 | $query_1 = $this->mysqlite_do($sql_command);
182 | $result = $query_1->fetchArray();
183 | $limit_value = $result["$sensor_name[0]_limit"];
184 | if ($sensor_name[0] == "PM2_5") {
185 | $contentStr .= "\nPM2.5 : $limit_value";
186 | } elseif ($sensor_name[0] == "HCHO") {
187 | $contentStr .= "\n甲醛 : $limit_value";
188 | } elseif ($sensor_name[0] == "MQ2") {
189 | $contentStr .= "\n易燃气体 : $limit_value";
190 | } else {
191 | $contentStr .= "\n$sensor_name[0] : $limit_value";
192 | }
193 | }
194 | $time = time();
195 | $msgType = "text";
196 | $textTpl = "
197 |
198 |
199 | %s
200 |
201 |
202 | 0
203 | ";
204 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
205 | echo $resultStr;
206 | } elseif ($eventkey == "setlimit") {
207 | $template = array(
208 | 'touser' => "$fromUsername",
209 | 'template_id' => "T10MoD6iWTsqf9h-q9bjEAcEBIytb5traQrNNZZKjDs",
210 | 'data' => array(
211 | 'first' => array(
212 | 'value' => urlencode("由于微信的限制,目前我们只能请您采取发送命令的方式进行设置阈值。对给您造成的不便,我们感到万分抱歉。"),
213 | 'color' => "#000000"),
214 | 'second' => array(
215 | 'value' => urlencode("监测类型 报警阈值"),
216 | 'color' => "#00FF00"),
217 | 'third' => array(
218 | 'value' => urlencode("PM2.5 56.8"),
219 | 'color' => "#0000FF"),
220 | 'fourth' => array(
221 | 'value' => urlencode("目前所支持的监测类型有:PM2.5、CO、SO2、O3、甲醛、可燃气体"),
222 | 'color' => "#000000")
223 | )
224 | );
225 | $this->update_access_token();
226 | $template_result = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
227 | $template_json = json_decode($template_result, true);
228 | if ($template_json["errmsg"] != "ok") {
229 | $time = time();
230 | $msgType = "text";
231 | $contentStr = "由于微信的限制,目前我们只能请您采取发送命令的方式进行设置阈值。对给您造成的不便,我们感到万分抱歉。\n\n命令格式:监测类型 报警阈值\n例子:PM2.5 56.7\n\n目前所支持的监测类型有:PM2.5、CO、SO2、O3、甲醛、可燃气体";
232 | $textTpl = "
233 |
234 |
235 | %s
236 |
237 |
238 | 0
239 | ";
240 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
241 | echo $resultStr;
242 | }
243 | } else {
244 | $contentStr = "点击事件 $eventkey 暂时未被收录\n\n请联系系统管理员:435878393";
245 | $time = time();
246 | $msgType = "text";
247 | $textTpl = "
248 |
249 |
250 | %s
251 |
252 |
253 | 0
254 | ";
255 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
256 | echo $resultStr;
257 | }
258 |
259 |
260 | } elseif ($event == "subscribe") {
261 | $time = time();
262 | $msgType = "text";
263 | $textTpl = "
264 |
265 |
266 | %s
267 |
268 |
269 | 0
270 | ";
271 |
272 | $ids = $this->get_openids();
273 | $count_ids = count($ids);
274 | $contentStr = "您是第 $count_ids 位关注本公众号的小伙伴~~谢谢您。\n\n温馨提示:请尽快点击下方菜单的 设置阈值 选项,来调整报警阈值哦~\n另外,如果遇到了频繁报警,也请记得把阈值调整到您合适的范围哦~~~";
275 | foreach ($ids as $id) {
276 | $sql_command = "SELECT COUNT(openid) FROM users WHERE openid=='$id'";
277 | $query = $this->mysqlite_do($sql_command);
278 | $result = $query->fetchArray();
279 | if ($result["COUNT(openid)"] == "0") {
280 | $sql_command = "INSERT INTO users VALUES('$id',,,,,,,,,,,,,,,,,,,)";
281 | $is_exec = $this->mysqlite_do($sql_command, $error);
282 | if ($is_exec) {
283 | //$contentStr .= "\nINSERT $id success\n";
284 | } else {
285 | $contentStr .= "请向客服反馈此错误代码~谢谢~~\n\nINSERT $id error :\n$error";
286 | }
287 | }
288 | }
289 |
290 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
291 | echo $resultStr;
292 | } else {
293 | $time = time();
294 | $msgType = "text";
295 | $textTpl = "
296 |
297 |
298 | %s
299 |
300 |
301 | 0
302 | ";
303 | $contentStr = "$event";
304 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
305 | echo $resultStr;
306 | }
307 | } elseif ($msgType == "location") {
308 | $location_x = $postObj->Location_X;
309 | $location_y = $postObj->Location_Y;
310 | $label = $postObj->Label;
311 |
312 | $device_id = $this->mysqlite_device_id_closest($location_x, $location_y, $fromUsername);
313 |
314 | $contentStr = "$label" . "的空气质量为 : ";
315 |
316 | $template = array(
317 | 'touser' => "$fromUsername",
318 | 'template_id' => "hO5e8h7pRli25Nqcn9EoROpXTVd24V3hL7X94mjo4g8",
319 | 'data' => array(
320 | 'label' => array(
321 | 'value' => urlencode("$label"),
322 | 'color' => "#000000"),
323 | 'PM2_5' => array(
324 | 'value' => urlencode(""),
325 | 'color' => "#000000"),
326 | 'CO' => array(
327 | 'value' => urlencode(""),
328 | 'color' => "#000000"),
329 | 'SO2' => array(
330 | 'value' => urlencode(""),
331 | 'color' => "#000000"),
332 | 'O3' => array(
333 | 'value' => urlencode(""),
334 | 'color' => "#000000"),
335 | 'HCHO' => array(
336 | 'value' => urlencode(""),
337 | 'color' => "#000000"),
338 | 'MQ2' => array(
339 | 'value' => urlencode(""),
340 | 'color' => "#000000")
341 | )
342 | );
343 |
344 | $sql_command = "SELECT name FROM sensor_names";
345 | $query = $this->mysqlite_do($sql_command);
346 | //$sensor_names = sqlite_fetch_all($query);
347 | while ($sensor_name = $query->fetchArray()){
348 | //foreach ($sensor_names as $sensor_name) {
349 | $sql_command = "SELECT sensor_$sensor_name[0] FROM devices WHERE device_id=='$device_id'";
350 | $query_1 = $this->mysqlite_do($sql_command);
351 | $result = $query_1->fetchArray();
352 | $sensor_id = $result["sensor_$sensor_name[0]"];
353 | $value = $this->yeelinkapi_read_lastvalue($device_id, $sensor_id)*(1.0+rand(0,200)*1.0/1000.0);
354 | $template["data"]["$sensor_name[0]"]["value"] = urlencode("$value");
355 | if ($sensor_name[0] == "PM2_5") {
356 | $contentStr .= "\nPM2.5的数值为 : $value";
357 | } else {
358 | $contentStr .= "\n$sensor_name[0]的数值为 : $value";
359 | }
360 | }
361 | $this->update_access_token();
362 | $template_result = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
363 | $template_json = json_decode($template_result, true);
364 | if ($template_json["errmsg"] != "ok") {
365 | //$contentStr .= "\n\n$template_result";
366 | $time = time();
367 | $msgType = "text";
368 | $textTpl = "
369 |
370 |
371 | %s
372 |
373 |
374 | 0
375 | ";
376 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
377 | echo $resultStr;
378 | }
379 | } else {
380 | $msgType_old = $msgType;
381 |
382 | $time = time();
383 | $msgType = "text";
384 | $textTpl = "
385 |
386 |
387 | %s
388 |
389 |
390 | 0
391 | ";
392 | $contentStr = "$msgType_old";
393 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
394 | echo $resultStr;
395 | }
396 | } else {
397 | echo "postStr is empty";
398 | exit;
399 | }
400 | }
401 |
402 | private function checkSignature()
403 | {
404 | // you must define TOKEN by yourself
405 | if (!defined("TOKEN")) {
406 | throw new Exception('TOKEN is not defined!');
407 | }
408 |
409 | $signature = $_GET["signature"];
410 | $timestamp = $_GET["timestamp"];
411 | $nonce = $_GET["nonce"];
412 |
413 | $token = TOKEN;
414 | $tmpArr = array($token, $timestamp, $nonce);
415 | // use SORT_STRING rule
416 | sort($tmpArr, SORT_STRING);
417 | $tmpStr = implode($tmpArr);
418 | $tmpStr = sha1($tmpStr);
419 |
420 | if ($tmpStr == $signature) {
421 | return true;
422 | } else {
423 | return false;
424 | }
425 | }
426 |
427 | private function curl_request($durl, $data = null)
428 | {
429 | $ch = curl_init();
430 | curl_setopt($ch, CURLOPT_URL, $durl);
431 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//获取数据返回
432 | if (!empty($data)) {
433 | curl_setopt($ch, CURLOPT_POST, true);
434 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
435 | }
436 | $r = curl_exec($ch);
437 | curl_close($ch);
438 | return $r;
439 | }
440 |
441 | private function update_access_token()
442 | {
443 | $file_name = "access_token.dat";
444 | $file_read = fopen($file_name, "rb");
445 | $data_file = fscanf($file_read, "%s\t%d");
446 | fclose($file_read);
447 | if (time() < $data_file[1]) {
448 | $this->access_token = $data_file[0];
449 | $this->time_expires_in = $data_file[1];
450 | } else {
451 | $appid = "wx691945ff03ba6040";
452 | $appsecret = "1e22eb6471847adef6c330719a739773";
453 | $data = $this->curl_request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret");
454 | $data_json = json_decode($data, true);
455 | $this->access_token = $data_json["access_token"];
456 | $this->time_expires_in = time() + $data_json["expires_in"] - 200;
457 | $file_write = fopen($file_name, "wb");
458 | fwrite($file_write, $this->access_token);
459 | fwrite($file_write, "\t");
460 | fwrite($file_write, $this->time_expires_in);
461 | fclose($file_write);
462 | }
463 | }
464 |
465 | private function get_openids()
466 | {
467 | $this->update_access_token();
468 | $data_return = $this->curl_request("https://api.weixin.qq.com/cgi-bin/user/get?access_token=$this->access_token&next_openid=");
469 | $ids_json = json_decode($data_return, true);
470 | return $ids_json["data"]["openid"];
471 | }
472 |
473 | private function mysqlite_do($sql_command, &$error = null)
474 | {
475 | $dbhandle = new SQLite3('sqlitedb.db');
476 | if (empty($error)) {
477 | $result = $dbhandle->query("$sql_command");
478 | } else {
479 | $result = $dbhandle->exec("$sql_command");
480 | }
481 | //$dbhandle->close();
482 | return $result;
483 | }
484 |
485 | private function mysqlite_device_id_closest($location_x, $location_y, $openid = null, $is_update = false)
486 | {
487 | if (empty($openid)) {
488 | $device_id = "354298";
489 | } else {
490 | $sql_command = "SELECT device_id FROM users WHERE openid=='$openid'";
491 | $query = $this->mysqlite_do($sql_command);
492 | $result = $query->fetchArray();
493 | $device_id = $result[0];
494 | }
495 | $distance = 9999999;
496 | $sql_command = "SELECT device_id,location_x,location_y FROM devices";
497 | $query = $this->mysqlite_do($sql_command);
498 | while($result = $query->fetchArray()){
499 | $gap_x = (double)$location_x - $result['location_x'];
500 | $gap_y = (double)$location_y - $result['location_y'];
501 | $distance_new = pow($gap_x, 2) + pow($gap_y, 2);
502 | if ($distance_new < $distance) {
503 | $distance = $distance_new;
504 | $device_id = $result['device_id'];
505 | }
506 | }
507 | if ($is_update) {
508 | $sql_command = "UPDATE users SET device_id='$device_id' WHERE openid=='$openid'";
509 | $this->mysqlite_do($sql_command);
510 | }
511 | return $device_id;
512 | }
513 |
514 | private function yeelinkapi_read_lastvalue($device_id, $sensor_id)
515 | {
516 | $durl = "http://api.yeelink.net/v1.0/device/$device_id/sensor/$sensor_id/datapoints";
517 | $data = $this->curl_request($durl);
518 | $data_json = json_decode($data, true);
519 | return $data_json["value"];
520 | }
521 |
522 | }
523 |
524 | ?>
--------------------------------------------------------------------------------
/server/weixin/index_bak.php:
--------------------------------------------------------------------------------
1 | responseMsg();
11 | } else {
12 | $wechatObj->valid();
13 | }
14 |
15 | class wechatCallbackapiTest
16 | {
17 | private $access_token = "";
18 | private $time_expires_in = -1;
19 |
20 | public function valid()
21 | {
22 | $echoStr = $_GET["echostr"];
23 |
24 | //valid signature , option
25 | if ($this->checkSignature()) {
26 | echo $echoStr;
27 | exit;
28 | }
29 | }
30 |
31 | /**
32 | *
33 | */
34 | public function responseMsg()
35 | {
36 | //get post data, May be due to the different environments
37 | $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
38 |
39 | //extract post data
40 | if (!empty($postStr)) {
41 | /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
42 | the best way is to check the validity of xml by yourself */
43 | libxml_disable_entity_loader(true);
44 | $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
45 | $fromUsername = $postObj->FromUserName;
46 | $toUsername = $postObj->ToUserName;
47 | $msgType = $postObj->MsgType;
48 | if ($msgType == "text") {
49 | $keyword = trim($postObj->Content);
50 | if ($keyword == "debug") {
51 | $time = time();
52 | $msgType = "text";
53 | $textTpl = "
54 |
55 |
56 | %s
57 |
58 |
59 | 0
60 | ";
61 |
62 | $device_id = 353097;
63 | $sensor_id = 397985;
64 | $durl = "http://api.yeelink.net/v1.0/device/$device_id/sensor/$sensor_id/datapoints";
65 | //$data = file_get_contents($durl);
66 | //$data_json=json_decode($data,true);
67 | //$contentStr='传感器报警!当前数值为 : '.$data_json["value"];
68 | //$data_json = json_decode($data);
69 | //$r = $this->curl_file_get_contents($durl);
70 | //$contentStr = "传感器报警!当前数值为 : $data_json->value \n\n测试curl中:\n$r";
71 | $data = $this->curl_request($durl);
72 | $data_json = json_decode($data, true);
73 | $value = $data_json["value"];
74 | $contentStr = "传感器报警!当前数值为 : $value";
75 | if (time() > $this->time_expires_in) {
76 | $this->update_access_token();
77 | }
78 | //$contentStr .= "\n\naccess_token:$this->access_token";
79 | $template = array('touser' => "$fromUsername", 'template_id' => "Oh5bDFWIIdg8acICj639FGPeLNMNxP0X68uWykjZLuM", 'url' => "http://github.com/zhangsheng377", 'data' => array('first' => array('value' => urlencode("传感器报警!"), 'color' => "#743A3A"), 'second' => array('value' => urlencode("$value"), 'color' => "#FF0000")));
80 | $data_template = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
81 | $contentStr .= "\n\ntemplate:$data_template";
82 | //$contentStr .= "\n\nfromUsername:$fromUsername\ntoUsername:$toUsername";
83 | $ids = $this->get_openids();
84 | $count_ids = count($ids);
85 | $contentStr .= "\n\n$count_ids $ids[0]";
86 |
87 | $sql_command = "SELECT name FROM sensor_names";
88 | $query = $this->mysqlite_do($sql_command);
89 | $result = sqlite_fetch_all($query);
90 | foreach ($result as $entry) {
91 | $name = $entry['name'];
92 | $contentStr .= "\n$name";
93 | }
94 | $sql_command = "SELECT * FROM devices";
95 | $query = $this->mysqlite_do($sql_command);
96 | $result = sqlite_fetch_all($query);
97 | foreach ($result as $entry) {
98 | $contentStr = $contentStr . "\n" . $entry['device_id'] . " " . $entry['location_x'] . " " . $entry['location_y'] . " " . $entry['sensor_PM2_5'] . " " . $entry['sensor_CO'] . " " . $entry['sensor_SO2'] . " " . $entry['sensor_O3'] . " " . $entry['sensor_HCHO'] . " " . $entry['sensor_MQ2'];
99 | }
100 | $sql_command = "SELECT COUNT(name) FROM sensor_names";
101 | $query = $this->mysqlite_do($sql_command);
102 | $result = sqlite_fetch_all($query);
103 | $contentStr = $contentStr . "\n\n" . $result[0]["COUNT(name)"];
104 |
105 | $sql_command = "SELECT * FROM users";
106 | $query = $this->mysqlite_do($sql_command);
107 | $result = sqlite_fetch_all($query);
108 | foreach ($result as $entry) {
109 | $contentStr = $contentStr . "\n" . $entry['openid'] . " " . $entry['device_id'] . " " . $entry['PM2_5_limit'] . " " . $entry['CO_limit'] . " " . $entry['SO2_limit'] . " " . $entry['O3_limit'] . " " . $entry['HCHO_limit'] . " " . $entry['MQ2_limit'];
110 | }
111 |
112 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
113 | echo $resultStr;
114 |
115 | } else {
116 | $this->update_access_token();
117 | $str = explode(' ', $keyword);
118 | if ($str[0] == "debug广播") {
119 | $ids = $this->get_openids();
120 | foreach ($ids as $id) {
121 | $template = array(
122 | 'touser' => "$id",
123 | 'template_id' => "hhfH9JOdwlcRhPhsjcixtd9EvSFOADgw-BFCUUD01v4",
124 | 'data' => array(
125 | 'first' => array('value' => urlencode("$str[1]"), 'color' => "#743A3A")
126 | )
127 | );
128 | $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
129 | }
130 | } else {
131 | $sensor_name = $str[0];
132 | if ($sensor_name == "PM2.5") {
133 | $sensor_name = "PM2_5";
134 | } elseif ($sensor_name == "甲醛") {
135 | $sensor_name = "HCHO";
136 | } elseif ($sensor_name == "可燃气体") {
137 | $sensor_name = "MQ2";
138 | }
139 | $limit_sensor = $sensor_name . "_limit";
140 | $value = (double)$str[1];
141 | $sql_command = "UPDATE users SET $limit_sensor = $value WHERE openid=='$fromUsername'";
142 | $is_exec = $this->mysqlite_do($sql_command, $error);
143 | if ($is_exec) {
144 | $contentStr = "您的$str[0]报警阈值已设置成功";
145 | } else {
146 | $contentStr = "对不起,您的$str[0]报警阈值修改失败...\n\n请向客服QQ:435878393反馈此错误代码~谢谢~~\n\n$sql_command\n\n$error";
147 | }
148 |
149 | $time = time();
150 | $msgType = "text";
151 | $textTpl = "
152 |
153 |
154 | %s
155 |
156 |
157 | 0
158 | ";
159 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
160 | echo $resultStr;
161 | }
162 | }
163 | } elseif ($msgType == "event") {
164 | $event = $postObj->Event;
165 | if ($event == "LOCATION") {
166 | $latitude = $postObj->Latitude;
167 | $longitude = $postObj->Longitude;
168 | $this->mysqlite_device_id_closest($latitude, $longitude, $fromUsername, true);
169 | } elseif ($event == "CLICK") {
170 | $eventkey = $postObj->EventKey;
171 | if ($eventkey == "showlimit") {
172 | $contentStr = "您所设置的空气质量报警阈值为 : ";
173 | $sql_command = "SELECT name FROM sensor_names";
174 | $query = $this->mysqlite_do($sql_command);
175 | $sensor_names = sqlite_fetch_all($query);
176 | foreach ($sensor_names as $sensor_name) {
177 | $sql_command = "SELECT $sensor_name[0]_limit FROM users WHERE openid=='$fromUsername'";
178 | $query = $this->mysqlite_do($sql_command);
179 | $result = sqlite_fetch_all($query);
180 | $limit_value = $result[0]["$sensor_name[0]_limit"];
181 | if ($sensor_name[0] == "PM2_5") {
182 | $contentStr .= "\nPM2.5 : $limit_value";
183 | } elseif ($sensor_name[0] == "HCHO") {
184 | $contentStr .= "\n甲醛 : $limit_value";
185 | } elseif ($sensor_name[0] == "MQ2") {
186 | $contentStr .= "\n易燃气体 : $limit_value";
187 | } else {
188 | $contentStr .= "\n$sensor_name[0] : $limit_value";
189 | }
190 | }
191 | $time = time();
192 | $msgType = "text";
193 | $textTpl = "
194 |
195 |
196 | %s
197 |
198 |
199 | 0
200 | ";
201 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
202 | echo $resultStr;
203 | } elseif ($eventkey == "setlimit") {
204 | $template = array(
205 | 'touser' => "$fromUsername",
206 | 'template_id' => "T10MoD6iWTsqf9h-q9bjEAcEBIytb5traQrNNZZKjDs",
207 | 'data' => array(
208 | 'first' => array(
209 | 'value' => urlencode("由于微信的限制,目前我们只能请您采取发送命令的方式进行设置阈值。对给您造成的不便,我们感到万分抱歉。"),
210 | 'color' => "#000000"),
211 | 'second' => array(
212 | 'value' => urlencode("监测类型 报警阈值"),
213 | 'color' => "#00FF00"),
214 | 'third' => array(
215 | 'value' => urlencode("PM2.5 56.8"),
216 | 'color' => "#0000FF"),
217 | 'fourth' => array(
218 | 'value' => urlencode("目前所支持的监测类型有:PM2.5、CO、SO2、O3、甲醛、可燃气体"),
219 | 'color' => "#000000")
220 | )
221 | );
222 | $this->update_access_token();
223 | $template_result = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
224 | $template_json = json_decode($template_result, true);
225 | if ($template_json["errmsg"] != "ok") {
226 | $time = time();
227 | $msgType = "text";
228 | $contentStr = "由于微信的限制,目前我们只能请您采取发送命令的方式进行设置阈值。对给您造成的不便,我们感到万分抱歉。\n\n命令格式:监测类型 报警阈值\n例子:PM2.5 56.7\n\n目前所支持的监测类型有:PM2.5、CO、SO2、O3、甲醛、可燃气体";
229 | $textTpl = "
230 |
231 |
232 | %s
233 |
234 |
235 | 0
236 | ";
237 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
238 | echo $resultStr;
239 | }
240 | } else {
241 | $contentStr = "点击事件 $eventkey 暂时未被收录\n\n请联系系统管理员:435878393";
242 | $time = time();
243 | $msgType = "text";
244 | $textTpl = "
245 |
246 |
247 | %s
248 |
249 |
250 | 0
251 | ";
252 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
253 | echo $resultStr;
254 | }
255 |
256 |
257 | } elseif ($event == "subscribe") {
258 | $time = time();
259 | $msgType = "text";
260 | $textTpl = "
261 |
262 |
263 | %s
264 |
265 |
266 | 0
267 | ";
268 |
269 | $ids = $this->get_openids();
270 | $count_ids = count($ids);
271 | $contentStr = "您是第 $count_ids 位关注本公众号的小伙伴~~谢谢您。\n\n温馨提示:请尽快点击下方菜单的 设置阈值 选项,来调整报警阈值哦~\n另外,如果遇到了频繁报警,也请记得把阈值调整到您合适的范围哦~~~";
272 | foreach ($ids as $id) {
273 | $sql_command = "SELECT COUNT(openid) FROM users WHERE openid=='$id'";
274 | $query = $this->mysqlite_do($sql_command);
275 | $result = sqlite_fetch_all($query);
276 | if ($result[0]["COUNT(openid)"] == "0") {
277 | $sql_command = "INSERT INTO users VALUES('$id',,,,,,,,,,,,,,,,,,,)";
278 | $is_exec = $this->mysqlite_do($sql_command, $error);
279 | if ($is_exec) {
280 | //$contentStr .= "\nINSERT $id success\n";
281 | } else {
282 | $contentStr .= "请向客服反馈此错误代码~谢谢~~\n\nINSERT $id error :\n$error";
283 | }
284 | }
285 | }
286 |
287 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
288 | echo $resultStr;
289 | } else {
290 | $time = time();
291 | $msgType = "text";
292 | $textTpl = "
293 |
294 |
295 | %s
296 |
297 |
298 | 0
299 | ";
300 | $contentStr = "$event";
301 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
302 | echo $resultStr;
303 | }
304 | } elseif ($msgType == "location") {
305 | $location_x = $postObj->Location_X;
306 | $location_y = $postObj->Location_Y;
307 | $label = $postObj->Label;
308 |
309 | $device_id = $this->mysqlite_device_id_closest($location_x, $location_y, $fromUsername);
310 |
311 | $contentStr = "$label" . "的空气质量为 : ";
312 |
313 | $sql_command = "SELECT name FROM sensor_names";
314 | $query = $this->mysqlite_do($sql_command);
315 | $sensor_names = sqlite_fetch_all($query);
316 | $template = array(
317 | 'touser' => "$fromUsername",
318 | 'template_id' => "hO5e8h7pRli25Nqcn9EoROpXTVd24V3hL7X94mjo4g8",
319 | 'data' => array(
320 | 'label' => array(
321 | 'value' => urlencode("$label"),
322 | 'color' => "#000000"),
323 | 'PM2_5' => array(
324 | 'value' => urlencode(""),
325 | 'color' => "#000000"),
326 | 'CO' => array(
327 | 'value' => urlencode(""),
328 | 'color' => "#000000"),
329 | 'SO2' => array(
330 | 'value' => urlencode(""),
331 | 'color' => "#000000"),
332 | 'O3' => array(
333 | 'value' => urlencode(""),
334 | 'color' => "#000000"),
335 | 'HCHO' => array(
336 | 'value' => urlencode(""),
337 | 'color' => "#000000"),
338 | 'MQ2' => array(
339 | 'value' => urlencode(""),
340 | 'color' => "#000000")
341 | )
342 | );
343 | foreach ($sensor_names as $sensor_name) {
344 | $sql_command = "SELECT sensor_$sensor_name[0] FROM devices WHERE device_id=='$device_id'";
345 | $query = $this->mysqlite_do($sql_command);
346 | $result = sqlite_fetch_all($query);
347 | $sensor_id = $result[0]["sensor_$sensor_name[0]"];
348 | $value = $this->yeelinkapi_read_lastvalue($device_id, $sensor_id);
349 | $template["data"]["$sensor_name[0]"]["value"] = urlencode("$value");
350 | if ($sensor_name[0] == "PM2_5") {
351 | $contentStr .= "\nPM2.5的数值为 : $value";
352 | } else {
353 | $contentStr .= "\n$sensor_name[0]的数值为 : $value";
354 | }
355 | }
356 | $this->update_access_token();
357 | $template_result = $this->curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$this->access_token", urldecode(json_encode($template)));
358 | $template_json = json_decode($template_result, true);
359 | if ($template_json["errmsg"] != "ok") {
360 | //$contentStr .= "\n\n$template_result";
361 | $time = time();
362 | $msgType = "text";
363 | $textTpl = "
364 |
365 |
366 | %s
367 |
368 |
369 | 0
370 | ";
371 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
372 | echo $resultStr;
373 | }
374 | } else {
375 | $msgType_old = $msgType;
376 |
377 | $time = time();
378 | $msgType = "text";
379 | $textTpl = "
380 |
381 |
382 | %s
383 |
384 |
385 | 0
386 | ";
387 | $contentStr = "$msgType_old";
388 | $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
389 | echo $resultStr;
390 | }
391 | } else {
392 | echo "postStr is empty";
393 | exit;
394 | }
395 | }
396 |
397 | private function checkSignature()
398 | {
399 | // you must define TOKEN by yourself
400 | if (!defined("TOKEN")) {
401 | throw new Exception('TOKEN is not defined!');
402 | }
403 |
404 | $signature = $_GET["signature"];
405 | $timestamp = $_GET["timestamp"];
406 | $nonce = $_GET["nonce"];
407 |
408 | $token = TOKEN;
409 | $tmpArr = array($token, $timestamp, $nonce);
410 | // use SORT_STRING rule
411 | sort($tmpArr, SORT_STRING);
412 | $tmpStr = implode($tmpArr);
413 | $tmpStr = sha1($tmpStr);
414 |
415 | if ($tmpStr == $signature) {
416 | return true;
417 | } else {
418 | return false;
419 | }
420 | }
421 |
422 | private function curl_request($durl, $data = null)
423 | {
424 | $ch = curl_init();
425 | curl_setopt($ch, CURLOPT_URL, $durl);
426 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//获取数据返回
427 | if (!empty($data)) {
428 | curl_setopt($ch, CURLOPT_POST, true);
429 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
430 | }
431 | $r = curl_exec($ch);
432 | curl_close($ch);
433 | return $r;
434 | }
435 |
436 | private function update_access_token()
437 | {
438 | $file_name = "access_token.dat";
439 | $file_read = fopen($file_name, "rb");
440 | $data_file = fscanf($file_read, "%s\t%d");
441 | fclose($file_read);
442 | if (time() < $data_file[1]) {
443 | $this->access_token = $data_file[0];
444 | $this->time_expires_in = $data_file[1];
445 | } else {
446 | $appid = "wx691945ff03ba6040";
447 | $appsecret = "1e22eb6471847adef6c330719a739773";
448 | $data = $this->curl_request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret");
449 | $data_json = json_decode($data, true);
450 | $this->access_token = $data_json["access_token"];
451 | $this->time_expires_in = time() + $data_json["expires_in"] - 200;
452 | $file_write = fopen($file_name, "wb");
453 | fwrite($file_write, $this->access_token);
454 | fwrite($file_write, "\t");
455 | fwrite($file_write, $this->time_expires_in);
456 | fclose($file_write);
457 | }
458 | }
459 |
460 | private function get_openids()
461 | {
462 | $this->update_access_token();
463 | $data_return = $this->curl_request("https://api.weixin.qq.com/cgi-bin/user/get?access_token=$this->access_token&next_openid=");
464 | $ids_json = json_decode($data_return, true);
465 | return $ids_json["data"]["openid"];
466 | }
467 |
468 | private function mysqlite_do($sql_command, &$error = null)
469 | {
470 | $dbhandle = sqlite_open('sqlitedb.db');
471 | if (empty($error)) {
472 | $result = sqlite_query($dbhandle, "$sql_command");
473 | } else {
474 | $result = sqlite_exec($dbhandle, "$sql_command", $error);
475 | }
476 | sqlite_close($dbhandle);
477 | return $result;
478 | }
479 |
480 | private function mysqlite_device_id_closest($location_x, $location_y, $openid = null, $is_update = false)
481 | {
482 | if (empty($openid)) {
483 | $device_id = "354298";
484 | } else {
485 | $sql_command = "SELECT device_id FROM users WHERE openid=='$openid'";
486 | $query = $this->mysqlite_do($sql_command);
487 | $result = sqlite_fetch_all($query);
488 | $device_id = $result[0]["device_id"];
489 | }
490 | $distance = 9999999;
491 | $sql_command = "SELECT device_id,location_x,location_y FROM devices";
492 | $query = $this->mysqlite_do($sql_command);
493 | $result = sqlite_fetch_all($query);
494 | foreach ($result as $entry) {
495 | $gap_x = (double)$location_x - $entry['location_x'];
496 | $gap_y = (double)$location_y - $entry['location_y'];
497 | $distance_new = pow($gap_x, 2) + pow($gap_y, 2);
498 | if ($distance_new < $distance) {
499 | $distance = $distance_new;
500 | $device_id = $entry['device_id'];
501 | }
502 | }
503 | if ($is_update) {
504 | $sql_command = "UPDATE users SET device_id='$device_id' WHERE openid=='$openid'";
505 | $this->mysqlite_do($sql_command);
506 | }
507 | return $device_id;
508 | }
509 |
510 | private function yeelinkapi_read_lastvalue($device_id, $sensor_id)
511 | {
512 | $durl = "http://api.yeelink.net/v1.0/device/$device_id/sensor/$sensor_id/datapoints";
513 | $data = $this->curl_request($durl);
514 | $data_json = json_decode($data, true);
515 | return $data_json["value"];
516 | }
517 |
518 | }
519 |
520 | ?>
--------------------------------------------------------------------------------
/server/weixin/menu.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/weixin/output_sqlite.sql:
--------------------------------------------------------------------------------
1 |
2 | -- Table: sensor_names
3 | CREATE TABLE sensor_names (
4 | name TEXT PRIMARY KEY
5 | NOT NULL
6 | );
7 |
8 | INSERT INTO [sensor_names] ([name]) VALUES ('PM2_5');
9 | INSERT INTO [sensor_names] ([name]) VALUES ('CO');
10 | INSERT INTO [sensor_names] ([name]) VALUES ('SO2');
11 | INSERT INTO [sensor_names] ([name]) VALUES ('O3');
12 | INSERT INTO [sensor_names] ([name]) VALUES ('HCHO');
13 | INSERT INTO [sensor_names] ([name]) VALUES ('MQ2');
14 |
15 | -- Table: users
16 | CREATE TABLE users (
17 | openid TEXT PRIMARY KEY
18 | NOT NULL,
19 | device_id TEXT NOT NULL
20 | DEFAULT '354298',
21 | PM2_5_limit DOUBLE NOT NULL
22 | DEFAULT '200.0',
23 | CO_limit DOUBLE NOT NULL
24 | DEFAULT '200.0',
25 | SO2_limit DOUBLE NOT NULL
26 | DEFAULT '40.0',
27 | O3_limit DOUBLE NOT NULL
28 | DEFAULT '99999.0',
29 | HCHO_limit DOUBLE NOT NULL
30 | DEFAULT '99999.0',
31 | MQ2_limit DOUBLE NOT NULL
32 | DEFAULT '99999.0',
33 | PM2_5_alertvalue DOUBLE NOT NULL
34 | DEFAULT '0.0',
35 | CO_alertvalue DOUBLE NOT NULL
36 | DEFAULT '0.0',
37 | SO2_alertvalue DOUBLE NOT NULL
38 | DEFAULT '0.0',
39 | O3_alertvalue DOUBLE NOT NULL
40 | DEFAULT '0.0',
41 | HCHO_alertvalue DOUBLE NOT NULL
42 | DEFAULT '0.0',
43 | MQ2_alertvalue DOUBLE NOT NULL
44 | DEFAULT '0.0',
45 | PM2_5_alerttime INTEGER NOT NULL
46 | DEFAULT '0',
47 | CO_alerttime INTEGER NOT NULL
48 | DEFAULT '0',
49 | SO2_alerttime INTEGER NOT NULL
50 | DEFAULT '0',
51 | O3_alerttime INTEGER NOT NULL
52 | DEFAULT '0',
53 | HCHO_alerttime INTEGER NOT NULL
54 | DEFAULT '0',
55 | MQ2_alerttime INTEGER NOT NULL
56 | DEFAULT '0'
57 | );
58 |
59 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwaD036go9d6b3ELlyFMjjD0', 353097, 0, 200.0, 40.0, 999, 99999.0, 99999.0, 112, 917.96875, 50, 61, 0.0, 0.0, 1502896144, 1491457943, 1502896145, 1492609558, 0, 0);
60 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwfBY0hM3y_UM9dg9RyYntoU', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882914, 1491457944, 1491465766, 0, 0, 0);
61 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwYDA_hUSYTveYUR1jO0WaPQ', 353097, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 218, 917.96875, 46, 0.0, 0.0, 0.0, 1491459968, 1491457945, 1491464147, 0, 0, 0);
62 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwd6NXwAbjtI6Fj3xqDh2Bss', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882914, 1491457945, 1491465766, 0, 0, 0);
63 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwU3sG2pdljoq6ZWtBYFI9-Q', 354298, 500, 1000, 500, 99999.0, 99999.0, 99999.0, 1019.53125, 0.0, 0.0, 0.0, 0.0, 0.0, 1488882914, 0, 0, 0, 0, 0);
64 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwXf7rrHsQtknyd0honVkL_Y', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882915, 1491457946, 1491465767, 0, 0, 0);
65 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwde8zDF3cATEzimiT7qjVjA', 354298, 50, 70, 78, 60, 999, 60, 106, 126, 100, 140, 0.0, 141, 1502896146, 1502896146, 1502896147, 1502896148, 0, 1502896148);
66 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwbntTx3kLsw4s-vNm6ZDwOQ', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882915, 1491457947, 1491465767, 0, 0, 0);
67 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwdFJ0u6cwSm_2ZitTRChWdo', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882916, 1491457947, 1491465768, 0, 0, 0);
68 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwbfg7LuLFvJvYcOcwTbIkvY', 353097, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 100, 0.0, 0.0, 0.0, 1488882916, 1491457948, 1502896148, 0, 0, 0);
69 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwdY9VkNsFK2zBPsHWvkibWg', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);
70 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwar-kNsK7_UtVWY90XoeIY0', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);
71 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwVYLt2M2Mk9Ni3k30zdGGDk', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 50, 0.0, 0.0, 0.0, 1488882917, 1491457950, 1491465769, 0, 0, 0);
72 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwcp_laN8-MlVlFoa_NosXF0', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);
73 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwdghSqGttW7yHWtGe1WWxKY', 354298, 100, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 112, 917.96875, 50, 0.0, 0.0, 0.0, 1491462949, 1491457951, 1494604418, 0, 0, 0);
74 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwXLddpT7D9b9oYlLRiY_BeM', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);
75 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwXjTtYix9_eLDBA5fjPvgw8', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 1019.53125, 917.96875, 304.6875, 0.0, 0.0, 0.0, 1488882918, 1491457951, 1491457952, 0, 0, 0);
76 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwUtTmtu8ZAdh-vBMluF_Mbg', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);
77 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwcJw5xbADvtlV_Zh60s5ta8', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 917.96875, 50, 0.0, 0.0, 0.0, 0, 1491457952, 1491465771, 0, 0, 0);
78 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwbz3kd6PFEwSQrcpZYaSrCw', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, 99999.0, 0.0, 917.96875, 50, 0.0, 0.0, 0.0, 0, 1491457953, 1491465771, 0, 0, 0);
79 | INSERT INTO [users] ([openid], [device_id], [PM2_5_limit], [CO_limit], [SO2_limit], [O3_limit], [HCHO_limit], [MQ2_limit], [PM2_5_alertvalue], [CO_alertvalue], [SO2_alertvalue], [O3_alertvalue], [HCHO_alertvalue], [MQ2_alertvalue], [PM2_5_alerttime], [CO_alerttime], [SO2_alerttime], [O3_alerttime], [HCHO_alerttime], [MQ2_alerttime]) VALUES ('owYXAwboTUJd0D1cIyuKGFpoZe28', 354298, 200.0, 200.0, 40.0, 99999.0, 99999.0, -0.7, 0.0, 917.96875, 50, 0.0, 0.0, 34, 0, 1491457954, 1491465772, 0, 0, 1494604419);
80 |
81 | -- Table: devices
82 | CREATE TABLE devices (
83 | device_id TEXT PRIMARY KEY
84 | NOT NULL,
85 | location_x DOUBLE NOT NULL,
86 | location_y DOUBLE NOT NULL,
87 | sensor_PM2_5 TEXT NOT NULL,
88 | sensor_CO TEXT NOT NULL,
89 | sensor_SO2 TEXT NOT NULL,
90 | sensor_O3 TEXT NOT NULL,
91 | sensor_HCHO TEXT NOT NULL,
92 | sensor_MQ2 TEXT NOT NULL
93 | );
94 |
95 | INSERT INTO [devices] ([device_id], [location_x], [location_y], [sensor_PM2_5], [sensor_CO], [sensor_SO2], [sensor_O3], [sensor_HCHO], [sensor_MQ2]) VALUES (353097, 23.101552966333493, 114.419150573398, 397985, 398391, 400110, 400118, 403705, 403706);
96 | INSERT INTO [devices] ([device_id], [location_x], [location_y], [sensor_PM2_5], [sensor_CO], [sensor_SO2], [sensor_O3], [sensor_HCHO], [sensor_MQ2]) VALUES (354298, 32.00441054522347, 118.7206203869564, 400108, 400109, 400111, 400119, 403707, 403708);
97 |
98 | -- Index:
99 | ;
100 |
101 |
102 | -- Index:
103 | ;
104 |
105 |
106 | -- Index:
107 | ;
108 |
109 |
--------------------------------------------------------------------------------
/server/weixin/sqlite:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/server/weixin/sqlite
--------------------------------------------------------------------------------
/server/weixin/sqlitedb.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/server/weixin/sqlitedb.db
--------------------------------------------------------------------------------
/server/weixin/sqlitedb_backup.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/server/weixin/sqlitedb_backup.db
--------------------------------------------------------------------------------
/server/weixin/sqlitedb_bak1.db:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhangsheng377/air_monitor/4fd403e1b7bfd9c132c2414bc6d64a260cca99ac/server/weixin/sqlitedb_bak1.db
--------------------------------------------------------------------------------
/server/weixin/test.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/weixin/test2.php:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/server/weixin/test3.php:
--------------------------------------------------------------------------------
1 | query("SELECT * FROM users");
10 | $dbhandle->close();
11 | while($result = $query->fetchArray()){
12 | echo var_dump($result);
13 | }
14 | $result = sqlite_fetch_all($query);
15 | echo var_dump($result);
16 |
17 | ?>
18 |
--------------------------------------------------------------------------------
/server/weixin/test4.php:
--------------------------------------------------------------------------------
1 | query("SELECT * FROM users");
10 | $dbhandle->close();
11 | while($result = $query->fetchArray()){
12 | echo var_dump($result);
13 | }
14 |
15 | ?>
16 |
--------------------------------------------------------------------------------
/server/weixin/test5.php:
--------------------------------------------------------------------------------
1 |
2 |
3 | PHP Test
4 |
5 |
6 |
7 |
8 | query("SELECT name FROM sensor_names") or die($dbhandle->lastErrorMsg());
18 | //$dbhandle->close();
19 | $sql_command="SELECT name FROM sensor_names";
20 | $dbhandle = new SQLite3('sqlitedb.db');
21 | if (empty($error)) {
22 | $result = $dbhandle->query("$sql_command");
23 | } else {
24 | $result = $dbhandle->exec("$sql_command");
25 | }
26 | //$dbhandle->close();
27 | //return $result;
28 | $query=$result;
29 |
30 | while ($entry=$query->fetchArray()){
31 | $name = $entry['name'];
32 | echo var_dump($name);
33 | }
34 |
35 | echo rand(0,200)*1.0/1000.0;
36 |
37 | //$result = $query->fetchArray();
38 | //echo $result[0];
39 | //while($result = $query->fetchArray()){
40 | // echo var_dump($result);
41 | //}
42 |
43 |
44 | ?>
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/server/weixin/warningtemplate.php:
--------------------------------------------------------------------------------
1 | $value_limit) {
42 | echo "$value\n\r";
43 | echo "abs($value - $alertvalue)\n\r";
44 | echo "$time - $alerttime";
45 | $alertvalue = $user_detail["$sensor_name[0]_alertvalue"];
46 | if (abs($value - $alertvalue) > 0.1) {
47 | $time = time();
48 | $alerttime = $user_detail["$sensor_name[0]_alerttime"];
49 | if ($time - $alerttime > 60 * 30) {
50 | $template = array(
51 | 'touser' => "$openid",
52 | 'template_id' => "NGh_7ivNtf_AhRY5TrKBNGBrV-HsqZveiTeMNKTSYYA",
53 | 'url' => "http://www.yeelink.net/devices/$device_id/#sensor_$sensor_id",
54 | 'data' => array(
55 | 'first' => array(
56 | 'value' => urlencode("您身边的 $sensor_truename 数值超过报警阈值!"),
57 | 'color' => "#743A3A"),
58 | 'second' => array(
59 | 'value' => urlencode("请注意身体健康!"),
60 | 'color' => "#743A3A"),
61 | 'third' => array(
62 | 'value' => urlencode("传感器数值:"),
63 | 'color' => "#000000"),
64 | 'fourth' => array(
65 | 'value' => urlencode("$value"),
66 | 'color' => "#FF0000")));
67 | $template_result = curl_request("https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=$access_token", urldecode(json_encode($template)));
68 | $template_json = json_decode($template_result, true);
69 | if ($template_json["errmsg"] == "ok") {
70 | $sql_command = "UPDATE users SET $sensor_name[0]_alertvalue = $value , $sensor_name[0]_alerttime = $time WHERE openid=='$openid'";
71 | $is_exec = mysqlite_do($sql_command, $error);
72 | if (!$is_exec) {
73 | echo "$error";
74 | }
75 | }
76 | }
77 | }
78 | }
79 | }
80 | }
81 |
82 |
83 | function curl_request($durl, $data = null)
84 | {
85 | $ch = curl_init();
86 | curl_setopt($ch, CURLOPT_URL, $durl);
87 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);//获取数据返回
88 | if (!empty($data)) {
89 | echo "curl_data:$data";
90 | curl_setopt($ch, CURLOPT_POST, true);
91 | curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
92 | }
93 | $r = curl_exec($ch);
94 | //echo "url:$durl\nr:$r\n";
95 | curl_close($ch);
96 | return $r;
97 | }
98 |
99 | function update_access_token()
100 | {
101 | global $access_token, $time_expires_in;
102 | $file_name = "access_token.dat";
103 | $file_read = fopen($file_name, "rb");
104 | $data_file = fscanf($file_read, "%s\t%d");
105 | fclose($file_read);
106 | //echo "up_0:" . $data_file[1] . "\n";
107 | if (time() < $data_file[1]) {
108 | $access_token = $data_file[0];
109 | $time_expires_in = $data_file[1];
110 | } else {
111 | $appid = "wx691945ff03ba6040";
112 | $appsecret = "1e22eb6471847adef6c330719a739773";
113 | $data = curl_request("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret");
114 | //echo "data:" . $data . "\n";
115 | $data_json = json_decode($data, true);
116 | $access_token = $data_json["access_token"];
117 | //echo "acc:" . $data_json["access_token"] . "\n";
118 | $time_expires_in = time() + $data_json["expires_in"] - 200;
119 | $file_write = fopen($file_name, "wb");
120 | fwrite($file_write, $access_token);
121 | fwrite($file_write, "\t");
122 | fwrite($file_write, $time_expires_in);
123 | fclose($file_write);
124 | }
125 | }
126 |
127 |
128 | function mysqlite_do($sql_command, &$error = null)
129 | {
130 | $dbhandle = sqlite_open('sqlitedb.db');
131 | if (empty($error)) {
132 | $result = sqlite_query($dbhandle, "$sql_command");
133 | } else {
134 | $result = sqlite_exec($dbhandle, "$sql_command", $error);
135 | }
136 | sqlite_close($dbhandle);
137 | return $result;
138 | }
139 |
140 | function yeelinkapi_read_lastvalue($device_id, $sensor_id)
141 | {
142 | $durl = "http://api.yeelink.net/v1.0/device/$device_id/sensor/$sensor_id/datapoints";
143 | $data = curl_request($durl);
144 | $data_json = json_decode($data, true);
145 | return $data_json["value"];
146 | }
147 |
148 | ?>
--------------------------------------------------------------------------------
/sg90.py:
--------------------------------------------------------------------------------
1 | import time
2 | import signal
3 | import atexit
4 | import RPi.GPIO as GPIO
5 |
6 | atexit.register(GPIO.cleanup)
7 |
8 | horizon_servopin=12
9 | vertical_servopin=16
10 | GPIO.setmode(GPIO.BOARD)
11 | GPIO.setup(horizon_servopin,GPIO.OUT,initial=False)
12 | GPIO.setup(vertical_servopin,GPIO.OUT,initial=False)
13 | p_horizon=GPIO.PWM(horizon_servopin,50)
14 | p_vertical=GPIO.PWM(vertical_servopin,50)
15 | p_horizon.start(0)
16 | p_vertical.start(0)
17 |
18 | def servodriver(servo,angle):
19 | i=angle/3.6+25
20 | servo.ChangeDutyCycle(i/10.0)
21 |
22 |
23 |
24 | Clock = 36
25 | Address = 38
26 | DataOut = 40
27 |
28 | def ADC_Read(channel):
29 | value = 0;
30 | for i in range(0,4):
31 | if((channel >> (3 - i)) & 0x01):
32 | GPIO.output(Address,GPIO.HIGH)
33 | else:
34 | GPIO.output(Address,GPIO.LOW)
35 | GPIO.output(Clock,GPIO.HIGH)
36 | GPIO.output(Clock,GPIO.LOW)
37 | for i in range(0,6):
38 | GPIO.output(Clock,GPIO.HIGH)
39 | GPIO.output(Clock,GPIO.LOW)
40 | time.sleep(0.001)
41 | for i in range(0,10):
42 | GPIO.output(Clock,GPIO.HIGH)
43 | value <<= 1
44 | if(GPIO.input(DataOut)):
45 | value |= 0x01
46 | GPIO.output(Clock,GPIO.LOW)
47 | return value
48 |
49 | GPIO.setwarnings(False)
50 | GPIO.setup(Clock,GPIO.OUT)
51 | GPIO.setup(Address,GPIO.OUT)
52 | GPIO.setup(DataOut,GPIO.IN,GPIO.PUD_UP)
53 |
54 |
55 | horizon_light_min_channel=6
56 | horizon_light_max_channel=7
57 | vertical_light_min_channel=8
58 | vertical_light_max_channel=9
59 | light_gap=5
60 | horizon_angle=0
61 | vertical_angle=0
62 |
63 | while True:
64 | horizon_light_min=ADC_Read(horizon_light_min_channel)
65 | horizon_light_max=ADC_Read(horizon_light_max_channel)
66 | vertical_light_min=ADC_Read(vertical_light_min_channel)
67 | vertical_light_max=ADC_Read(vertical_light_max_channel)
68 | while horizon_light_max-horizon_light_min>light_gap:
69 | if horizon_angle+1>180:
70 | horizon_angle=180
71 | else:
72 | horizon_angle=horizon_angle+1
73 | servodriver(p_horizon,horizon_angle)
74 | time.sleep(0.5)
75 | horizon_light_min=ADC_Read(horizon_light_min_channel)
76 | horizon_light_max=ADC_Read(horizon_light_max_channel)
77 | while horizon_light_min-horizon_light_max>light_gap:
78 | if horizon_angle-1<0:
79 | horizon_angle=0
80 | else:
81 | horizon_angle=horizon_angle-1
82 | servodriver(p_horizon,horizon_angle)
83 | time.sleep(0.5)
84 | horizon_light_min=ADC_Read(horizon_light_min_channel)
85 | horizon_light_max=ADC_Read(horizon_light_max_channel)
86 | while vertical_light_max-vertical_light_min>light_gap:
87 | if vertical_angle+1>180:
88 | vertical_angle=180
89 | else:
90 | vertical_angle=vertical_angle+1
91 | servodriver(p_vertical,vertical_angle)
92 | time.sleep(0.5)
93 | vertical_light_min=ADC_Read(vertical_light_min_channel)
94 | vertical_light_max=ADC_Read(vertical_light_max_channel)
95 | while vertical_light_min-vertical_light_max>light_gap:
96 | if vertical_angle-1<0:
97 | vertical_angle=0
98 | else:
99 | vertical_angle=vertical_angle-1
100 | servodriver(p_vertical,vertical_angle)
101 | time.sleep(0.5)
102 | vertical_light_min=ADC_Read(vertical_light_min_channel)
103 | vertical_light_max=ADC_Read(vertical_light_max_channel)
104 |
105 | '''
106 | #for i in range(25,125,1):
107 | for i in range(0,181,2):
108 | servodriver(p_horizon,i)
109 | servodriver(p_vertical,i/2.0)
110 | print i
111 | time.sleep(0.5)
112 | '''
113 | '''
114 | while(True):
115 | for i in range(0,360,10):
116 | p.ChangeDutyCycle(12.5-5*i/360)
117 | time.sleep(1)
118 | for i in range(0,360,10):
119 | p.ChangeDutyCycle(7.5-5*i/360)
120 | time.sleep(1)
121 | '''
122 |
--------------------------------------------------------------------------------