Quellcode durchsuchen

Merge branch 'rmaster' into rtest

stanley-king vor 4 Jahren
Ursprung
Commit
db6115ebe4

+ 2 - 0
admin/templates/default/css/recharge.css

@@ -7,12 +7,14 @@
 .w86 {width:86px;}
 .w90 {width:90px;}
 .w100 {width:100px;}
+.w130 {width: 130px;}
 .w160 {width:160px;}
 
 .mw24 {min-width:24px;}
 .mw60 {min-width:60px;}
 .mw96 {min-width:96px;}
 .mw120 {min-width:120px;}
+.mw130 {min-width:130px;}
 .mw160 {min-width:160px;}
 .mw156 {min-width:156px;}
 

+ 1 - 1
admin/templates/default/provider.amount.control.php

@@ -37,7 +37,7 @@
                         <tr class="w550" style="display:block;">
                             <th class="align-center w120 mw120"></th>
                             <?php foreach ($output['providers'] as $provider) { ?>
-                            <th class="align-center w156 mw156"><?php echo $provider['store_name']?>(<?php if($provider['opened'] == 1){?>
+                            <th class="align-center w160 mw160"><?php echo $provider['store_name']?>(<?php if($provider['opened'] == 1){?>
                                 <span style="color: #0bb20c">开启</span>
                             <?php }?><?php if($provider['opened'] == 2){?>
                                         <span style="color: #f30707">关闭</span>

+ 33 - 31
crontab/control/minutes.php

@@ -30,44 +30,46 @@ class minutesControl extends BaseCronControl
 
     private function _check_merchant_alarm_amount()
     {
-        $mch_cache = rcache("merchant-notify" , 'refill-');
-        $caches = empty($mch_cache['data']) ? [] : unserialize($mch_cache['data']);
-
-        $new_caches = [];
-        $merchants = Model('merchant')->getMerchantList([],'','','merchant.*,member.available_predeposit' ,"0,1000");
-        foreach ($merchants as $merchant)
-        {
-            $mchid = $merchant['mchid'];
-            $phones = empty($merchant['warning_phone']) ? [] : unserialize($merchant['warning_phone']);
-            $available_pd = intval($merchant['available_predeposit']);
-            $alarm_pd = intval($merchant['alarm_amount']);
+        if(defined('COMPANY_NAME') && COMPANY_NAME === 'XYZ_COMPANY') {
+            $mch_cache = rcache("merchant-notify" , 'refill-');
+            $caches = empty($mch_cache['data']) ? [] : unserialize($mch_cache['data']);
 
-            if(array_key_exists($mchid,$caches)) {
-                $mch_cache = $caches[$mchid];
-            }
-            else {
-                $mch_cache = ['last_time' => 0, 'send_count' => 0];
-            }
-            if($available_pd < $alarm_pd || $available_pd < 10000)
+            $new_caches = [];
+            $merchants = Model('merchant')->getMerchantList([],'','','merchant.*,member.available_predeposit' ,"0,1000");
+            foreach ($merchants as $merchant)
             {
-                $counts =  $mch_cache['send_count'];
-                if(($mch_cache['last_time'] + 300 < time()) && $counts < 2) {
-                    $mch_cache = ['last_time' => time(), 'send_count' => $counts + 1];
-                    foreach ($phones as $phone) {
-                        if(!empty($phone)){
-                            QueueClient::push('sendSMS', ['mobile'=>$phone,
-                                'type'=>'balance_warning','datas' => [date("m月d日H时") , $merchant['available_predeposit']]]);
+                $mchid = $merchant['mchid'];
+                $phones = empty($merchant['warning_phone']) ? [] : unserialize($merchant['warning_phone']);
+                $available_pd = intval($merchant['available_predeposit']);
+                $alarm_pd = intval($merchant['alarm_amount']);
+
+                if(array_key_exists($mchid,$caches)) {
+                    $mch_cache = $caches[$mchid];
+                }
+                else {
+                    $mch_cache = ['last_time' => 0, 'send_count' => 0];
+                }
+                if($available_pd < $alarm_pd || $available_pd < 10000)
+                {
+                    $counts =  $mch_cache['send_count'];
+                    if(($mch_cache['last_time'] + 300 < time()) && $counts < 2) {
+                        $mch_cache = ['last_time' => time(), 'send_count' => $counts + 1];
+                        foreach ($phones as $phone) {
+                            if(!empty($phone)){
+                                QueueClient::push('sendSMS', ['mobile'=>$phone,
+                                    'type'=>'balance_warning','datas' => [date("m月d日H时") , $merchant['available_predeposit']]]);
+                            }
                         }
                     }
                 }
+                else {
+                    $mch_cache = ['last_time' => 0, 'send_count' => 0];
+                }
+                $new_caches[$mchid] = $mch_cache;
             }
-            else {
-                $mch_cache = ['last_time' => 0, 'send_count' => 0];
-            }
-            $new_caches[$mchid] = $mch_cache;
-        }
 
-        wcache("merchant-notify", ['data' => serialize($new_caches)], 'refill-');
+            wcache("merchant-notify", ['data' => serialize($new_caches)], 'refill-');
+        }
     }
 
     public function check_refill_order_limit()

+ 30 - 10
docker/compose/stanley/docker-compose.yml

@@ -189,13 +189,33 @@ services:
       - "websrv"
       - "searcher"
 
-#  async:
-#    image: php-swool-redis:latest
-#    volumes:
-#      - ../../conf/etc/localtime:/etc/localtime:ro
-#      - ../../conf/php/php-swoole-debug.ini:/usr/local/etc/php/php.ini
-#      - ../../../:/var/www/html
-#      - /Volumes/Transcend/upload:/var/www/html/data/upload
-#      - /Users/stanley-king/work/PHPProject/shoplog:/var/www/html/data/log
-#    container_name: "panda-async"
-#    command: [php, "/var/www/html//test/examples/process/async_master.php"]
+  flasksrv:
+    image: pycpu:3.7.10
+    ports:
+      - "5000:5000"
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /Users/stanley-king/work/PHPProject/shoplog:/var/www/html/data/log
+      - /Users/stanley-king/work/PHPProject/stdata:/var/www/html/data/stdata
+    container_name: "panda-flask"
+    command: ['python','app.py']
+
+  pythoncli:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /Users/stanley-king/work/PHPProject/shoplog:/var/www/html/data/log
+      - /Users/stanley-king/work/PHPProject/stdata:/var/www/html/data/stdata
+    container_name: "panda-python"
+
+  readersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /Users/stanley-king/work/PHPProject/shoplog:/var/www/html/data/log
+      - /Users/stanley-king/work/PHPProject/stdata:/var/www/html/data/stdata
+    container_name: "panda-reader"
+    command: ['python','reader.py']

+ 26 - 0
docker/compose/xyz-stat/docker-compose.yml

@@ -0,0 +1,26 @@
+version: "3.7"
+
+services:
+  readersrv:
+    image: pycpu:3.7.10
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-reader"
+    command: ['python','reader.py']
+
+  flasksrv:
+    image: pycpu:3.7.10
+    ports:
+      - "5000:5000"
+    volumes:
+      - ../../conf/etc/localtime:/etc/localtime:ro
+      - ../../../:/var/www/html
+      - /nfs/upload:/var/www/html/data/upload
+      - /mnt/shoplog:/var/www/html/data/log
+      - /mnt/stdata:/var/www/html/data/stdata
+    container_name: "panda-flask"
+    command: ['python','app.py']

+ 11 - 0
docker/conf/nginx/nginx-stanley-http.conf

@@ -61,6 +61,17 @@ http
 	        try_files $uri $uri/ /mshop/index.html;
         }
 
+        location /plot {
+            root $folder_name;
+            proxy_pass         http://host.docker.internal:5000;
+            proxy_redirect     off;
+
+            proxy_set_header   Host                 $host;
+            proxy_set_header   X-Real-IP            $remote_addr;
+            proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
+            proxy_set_header   X-Forwarded-Proto    $scheme;
+        }
+
         location ~ /mobile/[/\w]+\.php$ {
             root           $folder_name;
             fastcgi_pass   host.docker.internal:9100;

+ 11 - 0
docker/conf/nginx/nginx-xyz-https.conf

@@ -73,6 +73,17 @@ http
             try_files $uri $uri/ /mshop/index.html;
         }
 
+        location /plot {
+            root $folder_name;
+            proxy_pass         http://172.26.105.127:5000;
+              proxy_redirect     off;
+
+            proxy_set_header   Host                 $host;
+            proxy_set_header   X-Real-IP            $remote_addr;
+            proxy_set_header   X-Forwarded-For      $proxy_add_x_forwarded_for;
+            proxy_set_header   X-Forwarded-Proto    $scheme;
+        }
+
         location /merchant {
             root $folder_name;
             autoindex on;

+ 0 - 1
helper/refill/RefillBase.php

@@ -127,7 +127,6 @@ class RefillBase
 //                        }
 
                         util::push_add($params);
-
                         return true;
                     }
                 }

+ 0 - 42
helper/refill/util.php

@@ -296,18 +296,14 @@ class util
 
         $name = 'channel_monitor_commit';
         $sec = time();
-        $min = $sec - $sec % 60;
 
         if ($fsuccess) {
             $key_sec = "succ-{$chname}-{$quality}-{$card_type}-{$spec}-{$sec}";
-            $key_min = "succm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
         } else {
             $key_sec = "fail-{$chname}-{$quality}-{$card_type}-{$spec}-{$sec}";
-            $key_min = "failm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
         }
 
         $ins->hIncrBy($name, $key_sec, 1);
-        $ins->hIncrBy($name, $key_min, 1);
     }
 
     public static function hget_commit_sec($chname, $card_type, $spec, $quality, $time_stamp, $fsuccess = true)
@@ -325,23 +321,6 @@ class util
         return intval($value);
     }
 
-    public static function hget_commit_min($chname, $card_type, $spec, $quality, $time_stamp, $fsuccess = true)
-    {
-        $ins = Cache::getInstance('cacheredis');
-
-        $name = 'channel_monitor_commit';
-        $min = $time_stamp - $time_stamp % 60;
-
-        if ($fsuccess) {
-            $key_sec = "succm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
-        } else {
-            $key_sec = "failm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
-        }
-        $value = $ins->hget($name, '', $key_sec);
-
-        return intval($value);
-    }
-
     //统计回调通知数据
     public static function incr_notify($chname, $card_type, $spec, $quality, $fsuccess = true)
     {
@@ -349,18 +328,14 @@ class util
 
         $name = 'channel_monitor_notify';
         $sec = time();
-        $min = $sec - $sec % 60;
 
         if ($fsuccess) {
             $key_sec = "succ-{$chname}-{$quality}-{$card_type}-{$spec}-{$sec}";
-            $key_min = "succm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
         } else {
             $key_sec = "fail-{$chname}-{$quality}-{$card_type}-{$spec}-{$sec}";
-            $key_min = "failm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
         }
 
         $ins->hIncrBy($name, $key_sec, 1);
-        $ins->hIncrBy($name, $key_min, 1);
     }
 
     public static function hget_notify_sec($chname, $card_type, $spec, $quality, $time_stamp, $fsuccess = true)
@@ -378,23 +353,6 @@ class util
         return intval($value);
     }
 
-    public static function hget_notify_min($chname, $card_type, $spec, $quality, $time_stamp, $fsuccess = true)
-    {
-        $ins = Cache::getInstance('cacheredis');
-
-        $name = 'channel_monitor_notify';
-        $min = $time_stamp - $time_stamp % 60;
-
-        if ($fsuccess) {
-            $key_sec = "succm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
-        } else {
-            $key_sec = "failm-{$chname}-{$quality}-{$card_type}-{$spec}-{$min}";
-        }
-        $value = $ins->hget($name, '', $key_sec);
-
-        return intval($value);
-    }
-
     ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
     public static function incr_amount_lock($mchid, $card_type, $spec)
     {

+ 7 - 5
mobile/control/refill_evidence.php

@@ -59,11 +59,13 @@ class refill_evidenceControl extends mbMerchantControl
 
         $ret = $model_merchant->addRefillEvidence($data);
         if ($ret) {
-            global $config;
-            $phones = $config['system_manager_phones'];
-            foreach ($phones as $phone) {
-                $ret = QueueClient::push('sendSMS', ['mobile'=>$phone,'type'=>'evidence','datas' => [date("m月d日H时") , $merchant_info['company_name'] , $params['amount']]]);
-                Log::record("phone : {$phone} , result : {$ret}",Log::DEBUG);
+            if(defined('COMPANY_NAME') && COMPANY_NAME === 'XYZ_COMPANY') {
+                global $config;
+                $phones = $config['system_manager_phones'];
+                foreach ($phones as $phone) {
+                    $ret = QueueClient::push('sendSMS', ['mobile'=>$phone,'type'=>'evidence','datas' => [date("m月d日H时") , $merchant_info['company_name'] , $params['amount']]]);
+                    Log::record("phone : {$phone} , result : {$ret}",Log::DEBUG);
+                }
             }
             return self::outsuccess([]);
         } else {

+ 294 - 0
plot/DataCenter.py

@@ -0,0 +1,294 @@
+from threading import Thread
+import os
+import time as stime
+from Singleton import Singleton
+import redis
+import h5py
+from os import path
+import re
+from datetime import timedelta
+import numpy as np
+from matplotlib.figure import Figure
+from matplotlib import ticker
+from io import BytesIO
+import logging
+
+
+class DataCenter(object):
+    pos_map = {
+        'commit-succ': 0, 'commit-fail': 1, 'notify-succ': 2, 'notify-fail': 3, 'user_succ': 4
+    }
+
+    def __init__(self):
+        self._mquit = False
+        self._file_name = '/var/www/html/data/stdata/data.hdf5'
+
+    def stop(self):
+        self._mquit = True
+        pass
+
+    def prepare_data(self):
+        while True:
+            try:
+                # pool = redis.ConnectionPool(host='121.89.223.81', port=57649, db=0)
+                pool = redis.ConnectionPool(host='172.26.105.125', port=6379, db=0)
+                r = redis.Redis(connection_pool=pool)
+
+                if path.exists(self._file_name):
+                    hfive = h5py.File(self._file_name, 'a')
+                else:
+                    hfive = h5py.File(self._file_name, 'w')
+
+                self.read_redis(hfive, r, 'nc_channel_monitor_commit', 'commit')
+                self.read_redis(hfive, r, 'nc_channel_monitor_notify', 'notify')
+                hfive.close()
+
+                self.del_redis(r, 'nc_channel_monitor_commit')
+                self.del_redis(r, 'nc_channel_monitor_notify')
+            except Exception as ex:
+                print(ex)
+            finally:
+                for i in range(60):
+                    if self._mquit == True:
+                        break
+                    else:
+                        stime.sleep(1)
+
+    def del_redis(self, redis, name):
+        latest_time = int(stime.time()) - 300
+        for item in redis.hscan_iter(name):
+            key = str(item[0], encoding="utf-8")
+            items = re.split(r'-', key)
+
+            fdel = True
+            if len(items) == 6:
+                (stype, chname, quality, card_type, amount, time) = items
+                time = int(time)
+                if latest_time <= time:
+                    fdel = False
+
+            if fdel:
+                redis.hdel(name, key)
+        pass
+
+    def read_redis(self, hfive, redis, name, prefix):
+        i = 0
+        for item in redis.hscan_iter(name):
+            key = str(item[0], encoding="utf-8")
+            val = str(item[1], encoding="utf-8")
+            print(f'{prefix}:{i}')
+            i += 1
+            self.parase(hfive, key, val, prefix)
+
+    def parase(self, hfive, text, val, prefix):
+        items = re.split(r'-', text)
+        if len(items) != 6:
+            return False
+
+        (stype, chname, quality, card_type, amount, time) = items
+        if stype == 'succ':
+            pos = self.pos_map[f'{prefix}-succ']
+        elif stype == 'fail':
+            pos = self.pos_map[f'{prefix}-fail']
+        else:
+            return False
+
+        time = int(time)
+        today = self.day_stamp(time)
+        path = f'/{today}/{chname}/{quality}/{card_type}/{amount}'
+        if path not in hfive:
+            hfive[path] = np.zeros((5, 86400))
+
+        diff = time - today
+        if diff < 0:
+            print(diff)
+        hfive[path][pos, diff] = val
+        print(path, pos, diff, val, hfive[path][pos, diff])
+        pass
+
+    def day_stamp(self, stamp):
+        stamp = int(stamp)
+        x = stime.gmtime(stamp + 8 * 3600)
+        diff = timedelta(hours=x.tm_hour, minutes=x.tm_min, seconds=x.tm_sec)
+        today = stamp - diff.total_seconds()
+        return int(today)
+
+    def _days(self, root):
+        result = []
+        try:
+            for name, sub in root.items():
+                if isinstance(sub, h5py.Group):
+                    result.append(name)
+        except Exception as ex:
+            print(ex)
+        finally:
+            return result
+
+    def days(self):
+        try:
+            hfive = h5py.File(self._file_name, 'r')
+            root = hfive.require_group('/')
+            days = self._days(root)
+            hfive.close()
+            return days
+        except Exception as ex:
+            print(ex)
+            return []
+
+    def paths(self,time_stamp):
+        try:
+            day_stamp = self.day_stamp(time_stamp)
+            hfive = h5py.File(self._file_name, 'r')
+            group = hfive.require_group(f'/{day_stamp}')
+            paths = self.dir(group)
+            hfive.close()
+            return paths
+        except Exception as ex:
+            print(ex)
+            return []
+
+    def dir(self, group):
+        result = []
+        for name, sub in group.items():
+            if isinstance(sub, h5py.Group):
+                result.extend(self.dir(sub))
+            else:
+                result.append(sub.name)
+        return result
+
+    def draw_plot(self, start_time, interval=300, **kwargs):
+        logger = logging.getLogger('app')
+        hfive = h5py.File(self._file_name, 'r')
+        try:
+            filer_text, paths = self.datasets(hfive, start_time, **kwargs)
+            day_stamp = self.day_stamp(start_time)
+            start_pos = start_time - day_stamp
+
+            cur_day = self.day_stamp(stime.time())
+            if day_stamp == cur_day:
+                end_pos = int(stime.time()) - day_stamp
+            else:
+                end_pos = -1
+
+            fig = Figure(figsize=(16, 9))
+            ax = fig.subplots()
+
+            predata = np.zeros((5, 86400))
+            x = np.arange(0, 86400, interval)
+            for path, data in self.read_data(hfive, paths):
+                data = np.array(data)
+                predata = predata + data
+                self._draw_plot(ax, x, day_stamp, start_pos,end_pos, data, interval, path)
+                logger.info("path=%s", path)
+
+            self._draw_plot(ax, x, day_stamp, start_pos,end_pos, predata, interval, filer_text)
+
+            ax.legend()
+            ax.grid()
+            ax.set_title('success ratio')
+            ax.set(xlabel='time', ylabel='ratio')
+            fig.autofmt_xdate()
+
+            buf = BytesIO()
+            fig.savefig(buf, format="png")
+            return buf
+        except Exception as ex:
+            print(ex)
+        finally:
+            hfive.close()
+
+    def read_data(self, hfive, paths):
+        for path in paths:
+            yield path, hfive[path]
+
+
+
+    def datasets(self, hfive, start_time, **kwargs):
+        logger = logging.getLogger('app')
+
+        day_stamp = self.day_stamp(start_time)
+        sday = f'{day_stamp}'
+        root = hfive.require_group('/')
+        days = self._days(root)
+        if sday not in days:
+            return False
+
+        group = hfive.require_group(sday)
+        dsets = self.dir(group)
+
+        chname = quality = card_type = amount = None
+        for key, val in kwargs.items():
+            if val is None:
+                continue
+
+            if key == 'chname':
+                chname = val
+            elif key == 'quality':
+                quality = f'{val}'
+            elif key == 'card_type':
+                card_type = f'{val}'
+            elif key == 'amount':
+                amount = f'{val}'
+            else:
+                continue
+        return self._filter(dsets, chname=chname, quality=quality, card_type=card_type, amount=amount)
+
+    def _filter(self, dsets, chname=None, quality=None, card_type=None, amount=None):
+        filer_text = ''
+        if chname is not None:
+            filer_text = chname
+        if quality is not None:
+            filer_text = filer_text + f"-qua:{quality}"
+        if card_type is not None:
+            filer_text = filer_text + f"-type:{card_type}"
+        if amount is not None:
+            filer_text = filer_text + f"-amount:{amount}"
+
+        paths = []
+        for text in dsets:
+            items = re.split(r'/', text)
+            if len(items) != 6:
+                return False
+            (_, _sday, _chname, _quality, _card_type, _amount) = items
+            if (chname is not None) and (_chname != chname):
+                continue
+            if (quality is not None) and (_quality != quality):
+                continue
+            if (card_type is not None) and (_card_type != card_type):
+                continue
+            if (amount is not None) and (_amount != amount):
+                continue
+            paths.append(text)
+
+        return filer_text, paths
+
+    def _draw_plot(self, ax, x, day_stamp, start_pos,end_pos, data, interval=300, path=''):
+        import matplotlib.dates as mdate
+        # 'commit-succ': 0, 'commit-fail': 1, 'notify-succ': 2, 'notify-fail': 3, 'user_succ': 4
+
+        all = data[2] + data[3]
+        all = all.reshape((-1, interval))
+        all = np.sum(all, axis=1)
+
+        ySucc = data[2]
+        ySucc = ySucc.reshape((-1, interval))
+        ySucc = np.sum(ySucc, axis=1)
+        ySucc = ySucc / (all + 0.00000001)
+
+        if end_pos == -1:
+            pos = np.where(x >= start_pos)
+            x = x[pos]
+            ySucc = ySucc[pos]
+        else:
+            pos = np.where(start_pos <= x)
+            x = x[pos]
+            ySucc = ySucc[pos]
+            pos = np.where(x < end_pos)
+            x = x[pos]
+            ySucc = ySucc[pos]
+
+        xs = np.array([stime.strftime('%H:%M', stime.localtime(d + day_stamp)) for d in x])
+        ax.yaxis.set_major_formatter(ticker.PercentFormatter(xmax=1, decimals=0))
+        ax.plot(xs, ySucc, ls='--', marker='o', label=path)
+
+dataCenter = DataCenter()

+ 9 - 0
plot/Singleton.py

@@ -0,0 +1,9 @@
+def Singleton(cls):
+    _instance = {}
+
+    def _singleton(*args, **kargs):
+        if cls not in _instance:
+            _instance[cls] = cls(*args, **kargs)
+        return _instance[cls]
+
+    return _singleton

+ 96 - 0
plot/app.py

@@ -0,0 +1,96 @@
+import os
+
+from gevent import monkey
+from gevent.pywsgi import WSGIServer
+from gevent import signal as geventsig
+import gevent
+from flask import Flask
+import base64
+from io import BytesIO
+from matplotlib.figure import Figure
+import json
+from DataCenter import dataCenter
+# from plog import initLog
+from flask import request, jsonify
+import logging
+from logging.handlers import RotatingFileHandler
+
+import time
+import signal as sig
+
+app = Flask(__name__)
+app.debug = True
+
+curname = __name__
+
+
+@app.route('/plot/index')
+def index():
+    time_stamp = request.args.get('time_stamp')
+    interval = request.args.get('interval')
+    chname = request.args.get('chname')
+    quality = request.args.get('quality')
+    card_type = request.args.get('card_type')
+    amount = request.args.get('amount')
+
+    app.logger.info('time_stamp=%s interval= %s chname=%s quality=%s card_type=%s amount=%s',
+                    time_stamp, interval, chname, quality, card_type, amount)
+
+    if time_stamp is None:
+        time_stamp = time.time()
+    else:
+        time_stamp = int(time_stamp)
+
+    if interval is None:
+        interval = 300
+    else:
+        interval = int(interval)
+
+    # buf = dataCenter.draw_plot(1618243200, chname=chname)
+    # , quality=quality, card_type=card_type, interval=interval,
+    #                        amount=amount)1618502478
+    buf = dataCenter.draw_plot(time_stamp, interval=interval, chname=chname, quality=quality, card_type=card_type,
+                               amount=amount)
+    data = base64.b64encode(buf.getbuffer()).decode("ascii")
+    return f"<img src='data:image/png;base64,{data}'/>"
+
+
+@app.route('/plot/days')
+def days():
+    datas = dataCenter.days()
+    return jsonify(datas)
+
+
+@app.route('/plot/paths')
+def paths():
+    time_stamp = request.args.get('time_stamp')
+    time_stamp = int(time_stamp)
+    paths = dataCenter.paths(time_stamp)
+    return jsonify(paths)
+
+
+if __name__ == "__main__":
+    handler = logging.FileHandler(filename='/var/www/html/data/log/plot.log')
+    handler.setLevel(logging.DEBUG)
+    logging_format = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s',
+                                       datefmt='%Y-%m-%d %H:%M:%S')
+    handler.setFormatter(logging_format)
+    app.logger.addHandler(handler)
+
+    logger = logging.getLogger('app')
+    logger.info('app')
+
+    monkey.patch_all()
+    http_server = WSGIServer(('0.0.0.0', 5000), app)
+
+
+    def shutdown():
+        print('Shutting down ...')
+        http_server.stop()
+        exit(sig.SIGTERM)
+
+
+    geventsig.signal(sig.SIGTERM, lambda: http_server.stop())
+    geventsig.signal(sig.SIGINT, lambda: http_server.stop())
+
+    http_server.serve_forever()

+ 11 - 0
plot/plog.py

@@ -0,0 +1,11 @@
+import logging
+
+
+def initLog():
+    logging.basicConfig(filename='/var/www/html/data/log/plot.log', level=logging.INFO,
+                        format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S')
+
+
+if __name__ == "__main__":
+    logger = initLog()
+    logging.info('start')

+ 11 - 0
plot/pywsgi.py

@@ -0,0 +1,11 @@
+import os
+
+from gevent import monkey
+from gevent.pywsgi import WSGIServer
+
+from app import app
+
+monkey.patch_all()
+
+http_server = WSGIServer(('0.0.0.0', int(os.environ['PORT_APP'])), app)
+http_server.serve_forever()

+ 6 - 0
plot/reader.py

@@ -0,0 +1,6 @@
+from DataCenter import dataCenter
+import signal as sig
+
+if __name__ == '__main__':
+    sig.signal(sig.SIGINT, lambda: dataCenter.stop())
+    dataCenter.prepare_data()

+ 107 - 0
plot/thdf5.py

@@ -0,0 +1,107 @@
+import unittest
+import redis
+import h5py
+import time
+from datetime import datetime
+from datetime import timedelta
+import re
+import threading
+import numpy as np
+from DataCenter import dataCenter
+from matplotlib.figure import Figure
+from PIL import Image
+from io import BytesIO
+from PIL import Image
+import json
+
+
+class DataTest(unittest.TestCase):
+    def test_parase(self):
+        try:
+            dataCenter.parase('succ-lingzh-1-4-50-1618184676', '1')
+        except Exception as ex:
+            print(ex)
+
+    # docker-compose up pythoncli python -m unittest thdf5.DataTest.test_predata
+    def test_predata(self):
+        try:
+            dataCenter.prepare_data()
+        except Exception as ex:
+            print(ex)
+
+    def test_connect(self):
+        pool = redis.ConnectionPool(host='121.89.223.81', port=57649, db=0)
+        r = redis.Redis(connection_pool=pool)
+        for item in r.hscan_iter('nc_channel_monitor_commit'):
+            key = item[0]
+            val = item[1]
+            print(str(key, encoding="utf-8"), str(val, encoding="utf-8"))
+
+    def test_regex(self):
+        text = 'succm-lingzh-1-4-30-1618291260'
+        result = re.split(r'-', text)
+        pass
+
+    def day(self, time):
+        pass
+
+    def test_today(self):
+        stamp = 1617908681
+        stamp = int(stamp)
+        x = time.gmtime(stamp + 8 * 3600)
+        diff = timedelta(hours=x.tm_hour, minutes=x.tm_min, seconds=x.tm_sec)
+        today = stamp - diff.total_seconds()
+        y = stamp - today
+        pass
+
+    def test_days(self):
+        days = dataCenter.days()
+        result = json.dumps(days)
+        print(days)
+
+    def test_data(self):
+        buf = dataCenter.draw_plot(1619020800, chname='lingzh')
+        img = Image.open(buf)
+        img.show()
+
+    def dir(self, group):
+        result = []
+        for name, sub in group.items():
+            if isinstance(sub, h5py.Group):
+                result.extend(self.dir(sub))
+            else:
+                print(sub.name)
+                result.append(sub.name)
+
+        return result
+
+    def test_h5pyr(self):
+        try:
+            file_name = '/var/www/html/data/stdata/data.hdf5'
+            f = h5py.File(file_name, 'r')
+            root = f.require_group('/')
+            result = self.dir(group=root)
+            f.close()
+        except Exception as ex:
+            print(ex)
+
+    def test_fig(self):
+        buf = dataCenter.draw()
+        img = Image.open(buf)
+        img.show()
+
+    def test_numpy(self):
+        x = np.arange(0, 86400)
+        y = x.reshape((-1, 300))
+        y = np.sum(y, axis=1)
+
+        pos = np.where(x >= 25890)
+        x = x[pos]
+        pos = np.where(x < 85400)
+        x = x[pos]
+
+        print(x)
+
+
+if __name__ == '__main__':
+    unittest.main()

+ 0 - 2
test/TestRedis.php

@@ -200,8 +200,6 @@ class TestRedis extends TestCase
 
         $x = 'http://www.sina.com.cn';
         $y = urlencode($x);
-
-
     }
 
     public function testMillsec()

+ 8 - 0
test/TestTime.php

@@ -140,6 +140,14 @@ class TestTime extends TestCase
         }
     }
 
+    public function testZero()
+    {
+        $x = time();
+        $date = date('Y-m-d H:i:s',1618243200);
+        $day_start = strtotime("{$date}");
+
+    }
+
     public function testDate()
     {
         $date = date('Y-m-d',time());