Particle Subscribe garbling data

I’m working on a project to pull weather data onto a Photon.

I have a webhook firing properly with a response template and everything is looking good from the cli:

{"name":"hook-response/WUForecast/0","data":"54~79~1~0~5.8~","ttl":60,"published_at":"2019-10-06T03:54:57.132Z","coreid":"particle-internal"}

My subscribe handler is firing, but i’m unable to parse the values inside the data payload.

Here’s my code and what it is producing:

void setup() {
    Particle.subscribe("hook-response/WUForecast", weatherDataParser, MY_DEVICES);
}

void weatherDataParser(const char *eventName, const char *data) {
Particle.publish("WeatherBug", "weatherDataParser eventName (String): " + String(eventName), PRIVATE);
    Particle.publish("WeatherBug", "weatherDataParser data (String): " + String(data), PRIVATE);
    char strBuffer[strlen(data)+1];
    strcpy(strBuffer, data);
    forecastMinimumTemp = atoi(strtok(strBuffer, "~"));
    forecastMaximumTemp = atoi(strtok(NULL, "~"));
    forecastDayIcon = atoi(strtok(NULL, "~"));
    precipitationProbability = atoi(strtok(NULL, "~"));
    forecastWindSpeed = atoi(strtok(NULL, "~"));
}   

And this is what i’m getting on my console:

{"name":"WeatherBug","data":"weatherDataParser eventName (String): �C�xq�Zk��\u001a\r~&x�)3�p�\u0015E\u0003 v�co\u0010��D�����?\u001b��-\u0012[���r�W�=��N%��\t��t�7H�h�\"\u000e�ɖW�HJymK�!�U�5v�.��RW�n�\u0014�a0\u0019�H�����\u000f�\u000b��!30��E\u001c\u0013�R�\u001b��E��M�t\fO\u0005�c�f�_�X���kV<�\u0014�5�Fk4ª�\u0016�T�1\u0001��%��;\f�vzNm�\u0010*\u000f��r�\u0010���\u0006[�[��1�f�$\u0016����\u0001�K�kb���~ʉ&\u0006���\u00178[7[��х�J�\u001c���a\u000e�1�un:�?V�\u0015�٢���\u001f�&X������p�ٰvF�]��+�p�D0wE’|���\u001d/Џ��w#\"7A�\"M�f�����R�`��\u0011���\u000fF�[ �0����\"�h�\u0006v\u0012�F*&P��Z�\u0019�\u0016:\u0001MY�\u000f\u0007��ЎӖ\u001e�c�s��\u000e^��6���ag!\u0015b��<�͋�^Uc@e`2���Օ�FƖ��\u0006�[\"��\f<\u0011�L�`���鱟{\u001e+t�\\$!$�\u000f\u001e�\nΝ!2��QD�\t�7F�%r%\u0006��n\u0014��wZ�)�R\u00109Y\u0005\u001b=\u0003�{VdKy\\���\u0012b��3s�U��5��\u001a̐��Z\u0006���D\u0002�r�r\u001a\u0006R7U�ʬ��2���=4[���","ttl":60,"published_at":"2019-10-06T03:57:45.140Z","coreid":"3c003d000c47363433353735"}
{"name":"WeatherBug","data":"weatherDataParser data (String): �3+��0<�e��/\u0012)�74�\u001d��s��~\u001e\u0010Q���m�|�#��B�`\u0010�L�\u0012���h42W\u001a2:���T�Vd$q\u00115��G�\u001a�\u001d?\u001cq�!�t/[�r�.T���c��?��\u0013\f\u0004�~���;�\u0012�0�DZ#P�:�n���R_&V����dޭ�v4�'�\\\u001fI���X\u0003'e8�i��eHX�����y�=�?�\t�c�*�x�)&��Z)O�q|�t6�\u0004�Fw_]�x��Mz��k\u0016)y��L/^��\u001co>�7�rF\u001ej�'��:�\u001b\u000fd��~�E�����+O�&㾣8\u0003��T��psƦ�n\u0011\u0001��X\"��u��\u000f�?�)\u000f]d5tz\u0015-tc��ԋ�-�=k�KhE����K���z����j�W\u0010�@d���ڃEу���he�E�U���g��\u0012�_\r�L\u001bnH\\TF�'�ʼ�\\3Jv�4�(�}�ja.Q�o\"�\\\u0019#T���p;\u0006�e>�\u0010^�?I�J|�=9�u@=\f�\u0002�Z[����|������\u001a�L����7�\u0012$r?W�r�~b�A?��\u0001\t�)v\u0004�a(��6F\u0006�Z\u0011b�����G'�r�q0z�v���\u0013I\f��!��","ttl":60,"published_at":"2019-10-06T03:57:45.223Z","coreid":"3c003d000c47363433353735"}

I feel like i’m missing something really dumb but I can’t spot the error. Anyone seen this kind of problem?

Webhook included in case that helps:

{
    "event": "WUForecast",
    "url": "http://dataservice.accuweather.com/forecasts/v1/daily/1day/39384_pc?apikey=<API-KEY-HERE>&details=true",
    "requestType": "GET",
    "noDefaults": true,
    "rejectUnauthorized": true,
    "responseTemplate": "{{#DailyForecasts}}{{RealFeelTemperature.Minimum.Value}}~{{RealFeelTemperature.Maximum.Value}}~{{Day.Icon}}~{{Day.PrecipitationProbability}}~{{Day.Wind.Speed.Value}}~{{/DailyForecasts}}"
}

That is a known issue with your code not considering this documented behaviour
https://docs.particle.io/reference/device-os/firmware/photon/#particle-subscribe-

If you had your strcpy() call before the publishes, your code would work as expected.

However, this is what I’d do instead

void weatherDataParser(const char *eventName, const char *data) {
  // FIRST do the required stuff
  if (sscanf(data                                        // parsing 5 ints into their respective variables
            , "%d~%d~%d~%d~%d"
            , &forecastMinimumTemp
            , &forecastMaximumTemp
            , &forecastDayIcon
            , &precipitationProbability
            , &forecastWindSpeed
            ) < 5)                                       // if we couldn't parse all 5 expected items
    Log.warn("Parsing error");                           // log a warning

  // AFTER the actual work publish some "debug" info 
  char str[strlen(eventName) + strlen(data) + 4];        // enough space for both parameters plus some extra
  snprintf(str, sizeof(str), "%s: %s", eventName, data); // format [eventName]: [data]
  Particle.publish("WeatherBug", str, PRIVATE);          // only one event for both infos
}   
1 Like

Brilliant - thanks!! Will implement this in the morning and i’m sure it’ll all work perfectly. Thanks for the tip on sscanf() too, that seems cleaner than my string buffer manipulation.

1 Like