Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Feature Requests
  3. Extra command message type for local data requests

Extra command message type for local data requests

Scheduled Pinned Locked Moved Feature Requests
4 Posts 2 Posters 1.9k Views 3 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • BartEB Offline
    BartEB Offline
    BartE
    Contest Winner
    wrote on last edited by
    #1

    Every now and then i'd think about sensors which rely on data from other sensors/nodes.

    The current way of gathering this data, is request the data direct from the other MySensors-node using the message command type "req" (see api: https://www.mysensors.org/download/serial_api_20) This limits the data gathering to MySensors nodes.

    My proposal would be to extend the message API with an additional message command type called "localrequest"
    where the payload of this command holds the unique device id as known by the HA-controller (each HA has such ID's)

    A localrequest message would look like this:

    30;1;5;0;15;215\n
    

    requesting node id (reply-to node);child id (reply-to sensor id);localrequest-command;nack;V_ARMED;HA-unique ID\n

    By having this localrequest command and using the unique HA-ID all devices connected to this HA can provide data to the MySensors nodes. At least for Vera this will work fine. (i can provide the correct code for the Vera plugin)
    This localrequest will also work for data provided by battery powered nodes which are sleeping most of their time.

    AWIA 1 Reply Last reply
    0
    • BartEB BartE

      Every now and then i'd think about sensors which rely on data from other sensors/nodes.

      The current way of gathering this data, is request the data direct from the other MySensors-node using the message command type "req" (see api: https://www.mysensors.org/download/serial_api_20) This limits the data gathering to MySensors nodes.

      My proposal would be to extend the message API with an additional message command type called "localrequest"
      where the payload of this command holds the unique device id as known by the HA-controller (each HA has such ID's)

      A localrequest message would look like this:

      30;1;5;0;15;215\n
      

      requesting node id (reply-to node);child id (reply-to sensor id);localrequest-command;nack;V_ARMED;HA-unique ID\n

      By having this localrequest command and using the unique HA-ID all devices connected to this HA can provide data to the MySensors nodes. At least for Vera this will work fine. (i can provide the correct code for the Vera plugin)
      This localrequest will also work for data provided by battery powered nodes which are sleeping most of their time.

      AWIA Offline
      AWIA Offline
      AWI
      Hero Member
      wrote on last edited by AWI
      #2

      @BartE I had (and maybe have) a similar need. Domoticz does something like that with S_CUSTOM which can request all kinds of data from the the controller. I have 'solved' it by duplicating the data with a controller script to a sensor specific 'dummy sensor' so that it can be retrieved with a request from the controller.

      Problem with having a controller dependent number would be 'controller dependency' so I'm not sure...
      (and a better name would be 'controllerRequest' :wink:)

      BartEB 1 Reply Last reply
      0
      • AWIA AWI

        @BartE I had (and maybe have) a similar need. Domoticz does something like that with S_CUSTOM which can request all kinds of data from the the controller. I have 'solved' it by duplicating the data with a controller script to a sensor specific 'dummy sensor' so that it can be retrieved with a request from the controller.

        Problem with having a controller dependent number would be 'controller dependency' so I'm not sure...
        (and a better name would be 'controllerRequest' :wink:)

        BartEB Offline
        BartEB Offline
        BartE
        Contest Winner
        wrote on last edited by
        #3

        @AWI i was actually referring to an additional "command" (third byte) and not a V-type.
        The V-type should represent the type of value which is requested from the controller. HA controller like Vera need the message type to be able to retrieve the data.

        ControlleRequest is indeed a better name than local request.

        Using V_CUSTOM could be an alternative. with the first payload byte the request V-type followed by and HA Controller ID.

        I can make a prototype with this implementation.

        1 Reply Last reply
        0
        • BartEB Offline
          BartEB Offline
          BartE
          Contest Winner
          wrote on last edited by
          #4

          OK i did make a prototype implementation using the V_CUSTOM message type.
          This works for Vera only.

          I had to change only one file: L_Arduino.lua
          The function starting on line 244 has te be extened with this if statement:

          -- Handle Local Request variables	
          if (varType == "CUSTOM") then
          	local bit         = require("bit")
                  local varReqIndex = bit.band(tonumber(value), 0xFF);
                  local varVeraId   = bit.rshift(tonumber(value), 8);
          	local varReqType  = tVarLookupNumType[varReqIndex]
          	local varReq      = tVarTypes[varReqType]
                                  
          	if (varReq[2] ~= nil) then 
          		log("Local request '" .. varReq[3] .. "' from Device ID: ".. varVeraId .. " sensor type '" .. varReqType .. "'")
          		local localValue = luup.variable_get(varReq[2], varReq[3], varVeraId)
          		if (localValue ~= nil) then
          			-- Send variable value to actuator
          			sendRequestResponse(nodeId .. ";" .. childId, varReqType, localValue)
          		end
          	end	
          else
          

          The complete function will then look like this:

          local function setVariable(incomingData, childId, nodeId)
          	if (childId ~= nil) then
          		-- Set variable on child sensor.
          		local index = tonumber(incomingData[5]);
          		local varType = tVarLookupNumType[index]
          		local var = tVarTypes[varType]
          		local value = incomingData[6]
          		local timestamp = os.time()
          
                          -- Handle Local Request variables	
          		if (varType == "CUSTOM") then
          			local bit         = require("bit")
                                  local varReqIndex = bit.band(tonumber(value), 0xFF);
                                  local varVeraId   = bit.rshift(tonumber(value), 8);
          			local varReqType  = tVarLookupNumType[varReqIndex]
          			local varReq      = tVarTypes[varReqType]
                                  
          		        if (varReq[2] ~= nil) then 
          				log("Local request '" .. varReq[3] .. "' from Device ID: ".. varVeraId .. " sensor type '" .. varReqType .. "'")
          				local localValue = luup.variable_get(varReq[2], varReq[3], varVeraId)
          				if (localValue ~= nil) then
          					-- Send variable value to actuator
          					sendRequestResponse(nodeId .. ";" .. childId, varReqType, localValue)
          				end
          			end	
          
          		elseif (var[2] ~= nil) then 
          			log("Setting variable '".. var[3] .. "' to value '".. value.. "'")
          			setVariableIfChanged(var[2], var[3], value, childId)
          		
          			-- Handle special variables battery level and tripped which also
          			-- should update other variables to os.time()
          			if (varType == "TRIPPED" and value == "1") then
          				local variable = tVeraTypes["LAST_TRIP"]
          				setVariableIfChanged(variable[2], variable[3], timestamp, childId)
          			else
          				local variable = tVeraTypes["LAST_UPDATE"]
          				setVariableIfChanged(variable[2], variable[3], timestamp, childId)
          			end
          		end
          
          		-- Always update LAST_UPDATE for node	
          		if (nodeId ~= nil) then
          			local nodeDevice = childIdLookupTable[nodeId .. ";" .. NODE_CHILD_ID] 
          			setLastUpdate(nodeDevice)
          		end
          	end
          end
          

          Now the Vera HA-contoller response on V_CUSTOM messages.

          Use the feature in a MySensors node:

          void requestValue(byte type, unsigned int id)
          {
               MyMessage msgRequest(1, V_CUSTOM);
               unsigned long msgData;
               msgData = type + ((unsigned long)id * 0x100); 
               send(msgRequest.set(msgData));
          }
          
          void loop()
          {
               // Request the status from Vera Device 4
               requestValue(V_STATUS,  4);
           
              // Request the dimn level  from Vera Device 20
              requestValue(V_LEVEL, 20);
             
             // etc..  
          }
          

          Make sure you can handle the incoming messages

          void receive(const MyMessage &message)
          {
          	if (message.type==V_STATUS) {
          		Serial.print(" New value: ");
          		Serial.println(message.getBool());
          	}
                 if (message.type==V_LEVEL) {
          		Serial.print(" New value: ");
          		Serial.println(message.getByte());
          	}
                 if (message.type==V_TEMP) {
          		 Serial.print(" New value: ");
          		Serial.println(message.getFloat());
          	}
          }
          

          If you need the same value type from different Device a different sensor id can be used, the requestValue will then look like this:

          void requestValue(byte type, unsigned int id, byte sensorid)
          {
               MyMessage msgRequest(sensorid, V_CUSTOM);
               unsigned long msgData;
               msgData = type + ((unsigned long)id * 0x100); 
               send(msgRequest.set(msgData));
          }
          

          In the receive function "message.sensor" can be used to determine for which device a request was made

          1 Reply Last reply
          1
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          27

          Online

          11.7k

          Users

          11.2k

          Topics

          113.1k

          Posts


          Copyright 2025 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • MySensors
          • OpenHardware.io
          • Categories
          • Recent
          • Tags
          • Popular