TT12-MCU/applications/getinfo.c
2023-06-19 15:56:45 +08:00

470 lines
13 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <board.h>
#include <rtthread.h>
//#include <../packages/webclient-v2.2.0/inc/webclient.h>
#include <webclient.h>
#define LOG_TAG "getinfo"
#define LOG_LVL LOG_LVL_INFO
#include <ulog.h>
//#define HTTP_GET_URL "http://www.rt-thread.com/service/rt-thread.txt"
#ifndef TT_IP
#define TT_IP "http://10.10.10.72:4005"
#endif
#define TT_SIM TT_IP "/action/webGetSIMState"//SIM
#define TT_XH TT_IP "/action/webGetTDSignal"//信号值
#define TT_RW TT_IP "/action/webGetTdState"//入网
#define TT_JH TT_IP "/action/webGetPSState"//激活
#define TT_DW TT_IP "/action/webGetBDGPS"//定位
//http://192.168.0.232:4005/action/webGetSIMState webGetBDGPS
#define MAX_LEN 15
#include <cJSON.h>
#include <finsh.h>
#include <usrcfg.h>
//#include <stdio.h>
//#include <stdlib.h> //用于strtod函数
//#include <string.h>
char *infoH[] = { TT_SIM, TT_XH, TT_RW, TT_JH, TT_DW};
typedef struct
{
char sim[MAX_LEN]; // SIM
char xh[MAX_LEN]; // SIM
char rw[MAX_LEN]; // SIM
char jh[MAX_LEN]; // SIM
char jd[MAX_LEN]; // SIM
char wd[MAX_LEN]; // SIM
char ele[MAX_LEN]; // SIM
// rt_uint8_t sim; // SIM
// rt_uint8_t xh; // 信号值
// rt_uint8_t rw; // 入网
// rt_uint8_t jh; // 激活
// char *jd; // 经度
// char *wd; // 纬度
// char *ele; // 高度
}TT;
TT tmp={.sim="-",.xh="-",.jh="-",.jd="-",.wd="-",.ele="-"};
//memset(&tmp,0x00,sizeof(TT));
TT *TTinfo=&tmp;
static rt_tick_t bootstamp=0;
//rt_memset(TTinfo,0,sizeof(TT));
//TT *TTinfo=RT_NULL;
//TTinfo = rt_malloc(sizeof(TT));
/**
* @description: 将TT结构体转换为数组
* @param {TT} *TTinfo TT结构体
* @param {rt_uint8_t} *buffer 存储转换结果
* @return {*} buffer大小
*/
rt_uint8_t info2HEX(TT *TTinfo, rt_uint8_t *buffer)
{
// 功能将tt数据转换为9字节HEX数据并返回存在data
// 第1节为高3位分别为sim、rw和jh其余位为xhxh值若大于31则为3131=b0001 1111
// 第2-5字节为经度。114.410050= 0xF2 0xD1 0xE4 0x42
// 第6-9字节为纬度。30.426840= 0x2B 0x6A 0xF3 0x41
// 第10字节为高度只保留整数。-31.5= 0x0A
rt_uint8_t tmp = (atoi(TTinfo->sim) << 7) + (atoi(TTinfo->rw) << 6) + (atoi(TTinfo->jh) << 5)
+ (atoi(TTinfo->xh) > 31 ? 31 : atoi(TTinfo->xh)); // 位操作
char *jd_c = &TTinfo->jd[2]; // 从第二位开始取,去除非数字字符
char *wd_c = &TTinfo->wd[2];
float jd_f = strtod(jd_c, NULL); // 字符转浮点
float wd_f = strtod(wd_c, NULL);
rt_int8_t ele_f = atoi(TTinfo->ele);
// printf("jd--%f\nwd--%f\nele-- %d \n", jd_f, wd_f, ele_f);
rt_uint8_t offset = 0;
memcpy(buffer + offset, &tmp, 1);
offset += 1;
memcpy(buffer + offset, &jd_f, sizeof(float));
offset += sizeof(float);
memcpy(buffer + offset, &wd_f, sizeof(float));
offset += sizeof(float);
memcpy(buffer + offset, &ele_f, sizeof(rt_int8_t));
offset += sizeof(rt_int8_t);
return offset;
}
static int minTTPeriCnt=5;
static int minTTsinal=3;
static int minActiveTime=0;
static int maxActiveTime=0;
//extern struct rt_event sw_check;//软件条件
extern void upTTflag(void);
extern void upTTflagtmp(void);//临时demo
static void updatecfg()
{
minTTsinal = get_cfg("minTTsinal");
minTTPeriCnt = get_cfg("minTTPeriCnt");
minActiveTime = get_val("minActiveTime");
maxActiveTime = get_val("maxActiveTime");
LOG_D("加载参数完成");
}
void initcfg()
{
updatecfg();
bootstamp = rt_tick_get_millisecond();
}
/**
* 更新统计信息
*/
static void updateSta()
{
uint16_t v = (rt_tick_get_millisecond()-bootstamp)/1000;//转换为秒
LOG_I("耗时%dS.",v);
if ((minActiveTime ==0) | (minActiveTime > v)) {
minActiveTime = v;
set_val("minActiveTime", v);
}
if (v>maxActiveTime) {
maxActiveTime=v;
set_val("maxActiveTime", v);
}
}
/**
* 按规则检查TT状态
*/
static void rulecheck(void)
{
//默认为 TT连续5个周期为激活状态且信号强度不低于5。
//满足加1不满足清零
static rt_uint16_t okCnt=0;
if (!okCnt) {
LOG_D("当前规则为:连续%d个采集周期TT信号质量不低于%d",minTTPeriCnt,minTTsinal);
}
int xh=atoi(TTinfo->xh);
if (xh == 99) {
xh=0;
}
if (atoi(TTinfo->jh) && !(xh < minTTsinal) ) {//
okCnt += 1;
LOG_D("第%d次符合规则。",okCnt);
}
else {
okCnt = 0;
LOG_W("不符合。");
return;
}
if (okCnt >= minTTPeriCnt) {
//TT具备发送条件
// rt_event_send(&sw_check, TT_IS_OK);
// upTTflag();
upTTflagtmp();
LOG_I("符合规则TT具备发送状态。");
// updateSta();
okCnt = minTTPeriCnt -1;
}
// if (okCnt > minTTPeriCnt) {
// //TT具备发送条件
//// rt_event_send(&sw_check, TT_IS_OK);
// upTTflag();
// okCnt = 2;
// LOG_I("符合规则TT具备发送状态。");
//// updateSta();
// }
}
/* 数据解析 */
static void tt_parse(rt_uint8_t *data)
{
extern TT *TTinfo;
cJSON *root = RT_NULL, *object = RT_NULL, *item = RT_NULL;
root = cJSON_Parse((const char *) data);
if (!root)
{
rt_kprintf("No memory for cJSON root!\n");
return;
}
object = cJSON_GetObjectItem(root, "data");
item = cJSON_GetObjectItem(object, "tdsignal");
if (item)
{
// TTinfo->xh = atoi(item->valuestring);
// tmp.xh = item->valuestring;
strcpy(TTinfo->xh,item->valuestring);
// rt_kprintf("\nxh:%s ", item->valuestring);
// rt_kprintf("\nxh:%s ", TTinfo->xh);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdnetregstate");
if (item)
{
// TTinfo->rw = atoi(item->valuestring);
// rt_kprintf("\nrw:%s ", TTinfo.rw);
strcpy(TTinfo->rw,item->valuestring);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdpsstate");
if (item)
{
// TTinfo->jh = atoi(item->valuestring);
// rt_kprintf("\njh:%s ", TTinfo.jh);
strcpy(TTinfo->jh,item->valuestring);
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "latitude");
if (item)
{
// TTinfo->wd = item->valuestring;
strcpy(TTinfo->wd,item->valuestring);
item = cJSON_GetObjectItem(object, "longitude");
// TTinfo->jd = item->valuestring;
strcpy(TTinfo->jd,item->valuestring);
item = cJSON_GetObjectItem(object, "elevation");
// TTinfo->ele = item->valuestring;
strcpy(TTinfo->ele,item->valuestring);
// rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", TTinfo->sim, TTinfo->xh, TTinfo->rw,
// TTinfo->jh, TTinfo->jd, TTinfo->wd,TTinfo->ele);
LOG_D("Get RAW data done.");
cJSON_Delete(root);
return RT_EOK;
}
item = cJSON_GetObjectItem(object, "tdsimstate");
if (item)
{
// TTinfo->sim = atoi(item->valuestring);
// tmp.sim = item->valuestring;
strcpy(TTinfo->sim,item->valuestring);
// rt_kprintf("\nSIM:%s \n", TTinfo->sim);
cJSON_Delete(root);
return RT_EOK;
}
if (root != RT_NULL)
cJSON_Delete(root);
}
/* HTTP client download data by GET request */
static int webclient_get_data(const char *url)
{
static unsigned char *buffer = RT_NULL;
size_t length = 0;
if (webclient_request(url, RT_NULL, RT_NULL, 0, (void **) &buffer, &length) < 0)
{
LOG_E("TT server is not ready.");
if (buffer)
{
web_free(buffer);
}
return -RT_ERROR;
}
LOG_D("webclient GET request response data :");
LOG_D("%s", buffer);
tt_parse(buffer);
if (buffer)
{
web_free(buffer);
}
return RT_EOK;
}
void getTTinfo_thread_entry(void* parameter)
{
// bootstamp = rt_tick_get();
CFG* cfg = RT_NULL;
cfg = (CFG*) parameter;
// TT TTinfo;
rt_uint8_t var = 0, isize = 0, i = 0;
isize = sizeof(infoH) / sizeof(infoH[0]);
rt_kprintf("\n%10s%s\n", " ", "↓---------getTT START.--------↓");
rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", "SIM", "xh", "rw", "jh", "N", "E", "ele");
for (i = 0; i < cfg->cnt; ++i) //按指定次数轮询
{
// for (var = 0; var < isize; var++) //轮询每个参数
// {
// static char *url = RT_NULL;
// url = web_strdup(*(infoH + var));
// if (url == RT_NULL)
// {
// LOG_E("no memory for create getTT url buffer.\n");
//// return -RT_ENOMEM;
// }
// if (webclient_get_data(url) != RT_EOK)
// {
// strcpy(TTinfo->sim,"-");
// strcpy(TTinfo->xh,"-");
// strcpy(TTinfo->jh,"-");
// strcpy(TTinfo->jd,"-");
// strcpy(TTinfo->wd,"-");
// strcpy(TTinfo->ele,"-");
// break;
// }
// web_free(url);
// rt_thread_mdelay(100);
// }
// rulecheck();
rt_kprintf("%5s%5s%5s%5s%15s%15s%10s\n", TTinfo->sim, TTinfo->xh, TTinfo->rw, TTinfo->jh, TTinfo->jd,
TTinfo->wd, TTinfo->ele);
if (i != cfg->cnt - 1) //最后一次采集不延时
{
rt_thread_mdelay(cfg->s * 1000);
}
}
rt_kprintf("%10s%s\n", " ", "↑---------getTT DONE.---------↑");
}
void getTT(int argc, char **argv)
{
// size_t cnt = 0, s=3;//次数、间隔
static CFG cfg;
memset(&cfg, 0, sizeof(CFG));
if (argc == 1)
{
cfg.cnt = 1;
cfg.s = 3;
}
else if (argc == 2)
{
cfg.cnt = atoi(argv[1]);
cfg.s = 3;
}
else if (argc == 3)
{
cfg.cnt = atoi(argv[1]);
cfg.s = atoi(argv[2]);
}
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("getTT", getTTinfo_thread_entry, (void *) &cfg, 1024 * 3, 25, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
// rt_kprintf("done");
}
else
{
LOG_E("thread 'getTT' create failure.");
return RT_ERROR;
}
}
/* 导出到自动初始化 */
MSH_CMD_EXPORT(getTT, "getTT 3 1" means try 3 times with 1 second interval.);
//MSH_CMD_EXPORT_ALIAS(webclient_get_data, gTTinfo, GET info of TT server.);
int isTTon(void)
{
return !rt_pin_read(TT_EN);
}
void repGetTT_thread_entry(void* parameter)
{
while(!isTTon())//第一次运行时未上电则等待
{}
while(isTTon())//中间未上电则退出
{
for (size_t var = 0; var < (sizeof(infoH) / sizeof(infoH[0])); var++) //轮询每个参数
{
static char *url = RT_NULL;
url = web_strdup(*(infoH + var));
if (url == RT_NULL)
{
LOG_E("no memory for create getTT url buffer.\n");
break;
// return -RT_ENOMEM;
}
if (webclient_get_data(url) != RT_EOK)
{
web_free(url);
strcpy(TTinfo->sim,"-");
strcpy(TTinfo->xh,"-");
strcpy(TTinfo->jh,"-");
strcpy(TTinfo->jd,"-");
strcpy(TTinfo->wd,"-");
strcpy(TTinfo->ele,"-");
break;
}
web_free(url);
// rt_thread_mdelay(100);
}
rulecheck();
rt_thread_mdelay(3 * 1000);//间隔3s更新一次数据
}
}
/**
* 持续更新TT状态信息数据3s刷新一次。TT断电后退出。
*/
void repGetTT(void)
{
/* 创建 serial 线程 */
rt_thread_t thread = rt_thread_create("repGetTT", repGetTT_thread_entry, RT_NULL, 1024 * 3, 27, 10);
/* 创建成功则启动线程 */
if (thread != RT_NULL)
{
rt_thread_startup(thread);
// rt_kprintf("done");
}
else
{
LOG_E("thread 'repGetTT' create failure.");
return RT_ERROR;
}
}
MSH_CMD_EXPORT(repGetTT,gett);
//由于
//
//static rt_timer_t timer1;
///* 定时器1超时函数 */
//static void timeout1(void *parameter)
//{
//
//// LOG_D("定时时间到,准备发送数据");
// if (isTTon()) {
// repGetTT();
// }
// else {
// rt_timer_stop(timer1);
// }
//// rt_event_send(&readyToSend, TIME_IS_UP);
//}
//void runTT()
//{
///* 创建定时器1 周期定时器 */
//timer1 = rt_timer_create("TTinfotimer", timeout1,
// RT_NULL, rt_tick_from_millisecond(3*1000),
// RT_TIMER_FLAG_PERIODIC);
//
///* 启动定时器1 */
//if (timer1 != RT_NULL && isTTon())
// rt_timer_start(timer1);
//}