home-assistant / core

:house_with_garden: Open source home automation that puts local control and privacy first.
https://www.home-assistant.io
Apache License 2.0
71.05k stars 29.71k forks source link

MySensors: Request V_TEMP always = 0, Supported request types? #26503

Closed Swiftnesses closed 5 years ago

Swiftnesses commented 5 years ago

Hello,

I'm trying to receive a V_TEMP value from the controller. It appears this isn't supported (always returns 0) but other types such as V_VAR1 are... where can I find a list of supported request types?

MartinHjelmare commented 5 years ago

Please give further detail about what sketch you're using and what kind of entity is or isn't created.

Swiftnesses commented 5 years ago

Hi @MartinHjelmare,

Nothing too complex, in this case I'm trying to work out what types support a node request?

For example, setting a V_TEMP value and trying a request leads to 0 being returned. I've tried V_STATUS and V_VAR1 which both appear to support request, where can I find a list of supported types? - I checked the code but couldn't find anything...

I would like to use V_TEMP, but can always use another type if required, perhaps more types could be supported...?

MartinHjelmare commented 5 years ago

All v types support the request command.

If you post your sketch we might be able to see what's going on.

Swiftnesses commented 5 years ago

Here's a test node:

/*
  REVISION HISTORY
*/

//*** EXTERNAL LIBRARIES **********************************

//*** MYSENSORS *******************************************

// Enable MY_SPECIAL_DEBUG in sketch to activate I_DEBUG messages if MY_DEBUG is disabled
// I_DEBUG requests are:
// R: routing info (only repeaters): received msg XXYY (as stream), where XX is the node and YY the routing node
// V: CPU voltage
// F: CPU frequency
// M: free memory
// E: clear MySensors EEPROM area and reboot (i.e. "factory" reset)
// #define MY_SPECIAL_DEBUG

// Enable debug prints
#define MY_DEBUG

// Lower serial speed if using 1Mhz clock
// #define MY_BAUD_RATE 9600

#define MY_NODE_ID 99
#define MY_PARENT_NODE_ID 0
#define MY_PARENT_NODE_IS_STATIC

// Search for a new parent node after this many transmission failures, lower threshold for non-repeating nodes (5)
// #define MY_TRANSPORT_MAX_TX_FAILURES (4u)

// Disables uplink check to GW during transport initialisation.
// #define MY_TRANSPORT_UPLINK_CHECK_DISABLED

// Time to wait for messages default is 500ms
// #define MY_SMART_SLEEP_WAIT_DURATION_MS (1000ul)

// Transport ready boot timeout default is 0 meaning no timeout
// Set to 30 seconds on battery nodes to avoid excess drainage
#define MY_TRANSPORT_WAIT_READY_MS (6*1000UL)

// Transport ready loop timeout default is 10 seconds
// Usually left at default but can be extended if required
#define MY_SLEEP_TRANSPORT_RECONNECT_TIMEOUT_MS (6*1000UL)

// Enable and select radio type attached
#define MY_RADIO_RF24
// #define MY_RADIO_RFM69

// #define MY_DEBUG_VERBOSE_RF24

// PINS for the RF24 Communication
#define MY_RF24_CE_PIN 10
#define MY_RF24_CS_PIN 9

// Override RF24L01 channel number default is 125
#define MY_RF24_CHANNEL 125

// Override RF24L01 module PA level default is max
#define MY_RF24_PA_LEVEL RF24_PA_MAX

// Override RF24L01 datarate default is 250Kbps
// #define MY_RF24_DATARATE RF24_250KBPS

// Enabled repeater feature for this node
// #define MY_REPEATER_FEATURE

#include <MySensors.h>

// *** SKETCH CONFIG **************************************

#define SKETCH_NAME "Test Node"
#define SKETCH_MAJOR_VER "1"
#define SKETCH_MINOR_VER "0"

// Define the sensor child IDs
#define CHILD_ID1 1 // Temperature
#define CHILD_ID2 2 // Humidity

// Define the message formats
MyMessage msg1(CHILD_ID1, V_TEMP);
MyMessage msg2(CHILD_ID2, V_HUM);

// *** SENSORS CONFIG *************************************

// Used to generature random mock sensor values
int temperature = 0;
int humidity = 0;

bool comms_ready = false;
bool msg_sent = false;
int ack_child = -1;

int test;

// Define loop time
#define LOOP_TIME 2000 // normally 30 minutes 1800000UL

// *** BEGIN **********************************************

void setup() {
  // Auto retransmit delay 1500us(5), auto retransmit count (15)
  // RF24_setRetries (0, 0);
}

void presentation() {
  // Send the sketch version information to the gateway and controller
  sendSketchInfo(SKETCH_NAME, SKETCH_MAJOR_VER "." SKETCH_MINOR_VER);
  // Register all sensors to the gateway
  present(CHILD_ID1, S_TEMP, F("Temperature sensor"));
  present(CHILD_ID2, S_HUM, F("Humidity sensor"));
}

void loop() {
#ifdef MY_DEBUG
  Serial.print(F("Transport status: "));
  Serial.println(isTransportReady());
  Serial.print(F("Uplink status: "));
  Serial.println(transportCheckUplink());
  Serial.print(F("Hops: "));
  Serial.println(transportGetDistanceGW());
  Serial.print(F("Parent: "));
  Serial.println(transportGetParentNodeId());
#endif

  // Check if transport and uplink are ready
  if (transportCheckUplink() == true && isTransportReady() == true) {
    Serial.println(F("Comms ready!"));
    comms_ready = true;
  } else {
    int repeat = 1;
    const int repeats = 10;
    const int repeatDelay = 10;
    comms_ready = false;
    while (comms_ready == false && repeat <= repeats) {
      bool transport_ready = isTransportReady();
      bool uplink_ready = transportCheckUplink();
      if (transport_ready == true && uplink_ready == true) {
        Serial.println(F("Transport and uplink ready!"));
        comms_ready = true;
      }
      if (transport_ready == false) {
        Serial.println(F("Transport not ready, retrying..."));
      }
      if (uplink_ready == false) {
        Serial.println(F("Uplink not ready, retrying..."));
      }
      repeat++;
      wait(repeatDelay);
    }
  }

  // Only start loop if comms are ready
  if (comms_ready == true) {

    temperature = random(5, 30);
    humidity = random(1, 100);

#ifdef MY_DEBUG
    Serial.print(F("Temperature: "));
    Serial.println(temperature);
#endif

    sendmsg(msg1.set(temperature, 0), true);
    wait(2000);

#ifdef MY_DEBUG
    Serial.print(F("Humidity: "));
    Serial.println(humidity);
#endif

    sendmsg(msg2.set(humidity, 0), true);
    wait(2000);

    request(CHILD_ID1, V_TEMP);
    wait(1000);
  }

  wait(LOOP_TIME); // wait or smartSleep
}

void sendmsg(MyMessage &message, bool ack_requested) {
  while (msg_sent == false) {
    resend(message, ack_requested);
    if (msg_sent == true) {
      msg_sent = false;
      break;
    }
  }
}

void resend(MyMessage &message, bool ack_requested) {
  int repeat = 1;
  const int repeats = 10;
  const int repeatDelay = 10;

  ack_child = message.sensor;

  Serial.print(F("Sending message of child: "));
  Serial.println(message.sensor);

  while (repeat <= repeats && msg_sent == false) {
    if (send(message, ack_requested) == true) {
      Serial.println(F("Hardware ACK!"));
      // Set message as unsent if ack is required
      if (ack_requested == true) {
        Serial.println(F("Software ACK requested..."));
      }
      // Set message as sent if ack not required
      if (ack_requested == false) {
        msg_sent = true;
        break;
      }
    } else {
      Serial.print(F("Send error: "));
      Serial.println(repeat);
    }

    repeat++;
    wait(repeatDelay);
  }
}

void receive(const MyMessage &message) {
  Serial.println(F("Message received from gateway..."));
  // 2.3.2+ isEcho
  if (message.isAck()) {
    Serial.print(F("Type: "));
    Serial.println(message.type);
    Serial.print(F("Child: "));
    Serial.println(message.sensor);
    Serial.print(F("Destination: "));
    Serial.println(message.destination);
    if (message.sensor == ack_child) {
      Serial.println(F("Software ACK!"));
      msg_sent = true;
    } else {
      Serial.println(F("Software ACK is wrong!"));
    }
  }
  if (message.type == V_TEMP) {
    Serial.println(F("Var received"));
    Serial.print("message.getInt()= ");
    Serial.println(message.getInt());
    test = message.getInt();
  }
}
Swiftnesses commented 5 years ago

Oh man, I just figured it out, changing:

sendmsg(msg2.set(humidity, 0), true);

to

sendmsg(msg2.set(humidity), true);

Fixes it, I assume that's because it was being sent as a float!