Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Question] Function for Client-Side RPC #110

Closed
callmereno opened this issue Jan 9, 2023 · 20 comments
Closed

[Question] Function for Client-Side RPC #110

callmereno opened this issue Jan 9, 2023 · 20 comments

Comments

@callmereno
Copy link

callmereno commented Jan 9, 2023

Hello guys,

i'm trying to perform client-side RPCs. The problem is that there's no predefined function for that in the SDK.
What would be the best way to realize them? I know that I have to subscribe the client to v1/devices/me/rpc/request/$request_id. Sadly i'm not to familiar with the architecture of the SDK. Would it make sense to modfiy this code snippet (v0.6.1)?:

    bool RPC_Subscribe(const RPC_Callback *callbacks, size_t callbacks_size) {
      if (callbacks_size > sizeof(m_rpcCallbacks) / sizeof(*m_rpcCallbacks)) {
        return false;
      }
      if (ThingsBoardSized::m_subscribedInstance) {
        return false;
      }

      if (!m_client.subscribe("v1/devices/me/rpc/request/+")) {
        return false;
      }

      ThingsBoardSized::m_subscribedInstance = this;
      for (size_t i = 0; i < callbacks_size; ++i) {
        m_rpcCallbacks[i] = callbacks[i];
      }

      m_client.setCallback(ThingsBoardSized::on_message);

      return true;
    }

    inline bool RPC_Unsubscribe() {
      ThingsBoardSized::m_subscribedInstance = NULL;
      return m_client.unsubscribe("v1/devices/me/rpc/request/+");
    }

Also this could be a nice feature for a future release.

My use case is that i want to send data from my client to TB when i press a button. The workaround that I was working is updating client attributes, but I think client RPCs would be more efficient and flexible.

Greetings
Reno

@callmereno callmereno changed the title [Question] Function for Client-RPC [Question] Function for Client-Side RPC Jan 9, 2023
@MathewHDYT
Copy link
Contributor

MathewHDYT commented Jan 11, 2023

I'm not sure what you mean, client side rpc is meant for you send a command to the cloud, meaning you might send a json containing a method called "getTime", and then the cloud will send you back a response containing the current timestamp.

But using it for simply sending data to the cloud doesn't make sense. Could you explain your use case a little bit further, sorry for the confusion.

I'm not sure but it could also be that you mean server-side RPC, that is when the server sends a message including a method name "getTemperature" and you return a message containing the current value which can then be displayed.

@callmereno
Copy link
Author

I want to clear an alarm locally by pushing a button. Right now i'm doing so by updating the client attribute

@MathewHDYT
Copy link
Contributor

Yeah okay that would make sense to integrate client side RPC for, if you could wait a while I might be able to integrate it in the next few days. I am currently working on an update to the OTA firmware update as well to allow a passive ota update (update starts as soon as the firmware is assigned to the device), as well as a call-back that tracks the progress of the download.

If it is very urgent you could also try it yourself, you can probably copy and inspire yourself with the Shared Attribute Request API, because it seems very similar, you request something and then get a response once, afterwards the callback can be cleared.

@callmereno
Copy link
Author

callmereno commented Jan 12, 2023

I will stick with my solution for now since i'm running out of time for my master thesis. But I will try it when i have time.
Keep me posted if you want :)

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Jan 12, 2023

Sadly couldn't completely finish the client side RPC implementation, but everything besides handling a possible response from the server is implemented, will probably try to finish that tomorrow. It will probably be completely tested and implemented friday evening.

@callmereno
Copy link
Author

Very cool man! I will try out the client-side RPC and let you know if it worked.

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Jan 13, 2023

Everything should at least on my ESP32 it does (at least the client-side RPC, changed some other stuff as well), but the optional response is still bugged shouldn't matter for your use case tough. Will try to fix that as well might need a while tough.

@callmereno
Copy link
Author

callmereno commented Jan 13, 2023

Could it be that #include <Seeed_mbedtls.h> is missing in your HashGenerator.h? #107

@MathewHDYT
Copy link
Contributor

The include has been added but only if you are actually using an ESP8266 board instead of an ESP32 board, but I didn't compile that code and got the Stack-trace, I just decoded yours? Sorry if I misunderstand.

@callmereno
Copy link
Author

callmereno commented Jan 13, 2023

I was getting the an error we discussed in #107:

grafik

So I applied the same troubleshooting (adding #include <Seeed_mbedtls.h> in the HashGenerator.h) and it fixed the problem i was just referring to:

Could it be that #include <Seeed_mbedtls.h> is missing in your HashGenerator.h? #107

Sadly I'm still getting Exceptions with the 0.8.0.. I used your updated fork. Here are the .zip containg the .elf-file and the exception I'm getting:

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (3):
epc1=0x40220e52 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4026edb3 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffd60 end: 3fffffc0 offset: 0190
3ffffef0:  00000000 3ffe8ac8 00000000 4020b440  
3fffff00:  514d0400 00045454 3ffe92c9 4020df7c  
3fffff10:  00000000 4026edb3 00000000 00000000  
3fffff20:  00000001 00000100 00000000 3fff084c  
3fffff30:  4020b860 3ffe92c8 3fff070c 3fff084c  
3fffff40:  3fffdad0 00000000 3fff05bc 4020b628  
3fffff50:  00000000 00000000 00000001 4020bbb0  
3fffff60:  5fb2a8c0 00ffffff 01b2a8c0 40206082  
3fffff70:  3fffdad0 3fff06d0 3fff070c 402057b8  
3fffff80:  40210c70 5fb2a8c0 00000000 3fff084c  
3fffff90:  3fffdad0 00000000 3fff05bc 40206208  
3fffffa0:  feefeffe feefeffe 3fff0838 4020d12c  
3fffffb0:  feefeffe feefeffe 3ffe86e0 40100d45  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

elf.zip

Let me know if you need something from me.

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Jan 13, 2023

Sorry for the confusion could you download the fork off this branch: https://github.com/MathewHDYT/thingsboard-arduino-sdk/tree/feat_examples

Because the changes are on that branch and not the main one so the version you downloaded is still the same as the main repository. Would be nice if you could then recompile again. Sorry for the inconvenience.

That should also fix any compilation errors on the ESP8266.

@callmereno
Copy link
Author

callmereno commented Jan 13, 2023

Could it be that ´#include <Seeed_mbedtls.h>´ is missing in your HashGenerator.h? #107

Ah, okay this probably also explains why I had this error again. Still getting an exception though :(

Code_Aktuator_TBv080.ino.zip <- elf.-file

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (3):
epc1=0x402211ee epc2=0x00000000 epc3=0x00000000 excvaddr=0x4026f0a3 depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffd60 end: 3fffffc0 offset: 0190
3ffffef0:  00000000 3ffe8b09 00000000 4020babc  
3fffff00:  514d0400 00045454 3ffe9309 4020e348  
3fffff10:  00000000 4026f0a3 00000000 00000000  
3fffff20:  00000001 00000100 00000000 3fff08a8  
3fffff30:  4020bedc 3ffe9308 3fff0768 3fff08a8  
3fffff40:  3fffdad0 00000000 3fff05fc 4020bca4  
3fffff50:  00000000 00000000 00000001 4020c22c  
3fffff60:  5fb2a8c0 00ffffff 01b2a8c0 40206246  
3fffff70:  3fffdad0 3fff072c 3fff0768 40205880  
3fffff80:  40211010 5fb2a8c0 00000000 3fff08a8  
3fffff90:  3fffdad0 00000000 3fff05fc 402063d8  
3fffffa0:  feefeffe feefeffe 3fff0894 4020d4f8  
3fffffb0:  feefeffe feefeffe 3ffe86e0 40100d45  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

I just saw that there's an update for the esp8266 boards. I'll try again

@MathewHDYT
Copy link
Contributor

Will check it tomorrow, but as before I am still pretty confused what could actually cause the issues.

Could you try to compile an test the examples for the ESP8266 in the examples folder and see if you get an exception there as well. Would be highly appreciated.

@callmereno
Copy link
Author

I am still pretty confused what could actually cause the issues.

I only can imagine how annoying this must. I'll report back!

@callmereno
Copy link
Author

Same error after updating the ESP8266 board manager from 3.0.0 to 3.1.0:

my_elf.zip

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Exception (3):
epc1=0x40221116 epc2=0x00000000 epc3=0x00000000 excvaddr=0x4026dbaf depc=0x00000000

>>>stack>>>

ctx: cont
sp: 3ffffd70 end: 3fffffd0 offset: 0190
3fffff00:  3ffe8ae9 3fff05dc 00000000 4021097d  
3fffff10:  00000000 3ffe8afd 00000000 4020ba60  
3fffff20:  514d0400 00045454 00000020 40100ac0  
3fffff30:  00000000 4026dbaf 00000000 00000000  
3fffff40:  00000001 00000100 0000000c 4020e324  
3fffff50:  3ffe92ea fffffffc 3fff0710 3fff08d4  
3fffff60:  3fffdad0 00000000 3fff05dc 4020bc48  
3fffff70:  00000000 00000000 00000001 4020c1c4  
3fffff80:  3fffdad0 3fff0710 3fff074c 40205f46  
3fffff90:  40210e44 6ab2a8c0 00000000 feefeffe  
3fffffa0:  3fffdad0 00000000 3fff08a8 3fff08d4  
3fffffb0:  3fffdad0 00000000 3fff08a8 4020d5d4  
3fffffc0:  feefeffe feefeffe 3fffdab0 40100e2d  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

When i try to compile your rpc example. Is this maybe caused by me using an ESP8266`?

c:\Users\Renaud Kenfack\Documents\Arduino\libraries\WiFiEsp-master\src\WiFiEspClient.cpp: In member function 'size_t WiFiEspClient::print(const __FlashStringHelper*)':
c:\Users\Renaud Kenfack\Documents\Arduino\libraries\WiFiEsp-master\src\WiFiEspClient.cpp:47:1: error: no return statement in function returning non-void [-Werror=return-type]
   47 | }
      | ^
c:\Users\Renaud Kenfack\Documents\Arduino\libraries\WiFiEsp-master\src\WiFiEspClient.cpp: In member function 'size_t WiFiEspClient::println(const __FlashStringHelper*)':
c:\Users\Renaud Kenfack\Documents\Arduino\libraries\WiFiEsp-master\src\WiFiEspClient.cpp:54:1: error: no return statement in function returning non-void [-Werror=return-type]
   54 | }
      | ^
cc1plus.exe: some warnings being treated as errors

@MathewHDYT
Copy link
Contributor

MathewHDYT commented Jan 14, 2023

Decoded Stacktrace:

Exception Cause: 3  [LoadStoreError: Processor internal physical address or data error during load or store]

0x40221006: _svfwprintf_r at /workdir/repo/newlib/newlib/libc/stdio/vfwprintf.c:1521
0x4026efc5: etharp_output at ??:?
0x4020b5f4: PubSubClient::unsubscribe(char const*) at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.cpp:646
0x4020e130: uart_peek_available at C:\Program Files\Arduino IDE/C:\Users\Renaud Kenfack\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/uart.cpp:260
0x4026efc5: etharp_output at ??:?
0x4020ba14: PubSubClient::connect(char const*, char const*, char const*, char const*, unsigned char, bool, char const*, bool) at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.cpp:197
 (inlined by) PubSubClient::connect(char const*, char const*, char const*, char const*, unsigned char, bool, char const*, bool) at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.cpp:181
0x4020b7dc: PubSubClient::loop() at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\PubSubClient\src/PubSubClient.cpp:370
0x4020bd64: HardwareSerial::available() at C:\Program Files\Arduino IDE/C:\Users\Renaud Kenfack\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/HardwareSerial.cpp:107
0x40206236: std::vector<Shared_Attribute_Callback, std::allocator<Shared_Attribute_Callback> >::at(unsigned int) at ??:?
0x402057b8: ArduinoJson6191_F1::parseNumber(char const*, ArduinoJson6191_F1::VariantData&) at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Numbers/parseNumber.hpp:53
0x40210e24: std::_Function_handler<bool (), settimeofday::{lambda()#1}>::_M_manager(std::_Any_data&, std::_Function_handler<bool (), settimeofday::{lambda()#1}> const&, std::_Manager_operation) at time.cpp:?
0x402063b8: ArduinoJson6191_F1::TextFormatter<ArduinoJson6191_F1::Writer<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, void> >::writeRaw(char const*) at C:\Program Files\Arduino IDE/c:\Users\Renaud Kenfack\Documents\Arduino\libraries\ArduinoJson\src/ArduinoJson/Json/TextFormatter.hpp:146
0x4020d2e0: eboot_command_write at C:\Program Files\Arduino IDE/C:\Users\Renaud Kenfack\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266/core_esp8266_eboot_command.cpp:53
0x40100d45: calloc at C:\Program Files\Arduino IDE/C:\Users\Renaud Kenfack\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.0\cores\esp8266\umm_malloc/umm_malloc.cpp:1275

and the error you get for the RPC example is also really werid, it seems to simply call return; without returnign a size_t like expected. I'm not sure why this is a problem only now tough and I also don't get when print / println on the WiFiEspClient class should even be called?

The weird things Is i adjusted PlattformIO to build for ESP8266 instead and the RPC example does compile for me. What type of ESP8266 are you using (what board is it connected too)?


And just to try can you define your constants like this

constexpr char WIFI_SSID[] PROGMEM = "YOUR_WIFI_SSID";
constexpr char WIFI_PASSWORD[] PROGMEM = "YOUR_WIFI_PASSWORD";

instead of #defines, I'm not sure what could cause the LoadStoreError, but that at least ensure you passed the correct data type to each method + it ensures we don't overwrite any other #defines.

@MathewHDYT
Copy link
Contributor

It seems someone else has the exact same problem and their stacktrace makes more sense, I'm assuming the stacktrace I got wasn't correct, because they seem to crash on the ESP8266WiFiSTAClass::begin() method. See #112

@callmereno
Copy link
Author

Hey @MathewHDYT ,

is there an example for client-side RPC?

Greetings Reno

@MathewHDYT
Copy link
Contributor

Here is an example it uses the ESP32 or ESP8266, but it still should lead you into the right direction.

@MathewHDYT
Copy link
Contributor

@imbeacon This can be closed as solved, client side RPC has been implemented and works well on the ESP32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants