项目

一般

简介

Linkage.php

李 凯健, 2024-08-23 17:32

 
1
<?php
2
define("WNMP_PATH", realpath(dirname(__FILE__) . '/../../../../../'));
3

    
4
$str = $argv[1];
5

    
6
$arrData = array();
7
$arrTmp = explode(',', $str);
8
for ($i = 0; $i < sizeof($arrTmp); $i = $i + 2) {
9
        $arrData[$arrTmp[$i]] = $arrTmp[$i + 1];
10
}
11

    
12
// memcached
13
$mip = $arrData['mip'];
14
$mport = $arrData['mport'];
15
$mexpire = $arrData['mexpire'];
16

    
17
// 日志路径
18
$log_part = $arrData['log_part'];
19

    
20
// 版本号
21
$v = $arrData['v'];
22

    
23
$memcache = new Memcache();
24
$memcache->connect($mip, $mport);
25

    
26
setLog('start:' . $arrData['id']);
27

    
28
declare(ticks = 1);
29
$is_end = false;
30

    
31
function catch_error()
32
{
33
        global $is_end;
34
        $time = date('Y-m-d H:i:s');
35
        $error = error_get_last();
36
        $msg = "$time [error]";
37
        if ($is_end) {
38
                $msg .= "is_end[yes]";
39
        } else {
40
                $msg .= "is_end[no]";
41
        }
42
        if ($error) {
43
                $msg .= var_export($error, 1);
44
        }
45
        setLog($msg);
46
}
47
register_shutdown_function("catch_error");
48

    
49
function sig_handler($signo)
50
{
51
        $time = date('Y-m-d H:i:s');
52
        if ($signo == 14) {
53
                // 忽略alarm信号
54
                setLog($time . " ignore alarm signo[{$signo}]");
55
        } else {
56
                setLog($time . " exit  signo[{$signo}]");
57
                exit("");
58
        }
59
}
60
/*
61
 * pcntl_signal(SIGTERM, "sig_handler");
62
 * pcntl_signal(SIGHUP, "sig_handler");
63
 * pcntl_signal(SIGINT, "sig_handler");
64
 * pcntl_signal(SIGQUIT, "sig_handler");
65
 * pcntl_signal(SIGILL, "sig_handler");
66
 * pcntl_signal(SIGPIPE, "sig_handler");
67
 * pcntl_signal(SIGALRM, "sig_handler");
68
 */
69

    
70
$arrTmpInfo = array(
71
        'state' => '1',
72
        'pid' => getmypid()
73
);
74
$arrEqControl = array();
75
$interval = 900;
76
$controlInterval = 0;
77

    
78
while (1) {
79
        $memcache->set($v . "LINKAGE-INFO-" . $arrData['id'], $arrTmpInfo, 0, $mexpire);
80
        
81
        $keyName = $v . "LINKAGE";
82
        $arr = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
83
        
84
        foreach ($arr as $key => $value) {
85
                if ($value['ID'] == $arrData['id']) {
86
                        // 联动
87
                        switch ($value['type']) {
88
                                case 0:
89
                                        // 温度联动(1792)
90
                                        linkageTem($arrData['id'], $value);
91
                                        break;
92
                                case 1:
93
                                        // 湿度联动(5000)
94
                                        linkageHum($arrData['id'], $value);
95
                                        break;
96
                                default:
97
                        }
98
                        break;
99
                }
100
        }
101
        
102
        sleep(5);
103
}
104

    
105
setLog('end:' . $arrData['id']);
106

    
107
/**
108
 * 检查控制(手动自动)
109
 *
110
 * @return boolean
111
 */
112
function checkControl($eq_sn, $eq_no)
113
{
114
        global $memcache;
115
        global $v;
116
        
117
        $bool = true;
118
        
119
        // 获取参数设置
120
        $keyName = $v . "PARAMETERS";
121
        $info = $memcache->get($keyName);
122
        if ($info === false) {
123
                return false;
124
        }
125
        
126
        $keyName = $v . "EQUIPMENTS";
127
        $arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
128
        
129
        foreach ($arrMemcacheEquipments as $key => $value) {
130
                if ($value['eq_sn'] == $eq_sn && $value['eq_no'] == $eq_no) {
131
                        $arrItem = explode("\n", $value['control_opt']);
132
                        foreach ($arrItem as $k => $val) {
133
                                if (strpos($val, 'sctrl') !== false) {
134
                                        $pname = "sctrl_" . $eq_sn . "_" . $eq_no;
135
                                        if (empty($info[$pname])) {
136
                                                $bool = false;
137
                                                break 2;
138
                                        }
139
                                }
140
                        }
141
                }
142
        }
143
        
144
        return $bool;
145
}
146

    
147
// 温度联动(1792)
148
function linkageTem($id, $arr)
149
{
150
        global $memcache;
151
        global $mexpire;
152
        global $arrTmpInfo;
153
        global $v;
154
        global $arrEqControl;
155
        global $interval;
156
        global $controlInterval;
157
        $b = false;
158
        
159
        $arrData = json_decode($arr['data'], true);
160
        
161
        // 获取平均温度值
162
        $avg = "0";
163
        $num = "0";
164
        $arrTmpSn = explode(',', $arr['eq_sn_m']);
165
        $arrTmpNo = explode(',', $arr['eq_no_m']);
166
        foreach ($arrTmpSn as $key => $value) {
167
                $keyName = $v . "EQUIP-LATEST-" . $arrTmpSn[$key] . "-" . $arrTmpNo[$key];
168
                $current_value = !isset($memcache->get($keyName)['Tem']) ? null : $memcache->get($keyName)['Tem'];
169
                if ($current_value === null) {
170
                        setLog("error($id):获取温度失败,sn($arrTmpSn[$key]),no($arrTmpNo[$key])");
171
                        continue;
172
                }
173
                $avg += $current_value;
174
                $num ++;
175
        }
176
        $avg = empty($num) ? $avg : $avg / $num;
177
        
178
        // 检查获取温度设备数量
179
        if (empty($num)) {
180
                setLog("error($id):获取平均温度失败");
181
                return false;
182
        }
183
        
184
        $keyName = $v . "EQUIPMENTS";
185
        $arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
186
        
187
        $arrEqControl = array();
188
        $arrTmpSn = explode(',', $arr['eq_sn_l']);
189
        $arrTmpNo = explode(',', $arr['eq_no_l']);
190
        // 获取联动设备信息
191
        foreach ($arrTmpSn as $key => $value) {
192
                foreach ($arrMemcacheEquipments as $k => $val) {
193
                        if ($val['eq_sn'] == $arrTmpSn[$key] && $val['eq_no'] == $arrTmpNo[$key]) {
194
                                $properties = json_decode($val['properties'], true);
195
                                $arrEqControl[] = array(
196
                                        'eq_sn' => $arrTmpSn[$key],
197
                                        'eq_no' => $arrTmpNo[$key],
198
                                        'properties' => $properties
199
                                );
200
                        }
201
                }
202
        }
203
        
204
        if (isset($arrData[0]) && $controlInterval < time()) {
205
                if (checkAlertRules($avg, $arrData[0]['vtype'], $arrData[0]['min_value'], $arrData[0]['max_value'], $arrData[0]['xor_value'])) {
206
                        // 进行联动操作
207
                        foreach ($arrEqControl as $key => $value) {
208
                                $tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], $arrData[0]['control'], $value['properties']);
209
                                if (! $tmp) {
210
                                        setLog("error($id):控制开启失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
211
                                } else {
212
                                        $b = true;
213
                                }
214
                        }
215
                }
216
        }
217
        
218
        if (isset($arrData[1]) && $controlInterval < time()) {
219
                // 关闭操作
220
                if (checkAlertRules($avg, $arrData[1]['vtype'], $arrData[1]['min_value'], $arrData[1]['max_value'], $arrData[1]['xor_value'])) {
221
                        // 进行联动操作
222
                        foreach ($arrEqControl as $key => $value) {
223
                                $tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], 0, $value['properties']);
224
                                if (! $tmp) {
225
                                        setLog("error($id):控制关闭失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
226
                                } else {
227
                                        $b = true;
228
                                }
229
                        }
230
                }
231
        }
232
        
233
        if ($b) {
234
                $controlInterval = time() + $interval;
235
                $b = false;
236
        }
237
}
238

    
239
// 湿度联动(5000)
240
function linkageHum($id, $arr)
241
{
242
        global $memcache;
243
        global $mexpire;
244
        global $arrTmpInfo;
245
        global $v;
246
        global $arrEqControl;
247
        global $interval;
248
        global $controlInterval;
249
        $b = false;
250
        
251
        $arrData = json_decode($arr['data'], true);
252
        
253
        // 获取平均湿度值
254
        $avg = "0";
255
        $num = "0";
256
        $arrTmpSn = explode(',', $arr['eq_sn_m']);
257
        $arrTmpNo = explode(',', $arr['eq_no_m']);
258
        foreach ($arrTmpSn as $key => $value) {
259
                $keyName = $v . "EQUIP-LATEST-" . $arrTmpSn[$key] . "-" . $arrTmpNo[$key];
260
                $current_value = !isset($memcache->get($keyName)['Hum']) ? null : $memcache->get($keyName)['Hum'];
261
                if ($current_value === null) {
262
                        setLog("error($id):获取湿度失败,sn($arrTmpSn[$key]),no($arrTmpNo[$key])");
263
                        continue;
264
                }
265
                $avg += $current_value;
266
                $num ++;
267
        }
268
        $avg = empty($num) ? $avg : $avg / $num;
269
        
270
        // 检查获取湿度设备数量
271
        if (empty($num)) {
272
                setLog("error($id):获取平均湿度失败");
273
                return false;
274
        }
275
        
276
        $keyName = $v . "EQUIPMENTS";
277
        $arrMemcacheEquipments = $memcache->get($keyName) === false ? array() : $memcache->get($keyName);
278
        
279
        $arrEqControl = array();
280
        $arrTmpSn = explode(',', $arr['eq_sn_l']);
281
        $arrTmpNo = explode(',', $arr['eq_no_l']);
282
        // 获取联动设备信息
283
        foreach ($arrTmpSn as $key => $value) {
284
                foreach ($arrMemcacheEquipments as $k => $val) {
285
                        if ($val['eq_sn'] == $arrTmpSn[$key] && $val['eq_no'] == $arrTmpNo[$key]) {
286
                                $properties = json_decode($val['properties'], true);
287
                                $arrEqControl[] = array(
288
                                        'eq_sn' => $arrTmpSn[$key],
289
                                        'eq_no' => $arrTmpNo[$key],
290
                                        'properties' => $properties
291
                                );
292
                        }
293
                }
294
        }
295
        
296
        if (isset($arrData[0]) && $controlInterval < time()) {
297
                if (checkAlertRules($avg, $arrData[0]['vtype'], $arrData[0]['min_value'], $arrData[0]['max_value'], $arrData[0]['xor_value'])) {
298
                        // 进行联动操作
299
                        foreach ($arrEqControl as $key => $value) {
300
                                $tmp = sendControl_1792($id, $value['eq_sn'], $value['eq_no'], $arrData[0]['control'], $value['properties']);
301
                                if (! $tmp) {
302
                                        setLog("error($id):控制开启失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
303
                                } else {
304
                                        $b = true;
305
                                }
306
                        }
307
                }
308
        }
309
        
310
        if (isset($arrData[1]) && $controlInterval < time()) {
311
                // 关闭操作
312
                if (checkAlertRules($avg, $arrData[1]['vtype'], $arrData[1]['min_value'], $arrData[1]['max_value'], $arrData[1]['xor_value'])) {
313
                        // 进行联动操作
314
                        foreach ($arrEqControl as $key => $value) {
315
                                $tmp = sendControl_5000($id, $value['eq_sn'], $value['eq_no'], 0, $value['properties']);
316
                                if (! $tmp) {
317
                                        setLog("error($id):控制关闭失败,sn(" . $value['eq_sn'] . "),no(" . $value['eq_no'] . ")");
318
                                } else {
319
                                        $b = true;
320
                                }
321
                        }
322
                }
323
        }
324
        
325
        if ($b) {
326
                $controlInterval = time() + $interval;
327
                $b = false;
328
        }
329
}
330

    
331
/**
332
 * 检查报警规则
333
 *
334
 * @param string $value
335
 *                当前值
336
 * @param string $vtype
337
 *                检查类型
338
 * @param string $min_value
339
 *                最小值
340
 * @param string $max_value
341
 *                最大值
342
 * @param string $xor_value
343
 *                等于值
344
 * @return boolean
345
 */
346
function checkAlertRules($value, $vtype, $min_value, $max_value, $xor_value, &$iDescribe = 0, &$threshold = '')
347
{
348
        switch ($vtype) {
349
                case '0':
350
                        // 范围内
351
                        $threshold = "$min_value ~ $max_value";
352
                        if ($min_value <= $value and $value <= $max_value) {
353
                                return true;
354
                        } else {
355
                                $iDescribe = $value < $min_value ? 0 : 1;
356
                                return false;
357
                        }
358
                        break;
359
                case '1':
360
                        // 范围外
361
                        $threshold = "~ $min_value || $max_value ~";
362
                        if ($value < $min_value or $max_value < $value) {
363
                                return true;
364
                        } else {
365
                                return false;
366
                        }
367
                        break;
368
                case '2':
369
                        // 小于小值
370
                        $threshold = "~ $min_value";
371
                        if ($value < $min_value) {
372
                                return true;
373
                        } else {
374
                                return false;
375
                        }
376
                        break;
377
                case '3':
378
                        // 大于大值
379
                        $threshold = "$max_value ~";
380
                        if ($max_value < $value) {
381
                                return true;
382
                        } else {
383
                                return false;
384
                        }
385
                        break;
386
                case '4':
387
                        // 通路检测
388
                        $threshold = "$xor_value";
389
                        if ($xor_value == $value) {
390
                                return true;
391
                        } else {
392
                                return false;
393
                        }
394
                        break;
395
                default:
396
        }
397
        
398
        return true;
399
}
400

    
401
/**
402
 * 发送控制命令-4944
403
 *
404
 * @return void
405
 *
406
 */
407
function sendControl_4944($id, $sn, $no, $cmdid, $arrProperties)
408
{
409
        if (empty($arrProperties)) {
410
                setLog("4944-error($id):获取联动设备数据失败");
411
                return false;
412
        }
413
        
414
        $cip = $arrProperties['cip'];
415
        $sid = $no;
416
        $url = "http://$cip/action/doctrl";
417
        
418
        // 制冷开机、制热开机、关机
419
        $data = array(
420
                'op' => ($cmdid & 0xffff),
421
                'value' => ($sid << 16) | (0 & 0xFFFF)
422
        );
423
        
424
        setLog("4944-send($id):" . $url);
425
        setLog("4944-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
426
        $result = curl_request($url, $data);
427
        setLog("4944-back($id):" . $result);
428
        
429
        $arrTmp = json_decode($result, true);
430
        if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
431
                return true;
432
        }
433
        
434
        return false;
435
}
436

    
437
/**
438
 * 发送控制命令-5000
439
 *
440
 * @return void
441
 *
442
 */
443
function sendControl_5000($id, $sn, $no, $cmdid, $arrProperties)
444
{
445
        if (empty($arrProperties)) {
446
                setLog("5000-error($id):获取联动设备数据失败");
447
                return false;
448
        }
449
        
450
        $cip = $arrProperties['cip'];
451
        $sid = $no;
452
        $url = "http://$cip/action/doctrl";
453
        
454
        // 制冷开机、制热开机、关机
455
        $ival = $cmdid == 1 ? 16 : 128;
456
        $data = array(
457
                'op' => (6 << 16) | (20 & 0xFFFF),
458
                'value' => ($sid << 16) | ($ival & 0xFFFF)
459
        );
460
        
461
        setLog("5000-send($id):" . $url);
462
        setLog("5000-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
463
        $result = curl_request($url, $data);
464
        setLog("5000-back($id):" . $result);
465
        
466
        $arrTmp = json_decode($result, true);
467
        if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
468
                return true;
469
        }
470
        
471
        return false;
472
}
473

    
474
/**
475
 * 发送控制命令-1792
476
 *
477
 * @return void
478
 *
479
 */
480
function sendControl_1792($id, $sn, $no, $cmdid, $arrProperties)
481
{
482
        if (empty($arrProperties)) {
483
                setLog("1792-error($id):获取联动设备数据失败");
484
                return false;
485
        }
486
        
487
        $mode = '';
488
        $ext3 = '';
489
        switch ($cmdid) {
490
                case '0':
491
                        // 关机
492
                        $mode = '1';
493
                        $ext3 = '0';
494
                        break;
495
                case '3':
496
                        // 制冷开机
497
                        $mode = '1';
498
                        $ext3 = '1';
499
                        break;
500
                case '4':
501
                        // 制热开机
502
                        $mode = '2';
503
                        $ext3 = '1';
504
                        break;
505
                default:
506
        }
507
        
508
        $cip = $arrProperties['cip'];
509
        $sid = $no;
510
        $url = "http://$cip/action/aircdas";
511
        
512
        $data = array(
513
                'op' => '1000',
514
                'value' => (($sid << 16) | 42),
515
                'ext' => '1',
516
                'ext2' => $mode,
517
                'ext3' => $ext3,
518
                'name' => ''
519
        );
520
        
521
        setLog("1792-send($id):" . $url);
522
        setLog("1792-data($id):" . json_encode($data, JSON_UNESCAPED_UNICODE));
523
        $result = curl_request($url, $data);
524
        setLog("1792-back($id):" . $result);
525
        
526
        $arrTmp = json_decode($result, true);
527
        if (! empty($result) and ($result == 'ok' || (isset($arrTmp['op']) && $arrTmp['op'] == 'ok'))) {
528
                return true;
529
        }
530
        
531
        return false;
532
}
533

    
534
/**
535
 * 通过php的curl库获取ajax的返回值
536
 *
537
 * @param $url 请求地址                
538
 * @param $post post数据(不填则为GET)                
539
 * @param $cookie 提交的$cookies                
540
 * @param $returnCookie 是否返回$cookies                
541
 * @return true/false
542
 *
543
 */
544
function curl_request($url, $post = '', $cookie = '', $returnCookie = 0, $proxy = '')
545
{
546
        $url = empty($url) ? $this->url : $url;
547
        
548
        $curl = curl_init();
549
        if ($proxy) {
550
                curl_setopt($curl, CURLOPT_PROXY, $proxy);
551
        }
552
        curl_setopt($curl, CURLOPT_URL, $url);
553
        curl_setopt($curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)');
554
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
555
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
556
        // ******************取消ssl双向认证****************//
557
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);
558
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
559
        // *************************************************//
560
        curl_setopt($curl, CURLOPT_REFERER, "http://www.vencs.com/");
561
        if ($post) {
562
                curl_setopt($curl, CURLOPT_POST, 1);
563
                curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
564
        }
565
        if ($cookie) {
566
                curl_setopt($curl, CURLOPT_COOKIE, $cookie);
567
        }
568
        curl_setopt($curl, CURLOPT_HEADER, $returnCookie);
569
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
570
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
571
        $data = curl_exec($curl);
572
        if (curl_errno($curl)) {
573
                return curl_error($curl);
574
        }
575
        curl_close($curl);
576
        if ($returnCookie) {
577
                list ($header, $body) = explode("\r\n\r\n", $data, 2);
578
                preg_match_all("/Set\-Cookie:([^;]*);/", $header, $matches);
579
                $info['cookie'] = substr($matches[1][0], 1);
580
                $info['content'] = $body;
581
                return $info;
582
        } else {
583
                return $data;
584
        }
585
}
586

    
587
/**
588
 * 记录日志
589
 *
590
 * @param string $str
591
 *                内容
592
 * @param string $filename
593
 *                可选,文件名,默认'Linkage'
594
 */
595
function setLog($str, $filename = 'Linkage')
596
{
597
        global $log_part;
598
        
599
        file_put_contents($log_part . $filename . "_" . date('Y-m-d') . ".log", '[' . date('Y-m-d H:i:s') . ']' . $str . PHP_EOL, FILE_APPEND);
600
}