Преглед изворни кода

IP:移植高配数据存储管理,以及解决获取从机数据失败bug!

liyi пре 2 година
родитељ
комит
848e524c77
8 измењених фајлова са 339 додато и 28 уклоњено
  1. 22 0
      ip/.vscode/launch.json
  2. 51 0
      ip/.vscode/settings.json
  3. 26 0
      ip/.vscode/tasks.json
  4. 19 10
      ip/src/cascade.c
  5. 105 17
      ip/src/sqlite_handle.c
  6. 2 0
      ip/src/sqlite_handle.h
  7. 113 0
      ip/src/sys.c
  8. 1 1
      ip/src/thread.h

+ 22 - 0
ip/.vscode/launch.json

@@ -0,0 +1,22 @@
+{
+    // Use IntelliSense to learn about possible attributes.
+    // Hover to view descriptions of existing attributes.
+    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+    "version": "0.2.0",
+    "configurations": [
+        {
+            "name": "(gdb) Launch",
+            "type": "cppdbg",
+            "request": "launch",
+            "program": "${workspaceFolder}/build/smartPDU",
+            "args": [],
+            "stopAtEntry": false,
+            "cwd": "${fileDirname}",
+            "environment": [],
+            "externalConsole": false,
+            "MIMode": "gdb",
+            "miDebuggerPath": "/home/liyi/tina/prebuilt/gcc/linux-x86/arm/toolchain-sunxi-arm9-musl/toolchain/bin/arm-openwrt-linux-muslgnueabi-gdb",
+            "miDebuggerServerAddress": "192.168.1.132:1234"
+        }
+    ]
+}

+ 51 - 0
ip/.vscode/settings.json

@@ -0,0 +1,51 @@
+{
+    "files.associations": {
+        "sqlite_handle.h": "c",
+        "json_handle.h": "c",
+        "cjson.h": "c",
+        "common.h": "c",
+        "cmath": "c",
+        "shell.h": "c",
+        "string.h": "c",
+        "list.h": "c",
+        "stdbool.h": "c",
+        "modbus_handle.h": "c",
+        "stdio.h": "c",
+        "switch_ctrl.h": "c",
+        "typeinfo": "c",
+        "list": "c",
+        "sensor_handle.h": "c",
+        "array": "c",
+        "istream": "c",
+        "ostream": "c",
+        "tuple": "c",
+        "type_traits": "c",
+        "utility": "c",
+        "stat.h": "c",
+        "unistd.h": "c",
+        "types.h": "c",
+        "fcntl.h": "c",
+        "pthread.h": "c",
+        "websocket_handle.h": "c",
+        "xutility": "c",
+        "system_error": "c",
+        "appweb.h": "c",
+        "string_view": "c",
+        "initializer_list": "c",
+        "stdlib.h": "c",
+        "pdumib_scalar.h": "c",
+        "elog.h": "c",
+        "language_hashmap.h": "c",
+        "paras.h": "c",
+        "cascade.h": "c",
+        "cascade_master.h": "c",
+        "bio.h": "c",
+        "ssl.h": "c",
+        "opensslconf.h": "c",
+        "x509.h": "c",
+        "cfg.h": "c",
+        "ioctl.h": "c",
+        "hlw8110_handle.h": "c"
+    },
+    "C_Cpp.errorSquiggles": "disabled"
+}

+ 26 - 0
ip/.vscode/tasks.json

@@ -0,0 +1,26 @@
+{
+    // See https://go.microsoft.com/fwlink/?LinkId=733558
+    // for the documentation about the tasks.json format
+    "version": "2.0.0",
+    "tasks": [
+        {
+            "label": "build",
+            "type": "shell",
+            "command": "msbuild",
+            "args": [
+                // Ask msbuild to generate full paths for file names.
+                "/property:GenerateFullPaths=true",
+                "/t:build",
+                // Do not generate summary otherwise it leads to duplicate errors in Problems panel
+                "/consoleloggerparameters:NoSummary"
+            ],
+            "group": "build",
+            "presentation": {
+                // Reveal the output only if unrecognized errors occur.
+                "reveal": "silent"
+            },
+            // Use the standard MS compiler pattern to detect errors, warnings and infos
+            "problemMatcher": "$msCompile"
+        }
+    ]
+}

+ 19 - 10
ip/src/cascade.c

@@ -461,7 +461,7 @@ static int slave_save(cascade_handle_t *cas)
 static int mb_init(cascade_handle_t *cas, char *path, int type, int addr, uint32_t baud)
 {
     int r;
-    r = g_modbus_init(&cas->m, path, baud, type, addr, (type>0)?"master":"slave", 1);
+    r = g_modbus_init(&cas->m, path, baud, type, addr, (type>0)?"slave":"master", 1);
     if(r==0) {
         if(type>0) {
             LOGD("___ set slave addr: %d\n", addr);
@@ -620,7 +620,7 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
         return -1;
     }
     //LOGD("___ mb_read dlen: %d\n", d->dlen);
-
+    //LOGD("______cas->info.cnt4: %d\n", cas->sInfo.cnt);
     while(1) {
         if(rlen+oncelen>d->dlen) {
             xlen = d->dlen-rlen;
@@ -631,6 +631,7 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
         xlen += xlen%2;
 
         r = _mb_read(cas, addr, CASCADE_REG_READ, buff, xlen/2);
+        //LOGD("______cas->info.cnt5: %d\n", cas->sInfo.cnt);
         if(r<0) {
             LOGE("___ _mb_read failed, %s, rlen: %d\n", modbus_strerror(errno), rlen);
             return -1;
@@ -650,7 +651,7 @@ static int mb_read(cascade_handle_t *cas, int addr, data_t *d)
             break;
         }
     }
-    
+   //LOGD("______cas->info.cnt6: %d\n", cas->sInfo.cnt);
     return 0;
 }
 static int mb_write(cascade_handle_t *cas, int addr, data_t *d)
@@ -697,6 +698,7 @@ static int mb_write_read(cascade_handle_t *cas, int addr, data_t *wd, data_t *rd
     int r=0;
     
     r = mb_write(cas, addr, wd);
+    //LOGD("______cas->info.cnt3: %d\n", cas->sInfo.cnt);
     if(r==0) {
         r = mb_read(cas, addr, rd);
     }
@@ -777,22 +779,22 @@ static int mb_receive(cascade_handle_t *cas)
                 break;
                 case CASCADE_CMD_BREAKER_SAVE_ADD:
                 {
-                    LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_ADD\n");
-                    LOGD("%d %d %s %s %s\n",cmd->datas.data.jdh,cmd->datas.data.cjdz,cmd->datas.data.cjfs,cmd->datas.data.com,cmd->datas.data.breaker_chns);
+                    //LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_ADD\n");
+                    //LOGD("%d %d %s %s %s\n",cmd->datas.data.jdh,cmd->datas.data.cjdz,cmd->datas.data.cjfs,cmd->datas.data.com,cmd->datas.data.breaker_chns);
                     //slave_breaker_add(&cmd->datas.data);
 
                 }
                 break;
                 case CASCADE_CMD_BREAKER_SAVE_UPDATE:
                 {
-                    LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_UPDATE\n");
-                    LOGD("%d %s %s\n",cmd->datas.data1.switch_id,cmd->datas.data1.switch_name,cmd->datas.data1.breaker_chns);
+                    //LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_UPDATE\n");
+                    //LOGD("%d %s %s\n",cmd->datas.data1.switch_id,cmd->datas.data1.switch_name,cmd->datas.data1.breaker_chns);
                     //slave_breaker_update(&cmd->datas.data1);
                 }
                 break;
                 case CASCADE_CMD_BREAKER_SAVE_DELETE:
                 {
-                    LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_DELETE\n");
+                    //LOGD("_____ slave CASCADE_CMD_BREAKER_SAVE_DELETE\n");
                    // slave_breaker_delete(&cmd->datas.data2);
                 }
             }
@@ -1358,10 +1360,12 @@ static int master_cmd(cascade_handle_t *cas, cmd_data_t *cmd)
             LOGD("_____ master send CASCADE_CMD_GET_INFO\n");
             r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata);
             if(r==0) {
-                LOGD("______cas->info.cnt: %d\n", cas->sInfo.cnt);
+               // LOGD("______cas->info.cnt: %d\n", cas->sInfo.cnt);
                 rdata.dlen = sizeof(slave_info_t)-sizeof(channel_info_t)*(CH_MAX-cas->sInfo.cnt);
                 rdata.data = (uint8_t*)&cas->sInfo;
+                //LOGD("______cas->info.cnt1: %d\n", cas->sInfo.cnt);
                 r = mb_write_read(cas, cur_dev_addr, &wdata, &rdata);
+                //LOGD("______cas->info.cnt2: %d\n", cas->sInfo.cnt);
                 if(r==0) {
                     power_add(cas);
                 }
@@ -1429,6 +1433,8 @@ static int master_query(cascade_handle_t *cas)
         case CASCADE_CMD_QUERY_CH:
         {
             //LOGD("__00__ master query CASCADE_CMD_QUERY_CH, cnt: %d\n", cas->sInfo.cnt);
+            if(cas->scanner_flag == 1)
+                return -1;
             if(cas->sInfo.cnt==0) {
                 return -1;
             }
@@ -1446,6 +1452,7 @@ static int master_query(cascade_handle_t *cas)
             }
             //LOGD("__11__ master query CASCADE_CMD_QUERY_CH, cnt: %d\n", cas->sInfo.cnt);
         }
+        
         break;
         case CASCADE_CMD_BREAKER_QUERY:
         {
@@ -1638,7 +1645,7 @@ static void* scan_thread(void *arg)
         if(info->product_modbus_type==0) {  //master
             cascade_lock();
             //r = new_master_scaner(cas);
-                master_scan(cas);
+            master_scan(cas);
             cascade_unlock();
         }
         sleep(1);
@@ -1900,7 +1907,9 @@ int cascade_request(cmd_data_t *cmd)
     }
 
     pthread_mutex_lock(&cas->lock);
+    cas->scanner_flag = 1;
     r = master_cmd(cas, cmd);
+    cas->scanner_flag = 0;
     pthread_mutex_unlock(&cas->lock);
 
     return r;

+ 105 - 17
ip/src/sqlite_handle.c

@@ -11,6 +11,11 @@
 #define	TOTAL_COUNT	60//统计总数
 
 
+enum{
+    DB_MIN=0,
+    DB_MAX,
+};
+
 typedef struct {
     sqlite3             *db;
     pthread_mutex_t     mutex;
@@ -19,6 +24,8 @@ static sql_handle_t sqlHandle={0};
 
 
 
+static int overwrite_flag=0;
+
 static int get_count(sqlite3 *db, char *table)
 {
     int r;
@@ -41,6 +48,34 @@ static int get_count(sqlite3 *db, char *table)
     return count;
 }
 
+static int get_key(sqlite3 *db, char *table, char *key, int mm)
+{
+    int r,id=-1;
+    char temp[1024];
+    sqlite3_stmt *stmt=NULL;
+
+    if(mm==DB_MIN) {
+        sprintf(temp, "SELECT MIN(%s) FROM %s;", key, table);
+    }
+    else {
+        sprintf(temp, "SELECT MAX(%s) FROM %s;", key, table);
+    }
+
+    r = sqlite3_prepare_v2(db, temp, -1, &stmt, 0);
+    if (r != SQLITE_OK) {
+        log_e("___get_extr_key, sqlite3_prepare_v2 failed, %s\n", sqlite3_errmsg(db));
+        return -1;
+    }
+    
+    while (sqlite3_step(stmt) == SQLITE_ROW) {
+        id = sqlite3_column_int(stmt, 0);
+        break;
+    }
+    sqlite3_finalize(stmt);
+
+    return id;
+}
+
 
 
 /// @brief 初始化SQLite数据库
@@ -332,19 +367,44 @@ int dev_insert_power_info(sqlite3 *db,GlobalPowerInfo* _globalPowerChnInfo,int*
     int ncolumn = 0;            //每条记录包含的字段数据
     char** pResult = NULL;  //用来指向sql执行结果的指针
     char* err_msg=NULL;
+    char *table="Table_PowerInfo";
+    GlobalPowerInfo *pInfo=_globalPowerChnInfo;
+
+    if(overwrite_flag) {
+        sprintf(select_sql,"UPDATE %s SET product_Index=%d,product_id=%d,product_ch_id=%d,product_ch_status=%d,"
+                                          "product_ch_voltage=%.2f,product_ch_current=%.2f,product_ch_power=%.2f,product_ch_power_freq=%.2f,"
+                                          "product_ch_consumption=%.2f,product_ch_power_factor=%.2f,product_samp_time='%s' "
+                                          "WHERE product_Index=(SELECT MIN(product_Index) FROM %s);",
+                            table,
+                            *nIndex,
+                            pInfo->product_id,
+                            pInfo->product_ch_id,
+                            pInfo->product_status,
+                            pInfo->_power_info.voltage,
+                            pInfo->_power_info.current,
+                            pInfo->_power_info.power,
+                            pInfo->_power_info.freq,
+                            pInfo->_power_info.consumption,
+                            pInfo->_power_info.factor,
+                            pInfo->samp_time,
+                            table
+                            );
+        printf("power update!!!!\n");
+    }else {
     
-    sprintf(select_sql,"INSERT INTO Table_PowerInfo VALUES ('%s',%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%d);",
-                        _globalPowerChnInfo->samp_time,
-                        _globalPowerChnInfo->product_id,
-                        _globalPowerChnInfo->product_ch_id,
-                        _globalPowerChnInfo->product_status,
-                        _globalPowerChnInfo->_power_info.voltage,
-                        _globalPowerChnInfo->_power_info.current,
-                        _globalPowerChnInfo->_power_info.power,
-                        _globalPowerChnInfo->_power_info.freq,
-                        _globalPowerChnInfo->_power_info.consumption,
-                        _globalPowerChnInfo->_power_info.factor,
-                        *nIndex);
+        sprintf(select_sql,"INSERT INTO Table_PowerInfo VALUES ('%s',%d,%d,%d,%.2f,%.2f,%.2f,%.2f,%.2f,%.2f,%d);",
+                            _globalPowerChnInfo->samp_time,
+                            _globalPowerChnInfo->product_id,
+                            _globalPowerChnInfo->product_ch_id,
+                            _globalPowerChnInfo->product_status,
+                            _globalPowerChnInfo->_power_info.voltage,
+                            _globalPowerChnInfo->_power_info.current,
+                            _globalPowerChnInfo->_power_info.power,
+                            _globalPowerChnInfo->_power_info.freq,
+                            _globalPowerChnInfo->_power_info.consumption,
+                            _globalPowerChnInfo->_power_info.factor,
+                            *nIndex);
+    }
     (*nIndex)+=1;    
     // if(_globalPowerChnInfo->product_ch_id==0)
     //log_d(select_sql);
@@ -2505,12 +2565,32 @@ int dev_insert_alarm_info(sqlite3* db,int product_id,int alarm_type,char* date_t
     char** pResult = NULL;  //用来指向sql执行结果的指针
     char* err_msg=NULL;
     char select_sql[1024] = {0};
+    char *table="Table_AlarmManage";
+    if(overwrite_flag) {
+        int alarmNumber=get_key(db, table, "alarmNumber", DB_MAX);
+        if(alarmNumber<0) {
+            return -1;
+        }
+        alarmNumber++;
 
-    sprintf(select_sql,"INSERT INTO Table_AlarmManage (alarmDate,alarmType,product_id,alarmContent) VALUES ('%s',%d,%d,'%s');",
-        date_time,
-        alarm_type,
-        product_id,
-        alarm_content);
+        sprintf(select_sql,"UPDATE %s SET alarmNumber=%d,alarmDate='%s',alarmType=%d,product_id=%d,alarmContent='%s' "
+                                          "WHERE alarmNumber=(SELECT MIN(alarmNumber) FROM %s);",
+                table,
+                alarmNumber,
+                date_time,
+                alarm_type,
+                product_id,
+                alarm_content,
+                table);
+        printf("alarm  update!!\n");
+    }else{
+
+        sprintf(select_sql,"INSERT INTO Table_AlarmManage (alarmDate,alarmType,product_id,alarmContent) VALUES ('%s',%d,%d,'%s');",
+            date_time,
+            alarm_type,
+            product_id,
+            alarm_content);
+    }
     res = sqlite_SQL_RUN(db, select_sql, &pResult, &nrow, &ncolumn, &err_msg);
     if(res != SQLITE_OK) {
         log_e("sqlite handle error: %s\n%s\n", err_msg,select_sql); sqlite3_free(err_msg);
@@ -4304,3 +4384,11 @@ int dev_sql_VACCUM(sqlite3 *db)
     return 0;
 }
 
+
+
+int dev_sql_set_overwrite(int flag)
+{
+    overwrite_flag = flag;
+    return 0;
+}
+

+ 2 - 0
ip/src/sqlite_handle.h

@@ -154,4 +154,6 @@ int dev_mqtt_update(sqlite3 *db, mqtt_server_t *ser);
 
 int dev_sql_VACCUM(sqlite3 *db);
 
+int dev_sql_set_overwrite(int flag);
+
 #endif

+ 113 - 0
ip/src/sys.c

@@ -16,6 +16,9 @@
 #include "common.h"
 #include "sqlite_handle.h"
 
+//#include <sys/sysinfo.h>
+#include <sys/statvfs.h>
+
 #if 0
 #define LOGE  log_e
 #define LOGW  log_w
@@ -1020,6 +1023,115 @@ quit:
     pthread_exit(NULL);
 }
 
+int sys_get_disk_ava_MB(char *path)
+{
+    int r;
+    struct statvfs st;
+
+    r = statvfs(path, &st);
+    if(r) {
+        return -1;
+    }
+
+    int avaMB = (st.f_frsize*st.f_bavail)/(1024*1024);
+    //int freeMB = (st.f_frsize*st.f_bfree)/(1024*1024);
+    //printf("____ava: %dMB, free %dMB\n", avaMB, freeMB);
+	LOGD("___ RomAvailable rom: %dMB\n", avaMB);
+
+    return avaMB;
+}
+
+
+int sys_get_mem_ava_MB(void)
+{
+    int r;
+    long v1=0,v2=0;
+    char buf[32];
+    struct sysinfo info;
+
+#if 0
+    r = sysinfo(&info);
+    if(r) {
+        return -1;
+    }
+    value = (info.freeram*info.mem_unit)/(1014*1024);
+#else
+
+    FILE *fp = fopen("/proc/meminfo", "r");
+    if(!fp) {
+        return -1;
+    }
+
+    fscanf(fp, "MemTotal: %s kB\n", buf);
+    
+    fscanf(fp, "MemFree: %s kB\n", buf);
+    v1 = atol(buf);
+    
+    fscanf(fp, "MemAvailable: %s kB\n", buf);
+    v2 = atol(buf);
+    
+    fclose(fp);
+    LOGD("___MemFree: %ldkB, MemAvailable: %ldkB\n", v1, v2);
+    
+    v2 /= 1024;
+#endif
+
+    return v2;
+}
+
+
+#ifdef RAM_DEBUG
+    #define RAM_THRD        50
+    #define RAM_PERIOD      1
+#else
+    #define RAM_THRD        20
+    #define RAM_PERIOD      60
+#endif
+
+#ifdef ROM_DEBUG
+    #define ROM_THRD        50
+    #define ROM_PERIOD      1
+#else
+    #define ROM_THRD        30
+    #define ROM_PERIOD      1
+#endif
+static void mem_check(void)
+{
+    int avaMB,flag=0;
+    static uint32_t mem_cnt=0;
+
+    mem_cnt++;
+    if(mem_cnt%RAM_PERIOD==0) {
+        avaMB = sys_get_mem_ava_MB();
+        if(avaMB<RAM_THRD) {
+            LOGE("___ free mem less than %dMB, reboot now ...\n", RAM_THRD);
+            sys_reboot();
+        }
+    }
+
+    if(mem_cnt%ROM_PERIOD==0) {
+        avaMB = sys_get_disk_ava_MB("/mnt/UDISK/");
+        if(avaMB<ROM_THRD) {
+            flag = 1;
+            LOGE("___ free 2222 less than MB, reboot now ...\n");
+        }
+        dev_sql_set_overwrite(flag);
+    }
+}
+
+
+
+static void* polling_thread(void *arg)
+{
+    thread_handle_t *h=(thread_handle_t*)arg;
+
+    while(h->quit==0) {
+        mem_check();
+        sleep(1);
+    }
+    pthread_exit(NULL);
+}
+
 
 int sys_init(void)
 {
@@ -1029,6 +1141,7 @@ int sys_init(void)
     
     //thread_start(THREAD_ID_PLUG, plug_thread, NULL, 4*MB, 0);
 
+    thread_start(THREAD_ID_POLLING, polling_thread, NULL, 4*MB, 0);
     return 0;
 }
 

+ 1 - 1
ip/src/thread.h

@@ -20,7 +20,7 @@ enum {
     THREAD_ID_SNMP,
     THREAD_ID_POWER,
     THREAD_ID_SENSOR,
-    THREAD_ID_PLUG,
+    THREAD_ID_POLLING,
     THREAD_ID_CASCADE,
     THREAD_ID_SCAN,
     THREAD_ID_SHMW,