Pebble AppMessage JS json/csv -> C

Я экспериментирую с Pebble SDK и хотел бы читать солнечные данные из Интернета. Мне удалось полностью создать приложение на JS. См. эту ссылку. введите здесь описание изображения

Поскольку я обнаружил некоторые ограничения в JS, я переписываю код на C. При получении json-данных через JS я отправляю это через словарь на C. Вы можете найти версию C здесь

Данные RAW, полученные из Интернета:

[ { HourNum: "0:0", HourPower: "0" }, { HourNum: "0:10", HourPower: "0" }, { HourNum: "0:20", HourPower: "0" } и т. д.

Данные "HourPower" отфильтрованы и отправлены на C с помощью опции Dictionary:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,72,89,110,127,160,192,253,316,352,360,522,539,601,598,770,582,650,810,741,805,894,908,864,904,962,1016,1106,1853,1503,1311,1406,1444,1401,1409,1344,1622,1472,1382,1609,1766,3310,3093,2041,1496,2068,3302,3185,1358,2760,2715,1285,994,1086,832,871,813,1707,1218,1218,239,203,170,132,70,53,45,39,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

Две задачи:

  • 1 Интересно, получил ли я все 144 заявки.

В журнале я вижу только:

Получено buffer_solarvalue: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0, ‹-останавливается здесь

Ограничены ли данные между JS и C? Нужно ли мне разбивать данные на несколько частей перед их отправкой из JS в C?

  • 2 Я не знаю, как обрабатывать данные, полученные в C. ** Я читал и пробовал несколько возможностей, пытаясь прочитать нативный json и теперь пытаюсь прочитать его через csv, но как?

Конечная цель — прочитать эти значения из Интернета и создать график. Но сначала мне нужно правильно прочитать значения в C.

Я прав, я должен пойти по пути csv? У кого-нибудь есть опыт работы с «большим» набором данных между JS и C?


person Gaston    schedule 09.10.2015    source источник


Ответы (2)


Я не мог использовать strtok в CloudPebble, поэтому я написал эту функцию для перемещения указателя на следующее число.

void skip_over_char(char **buffer, const char lookup) {
  while(((*buffer)[0] != lookup) && ((*buffer)[0] != '\0')) {
    (*buffer)++;
  }
  (*buffer)++; //skip over lookup character
}

Затем вы можете добавить значения в массив solar_values ​​таким образом. В результате вы можете видеть, что вы действительно получаете все 144 записи.

static int solar_values[144];
static int index;
static int received;
char *pch;

case KEY_SOLARVALUE :
  received = snprintf(buffer_solarvalue, sizeof(buffer_solarvalue), "%s", t->value->cstring);
  APP_LOG(APP_LOG_LEVEL_INFO , "Received buffer_solarvalue: %s", buffer_solarvalue);
  pch = buffer_solarvalue;
  skip_over_char(&pch, '[');
  index = 0;
  while (pch - buffer_solarvalue < received) {
    solar_values[index++] = atoi(pch);
    APP_LOG(APP_LOG_LEVEL_INFO, "solar_values[%3d] = %d", index - 1, solar_values[index-1]);
    skip_over_char(&pch, ',');
  }
  APP_LOG(APP_LOG_LEVEL_INFO , "Received %d values", index);
  break;  
person jayant    schedule 10.10.2015
comment
Спасибо вам обоим за то, что указали мне то, что кажется логичным направлением. Я также проверил, сколько статей может содержать одна словарная статья. Ответ, который я придумал, - 58 символов, например: [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ,0,0,0,0,0,0,0,0,0,0 Если я хочу отправить данные, такие как nr: 1000 или 2000, я могу отправить только ± 9 записей данных, что составляет всего 16 записей словаря. . Поскольку 16 записей не имеют смысла, мне нужно найти способ отправлять данные по частям: отправить пакет данных1, дождаться подтверждения, отправить следующий пакет. Это отличный шаг в изучении C и метода работы Pebble. - person Gaston; 10.10.2015

Первое, что вам нужно сделать, если вы хотите прочитать значения 144, это отправить значения 144 для преобразования. Ваши данные содержат только 138:

[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,59,72,89,110,127,160,192,253,316,352,360,522,539,601,598,770,582,650,810,741,805,894,908,864,904,962,1016,1106,1853,1503,1311,1406,1444,1401,1409,1344,1622,1472,1382,1609,1766,3310,3093,2041,1496,2068,3302,3185,1358,2760,2715,1285,994,1086,832,871,813,1707,1218,1218,239,203,170,132,70,53,45,39,39,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]

У вас есть много вариантов преобразования данных csv в числа. strtok, strsep или лично мой выбор strtol. Причина в том, что для числового преобразования strtol (и родственные функции) обеспечивают наибольшую степень сообщения об ошибках при сбое преобразования.

Поскольку strtol (const char *nptr, char **endptr, int base); использует указатель на преобразуемые цифры (nptr) и обновляет конечный указатель (endptr), указывающий на следующий символ после только что преобразованного числа, он идеально подходит для перехода по строке цифр, разделенных любой разделитель и преобразование всех значений в числа.

Ниже приведен лишь краткий пример того, как вы можете использовать его для преобразования данных "HourPower" в отдельные целые числа, содержащиеся в массиве. Для примера ваши значения просто считываются из stdin. Я предоставил свободную проверку ошибок только для того, чтобы поймать некоторые из основных ошибок, которые в противном случае привели бы к записи за пределы вашего массива и т. д. Это примеры проверок ошибок, которые не претендуют на то, чтобы быть исчерпывающими.

Просмотрите его и дайте мне знать, если у вас есть вопросы:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

#define NDATA 160
#define MAXC 1024

long xstrtol (char *p, char **ep, int base);

int main (void) {

    char line[MAXC] = {0};              /* line buffer for fgets    */
    char *p, *ep;                       /* pointers for strtol      */
    int array[NDATA] = {0};             /* array of values          */
    size_t idx = 0, nelem = 0;          /* indexes, number of ints  */

    /* read each line in file */
    while (fgets(line, MAXC, stdin))
    {
        p = ep = line;  /* initize pointer/end pointer      */

        /* convert each csv value to number, store in array */
        while (errno == 0)
        {
            /* skip delimiters/move pointer to next digit */
            while (*ep && *ep != '-' && (*ep < '0' || *ep > '9')) ep++;
            if (*ep)
                p = ep;
            else  /* break if end of string */
                break;

            array[idx++] = (int)xstrtol (p, &ep, 10); /* convert */

            if (idx == NDATA) { /* NDATA reached, conversion error */
                fprintf (stderr, "error: conversion exceeded 144.\n");
                return 1;
            }

        }

        if (idx != 144)   /* validate 144 values converted */
            fprintf (stderr, "warning: invalid conversion of '%zu' values.\n",
                    idx);

        nelem = idx;  /* save the final number of values (144) */
    }

    printf ("\n the converted json values are:\n\n");
    for (idx = 0; idx < nelem; idx++) {
        printf ("  array[%2zu] : %d\n", idx, array[idx]);
    }
    putchar ('\n');

    return 0;
}

/** a simple strtol implementation with error checking.
*  any failed conversion will cause program exit. Adjust
*  response to failed conversion as required.
*/
long xstrtol (char *p, char **ep, int base)
{
    errno = 0;

    long tmp = strtol (p, ep, base);

    /* Check for various possible errors */
    if ((errno == ERANGE && (tmp == LONG_MIN || tmp == LONG_MAX)) ||
        (errno != 0 && tmp == 0)) {
        perror ("strtol");
        exit (EXIT_FAILURE);
    }

    if (*ep == p) {
        fprintf (stderr, "No digits were found\n");
        exit (EXIT_FAILURE);
    }

    return tmp;
}

Пример вывода

$ ./bin/array_json_xstrtol <hpdata.txt
warning: invalid conversion of '138' values.

 the converted json values are:

  array[ 0] : 0
  array[ 1] : 0
  array[ 2] : 0
  array[ 3] : 0
  array[ 4] : 0
  array[ 5] : 0
  array[ 6] : 0
  array[ 7] : 0
  array[ 8] : 0
  array[ 9] : 0
  array[10] : 0
...
  array[47] : 59
  array[48] : 72
  array[49] : 89
  array[50] : 110
  array[51] : 127
  array[52] : 160
  array[53] : 192
  array[54] : 253
  array[55] : 316
  array[56] : 352
  array[57] : 360
  array[58] : 522
  array[59] : 539
...
  array[130] : 0
  array[131] : 0
  array[132] : 0
  array[133] : 0
  array[134] : 0
  array[135] : 0
  array[136] : 0
  array[137] : 0

Где hpdata.txt содержал данные вашего примера.

person David C. Rankin    schedule 10.10.2015
comment
Вы правы только насчет 138. Солнечные данные могут вырасти за целые сутки до 144. (каждые 10 минут 24 часов). Спасибо за развернутый ответ! - person Gaston; 10.10.2015
comment
Конечно рад помочь. Надеюсь, вы сможете использовать некоторые из них. Я проделал большую работу с анализом данных/числовыми преобразованиями, и это самый гибкий и надежный способ приблизиться к этому. Если вы используете strtok или strsep, все, что они делают, — это разделение значений, вам все равно нужно пройти процесс преобразования строк в числа — это делает все одним выстрелом, используя endptr так, как это было задумано... - person David C. Rankin; 10.10.2015