Copyright © https://mongoose-os.com

Mongoose OS Forum

frame

Time based event

DuncanCTDuncanCT South Africa

I would like to reset a counter at midnight.

This is the basic idea but not sure if any of it is right? Any help is appreciated.

let resetcounter = function() {
  let now = Timer.now();
  let timestamp = Timer.fmt("%H:%M:%S", now);
};

if (resetcounter = '00:00:00') {
  let counter = 0;
}

Comments

  • SergeySergey Dublin, Ireland

    Use cron library

    Thanked by 1DuncanCT
  • DuncanCTDuncanCT South Africa

    So as far as I can gather from this...

    https://github.com/mongoose-os-libs/cron

    the c/c++ api ref suggests this...

    0 0 0 * * * for midnight.

    And here... https://www.npmjs.com/package/cron

    var CronJob = require('cron').CronJob;
    new CronJob('0 0 0 * * *', function() {
      let counter = 0;
    }, null);

    Assume this syntax (not sure that's the correct terminology?) is wrong for mJS?

    Or can someone please link to a mJS example somewhere?

  • nliviunliviu Romania
    edited April 11

    C/C++ interoperability
    You need to ffi mgos_cron_add in mJS code and define a callback.

    Thanked by 1DuncanCT
  • @nliviu
    Can you give an example code and js function to call a defined callback?

  • nliviunliviu Romania
    /*
     * Cron callback signature; `user_data` is a pointer given to
     * `mgos_cron_add()`, and `id` is the id of the corresponding cron job.
     * typedef void (*mgos_cron_callback_t)(void *user_data, mgos_cron_id_t id);
     */
    function cronCallback(arg, cron_id)
    {
        let now = Timer.now();
        let timestring = Timer.fmt('%FT%TZ', now);
        print('++++ cronCallback id=' + JSON.stringify(cronId) + ', time=' + timestring);
    }
    
    /*
     * Adds cron entry with the expression `expr` (a null-terminated string, should
     * be no longer that 256 bytes) and `cb` as a callback.
     * `user_data` is an arbitrary pointer which will be passed to `cb`.
     * Returns cron ID.
     * mgos_cron_id_t mgos_cron_add(const char *expr, mgos_cron_callback_t cb, void *user_data);
    */
    let cronAdd = ffi('int mgos_cron_add(char*, void (*)(userdata, int),userdata)');
    cronAdd("*/15 * * * * *", cronCallback, null);
    

    cronCallback is called every 15 seconds.

    Results:

    [Apr 13 06:32:14.254] s_print_time         Next invocation: 1523590350 [2018/04/13 03:32:30 UTC]
    [Apr 13 06:32:14.294] ++++ cronCallback id=1073531312, time=2018-04-13T03:32:15Z 
    [Apr 13 06:32:29.254] s_print_time         Next invocation: 1523590365 [2018/04/13 03:32:45 UTC]
    [Apr 13 06:32:29.299] ++++ cronCallback id=1073531312, time=2018-04-13T03:32:30Z 
    [Apr 13 06:32:44.255] s_print_time         Next invocation: 1523590380 [2018/04/13 03:33:00 UTC]
    [Apr 13 06:32:44.294] ++++ cronCallback id=1073531312, time=2018-04-13T03:32:45Z 
    
    Thanked by 2Generator DuncanCT
  • @nliviu Thank You!
    Everything works fine!
    However, the question remained: how to pick up an event, which is created through prc-service-cron?

  • DuncanCTDuncanCT South Africa
    edited April 13

    Back with the stupid questions, please forgive me.

    Do the two pieces of code @nliviu provided all need to be in init.js or elsewhere?

    For my example of resetting counter at midnight...

    function cronCallback(arg, cron_id)
    {
        let counter = 0;    
    }

    let cronAdd = ffi('int mgos_cron_add(char*, void (*)(userdata, int),userdata)');
    cronAdd("0 0 0 * * *", cronCallback, null);

    Are any other changes that need to be made to the device files?

  • DuncanCTDuncanCT South Africa
    edited April 13

    After adding the cron library to the yml file then build and flashing @nliviu code posted above...

    load('api_config.js');
    load('api_events.js');
    load('api_gpio.js');
    load('api_mqtt.js');
    load('api_net.js');
    load('api_sys.js');
    load('api_timer.js');
    load('api_shadow.js');
    function cronCallback(arg, cron_id) {
      let now = Timer.now();
      let timestring = Timer.fmt('%FT%TZ', now);
      print('++++ cronCallback id=' + JSON.stringify(cronId) + ', time=' + timestring);
    }
    let cronAdd = ffi('int mgos_cron_add(char*, void (*)(userdata, int),userdata)');
    cronAdd("*/15 * * * * *", cronCallback, null);

    I get this...

    [Apr 13 13:58:46.861] s_print_time         Next invocation: 1523620740 [2018/04/13 11:59:00 UTC]
    [Apr 13 13:58:46.923]   at init.js:13
    [Apr 13 13:58:46.924] MJS callback error: [cronId] is not defined

    Final edit see that JSON.stringify(cronId) should be JSON.stringify(cron_id)

  • @DuncanCT, replace

    cronAdd("*/15 * * * * *", cronCallback, null);

    to

    let cronId = cronAdd("*/15 * * * * *", cronCallback, null);

    Thanked by 1DuncanCT
  • nliviunliviu Romania

    Sorry, it was my fault, it was meant to be

    function cronCallback(arg, cronId)
    {
        let now = Timer.now();
        let timestring = Timer.fmt('%FT%TZ', now);
        print('++++ cronCallback id=' + JSON.stringify(cronId) + ', time=' + timestring);
    }
    
    Thanked by 1DuncanCT
  • nliviunliviu Romania

    @DuncanCT Something like that

    let counter=0;
    /*
    do something with the counter
    ...
    */
    
    function cronCallback(arg, cron_id)
    {
        counter = 0;    
    }
    
    Thanked by 1DuncanCT
  • nliviunliviu Romania

    @Generator What is your question? Ref: "However, the question remained: how to pick up an event, which is created through prc-service-cron?"

  • @nliviu
    After adding the entry to crontab, using RPC call Cron.add. The cron firing event
    and i have error message in log panel

    [Apr 13 19:52:35.816] cron_cb              Cron job 2 is firing: "bar" {}
    [Apr 13 19:52:35.822] cron_cb              No actual handler for the cron action "bar"
    

    Question - how to add a handler for the cron action "bar" in mJS code?

  • nliviunliviu Romania

    You have to associate the action from Cron.Add with a callback using mgos_crontab_register_handler
    Example in C:

    #include <mgos.h>
    #include "mgos_crontab.h"
    
    void test(struct mg_str action, struct mg_str payload, void *userdata) {
      (void) payload;
      (void) userdata;
      time_t t = time(0);
      struct tm* timeinfo = localtime(&t);
      char timestamp[24];
      strftime(timestamp, sizeof (timestamp), "%FT%TZ", timeinfo);
      LOG(LL_INFO, ("%s - crontab test, action: %.*s", timestamp, action.len, action.p));
    }
    
    enum mgos_app_init_result mgos_app_init(void) {
      /*
       * Add a handler for the given string action
       *
       * Example:
       *
       * ```c
       * static void my_foo_cb(struct mg_str action,
       *                       struct mg_str payload, void *userdata) {
       *   LOG(LL_INFO, ("Crontab foo job fired! Payload: %.*s", payload.len, payload.p));
       *   (void) action;
       *   (void) userdata;
       * }
       *
       * // Somewhere else:
       * mgos_crontab_register_handler("foo", my_foo_cb, NULL);
       * ```
       *
       * The code above maps action `foo` in the JSON to the callback `my_foo_cb`.
       */
      mgos_crontab_register_handler(mg_mk_str("test"), test, NULL);
    
      return MGOS_APP_INIT_SUCCESS;
    }
    

    Add cron:
    mos --port ws://<IP>/rpc call Cron.Add '{"at":"*/20 * * * * *", "action":"test"}'

    Results:

    [Apr 13 20:40:39.892] cron_cb              Cron job 1 is firing: "test" 
    [Apr 13 20:40:39.900] test                 2018-04-13T17:40:40Z - crontab test, action: test
    [Apr 13 20:40:59.892] cron_cb              Cron job 1 is firing: "test" 
    [Apr 13 20:40:59.900] test                 2018-04-13T17:41:00Z - crontab test, action: test
    [Apr 13 20:41:19.892] cron_cb              Cron job 1 is firing: "test" 
    [Apr 13 20:41:19.899] test                 2018-04-13T17:41:20Z - crontab test, action: test
    
    mos --port ws://<IP>/rpc call Cron.List
    [
      {
        "id": 1,
        "at": "*/20 * * * * *",
        "enable": true,
        "action": "test"
      }
    ]
    
  • edited April 13

    @nliviu
    Thanks. I tried this example. I just can not understand how to do ffi

    void test(struct mg_str action, struct mg_str payload, void *userdata)

    mgos_crontab_register_handler(mg_mk_str("test"), test, NULL);

    to use it in mJS code

  • nliviunliviu Romania

    C/C++ interoperability.
    AFAIK, the best ideea would be to use C.

Sign In or Register to comment.