Smart-Home am Beispiel der Präsenzerkennung im Raum Projektarbeit Lennart Heimbs, Johannes Krug, Sebastian Dohle und Kevin Holzschuh bei Prof. Oliver Hofmann SS2019
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MyOTALogging.cpp 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * The MySensors Arduino library handles the wireless radio link and protocol
  3. * between your home built sensors/actuators and HA controller of choice.
  4. * The sensors forms a self healing radio network with optional repeaters. Each
  5. * repeater and gateway builds a routing tables in EEPROM which keeps track of the
  6. * network topology allowing messages to be routed to nodes.
  7. *
  8. * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
  9. * Copyright (C) 2013-2018 Sensnology AB
  10. * Full contributor list: https://github.com/mysensors/MySensors/graphs/contributors
  11. *
  12. * Documentation: http://www.mysensors.org
  13. * Support Forum: http://forum.mysensors.org
  14. *
  15. * This program is free software; you can redistribute it and/or
  16. * modify it under the terms of the GNU General Public License
  17. * version 2 as published by the Free Software Foundation.
  18. */
  19. #include "MyOTALogging.h"
  20. #ifdef MY_OTA_LOG_SENDER_FEATURE
  21. // global variables
  22. static bool inOTALog = false;
  23. void OTALog(uint8_t logNode, bool enableAck, const char *fmt, ... )
  24. {
  25. // Avoid recursion
  26. if (inOTALog==true) {
  27. return;
  28. }
  29. inOTALog = true;
  30. MyMessage msg(NODE_SENSOR_ID, I_LOG_MESSAGE);
  31. char fmtBuffer[MY_SERIAL_OUTPUT_SIZE];
  32. va_list args;
  33. // create message
  34. va_start (args, fmt );
  35. int n = vsnprintf_P(fmtBuffer, sizeof(fmtBuffer), fmt, args);
  36. va_end (args);
  37. // Check number of chars
  38. if (n<1) {
  39. // Nothing to send
  40. inOTALog = false;
  41. return;
  42. }
  43. // Add \n to the end of string
  44. if (n>(int)(sizeof(fmtBuffer)-2)) {
  45. // String is truncated
  46. n = sizeof(fmtBuffer)-2;
  47. }
  48. // add LF if not set
  49. if (fmtBuffer[n-1]!='\n') {
  50. fmtBuffer[n++]='\n';
  51. fmtBuffer[n++]=0;
  52. }
  53. // Configure message
  54. msg.sender = getNodeId();
  55. msg.setDestination(logNode);
  56. mSetCommand(msg, C_INTERNAL);
  57. mSetRequestAck(msg, enableAck);
  58. // Send package
  59. for (int pos = 0; pos<n; pos+=MAX_PAYLOAD) {
  60. uint8_t length = strlen(&fmtBuffer[pos]);
  61. if (length>MAX_PAYLOAD) {
  62. length = MAX_PAYLOAD;
  63. }
  64. (void)_sendRoute(msg.set((char*)&fmtBuffer[pos]));
  65. }
  66. inOTALog = false;
  67. }
  68. #endif
  69. #ifdef MY_OTA_LOG_RECEIVER_FEATURE
  70. // Global variables
  71. char OTALogfmtBuffer[MY_SERIAL_OUTPUT_SIZE];
  72. int OTALogfmtBufferPos = 0;
  73. uint8_t OTALogBufferNode = BROADCAST_ADDRESS;
  74. uint8_t OTALogBufferSensor = 0;
  75. void OTALogPrintPrefix()
  76. {
  77. char prefix[37];
  78. // prepend debug message to be handled correctly by controller (C_INTERNAL, I_LOG_MESSAGE)
  79. snprintf_P(prefix, sizeof(prefix),
  80. PSTR("%" PRId8 ";%" PRId8 ";%" PRId8 ";0;%" PRId8 ";%" PRIu32 " "),
  81. OTALogBufferNode, OTALogBufferSensor, C_INTERNAL, I_LOG_MESSAGE, hwMillis());
  82. MY_SERIALDEVICE.print(prefix);
  83. }
  84. void OTALogFlushBuffer()
  85. {
  86. OTALogfmtBuffer[0] = 0;
  87. OTALogfmtBufferPos = 0;
  88. OTALogBufferNode = BROADCAST_ADDRESS;
  89. }
  90. inline void OTALogPrint(const MyMessage &message)
  91. {
  92. // Ignore log messages via broadcast
  93. if (message.destination == BROADCAST_ADDRESS) {
  94. return;
  95. }
  96. // FLush buffer, when node id changes
  97. if ((OTALogBufferNode!=BROADCAST_ADDRESS) && ((OTALogBufferNode != message.sender) ||
  98. (OTALogBufferSensor != message.sensor))) {
  99. OTALogPrintPrefix();
  100. MY_SERIALDEVICE.print(OTALogfmtBuffer);
  101. MY_SERIALDEVICE.println("...");
  102. OTALogFlushBuffer();
  103. }
  104. // Add data to buffer
  105. const char *str = message.getString();
  106. strncpy(&OTALogfmtBuffer[OTALogfmtBufferPos], str,
  107. sizeof(OTALogfmtBuffer)-OTALogfmtBufferPos);
  108. OTALogfmtBufferPos += strlen(str);
  109. // Store node ID and sensor ID
  110. OTALogBufferNode = message.sender;
  111. OTALogBufferSensor = message.sensor;
  112. // Print out buffered lines ending with \n
  113. char *EOLpos;
  114. while (EOLpos = strchr(OTALogfmtBuffer,'\n'), EOLpos != NULL) {
  115. // Add end of string
  116. EOLpos[0]=0;
  117. // Print out line
  118. OTALogPrintPrefix();
  119. MY_SERIALDEVICE.println(OTALogfmtBuffer);
  120. // Check if more content in buffer
  121. int lenAfterEOL = (size_t)&OTALogfmtBuffer[OTALogfmtBufferPos]-(size_t)EOLpos-2;
  122. if (lenAfterEOL>0) {
  123. // More lines, move string to the beginning of the buffer
  124. strcpy((char*)&OTALogfmtBuffer[0], (char*)&EOLpos[1]);
  125. // calculate OTALogfmtBufferPos
  126. OTALogfmtBufferPos -= (size_t)EOLpos-(size_t)&OTALogfmtBuffer[0]+2;
  127. // Security check
  128. if ((OTALogfmtBufferPos<=0) || (OTALogfmtBufferPos>=(int)sizeof(OTALogfmtBuffer))) {
  129. MY_SERIALDEVICE.print("Sec:");
  130. MY_SERIALDEVICE.println(OTALogfmtBufferPos);
  131. OTALogFlushBuffer();
  132. }
  133. } else {
  134. // End of message, prepare new one
  135. OTALogFlushBuffer();
  136. }
  137. }
  138. }
  139. #endif