ESP8266 gateway with VeraPlus



  • OK, pardon my ignorance. I have read a bunch of the threads on the ESP8266 used with a sonoff, but I am still slightly confused. My confusion comes on the Vera side of this. So if I use the gateway code on the sonoff, how is the Vera able to see and control the device? In my setup, I just have a serial nRF24L01 gateway connected to the Vera. Does the Vera use it's internal wifi to talk to the devices? Can someone outline a simple relay command from the Vera controller to the sonoff and how it communicates to the sonoff node? If I wanted to do node to node control from an nRF24 node to an ESP node, how would I bridge the gap?


  • Hero Member

    @dbemowsk I have not used any sonoff devices but the ESP8266 in any case would need to be added to Vera as another Gateway so that you have 2 Gateways in Vera like this:

    0_1485492816991_2xMySVera.jpg

    This means that you then have also 2 separate MySensors networks but the ESP8266 would have no transport layer (NRF24L01+ or RFM69 or something else).

    The sonoff local features needs to be added to the Gateway code as local sensors and actuators.

    Since this setup forms 2 separate networks there is no way to send any control commands directly from the nRF24 node to an ESP node. You need to handle this part in Vera.

    I have not looked in to the sonoff device but if it was possible to add a nRF24 to it then you could actually create additional nodes to this network which could then control the ESP local sensors/actuator also. It would be much easier to make some logic in Vera to forward some commands though.



  • @korttoma Thanks for the reply. My question then is, if I have multiple sonoffs/ESP8266 devices, do I need to present each as it's own gateway?

    I currently have one of these wifi outlets that I bought from walmart.
    0_1485493898513_upload-61118b76-e0fc-44b1-b790-d4d9d6027cb0
    These too run from an ESP8266 chip. I hacked this one with ESP Easy firmware from letscontrolit.com and I installed the HTTP Switch plugin on the Vera.
    0_1485494221921_upload-fc2712bb-34d4-4e0f-b548-e498e5f21a0d
    I had to do some tweaking to the lua file for the plugin to get it to work. but I can turn a light on and off.

    My main reason for this post was to see if I would gain anything in switching it to a MySensors node instead since I have a number of other MySensors devices. If I have to create scenes or someother lua code on the Vera side to get the nodes to talk to each other, I may just stick with the ESP Easy firmware.


  • Hero Member

    @dbemowsk yes each ESP is presented as another Gateway in Vera if you use the ESP Gateway sketch (currently this is the only MySensors implementation available). I say stick with the ESP Easy firmware since you gain nothing by using the MySensors ESP gateway implementation.

    Unless you can come up with something better ;)



  • @korttoma In that case, I agree. Base on what you are saying I think I would be better off with the ESP Easy firmware all around because if I am correct, Vera would show 2 objects for every ESP. Both the gateway device and the sensor device. With the ESP Easy I would just create another HTTP Switch. I wouldn't have to deal with the extra gateway object fort each one.

    I truly appreciate your feedback.


  • Hero Member

    @dbemowsk you would actually get 3 objects per ESP using the MySensors implementation.
    Gateway, Node 0 and Switch.



  • @korttoma Ahhhh, yes, I forgot the node object. That solidifies my decision even more. I just have a few more tweaks to figure out with the HTTP Switch code to make it a bit more flexible with ESP Easy. The biggest being how to define a variable for setting the GPIO pin under the advanced section of the device, and then figuring out how to access that variable in the lua code. Right now I have GPIO 15 hard coded in the lua file (L_HttpSwitch1.lua) as the pin to control the relay. The problem in that is that when I get the sonoffs, if they use a different GPIO pin to control the relays than the devices that I bought at walmart, that might be a problem. I just need to learn more about coding an app for Vera.



  • @dbemowsk said in ESP8266 gateway with VeraPlus:

    L_HttpSwitch1.lua

    @dbemowsk Can you share your L_HttpSwitch1.lua please.



  • @camadort My appologies for the INSANELY late response to this. Not sure how I missed this. I am not sure if you are the one that just sent me an email requesting this, but here is more information.

    The plugin that I have installed that this modified file originates from is the "HTTP Switch (WiFi Switch)" plugin. The icon for the plugin looks like this:
    0_1498853761585_upload-de7bc467-3966-48df-a3c6-21197b99327f
    It has been a while since I made the changes, so there may be a few other file changes that you need besides just the lua file for setting the GPIO pin. Here are my files:

    L_HttpSwitch1.Lua

    	local HS_SID = "urn:mios-nullx8-com:serviceId:HttpSwitch1"
    	local HAD_SID = "urn:micasaverde-com:serviceId:HaDevice1"	
    	local DEFAULT_ADDRESS = "127.0.0.1"
    	
    
    	-- just a function to decode (decode only) json responses
    	function decode_json(json)
    		if (not json) then 
    			return nil
    		end
    		local str = {} 
    		local escapes = { r='\r', n='\n', b='\b', f='\f', t='\t', Q='"', ['\\'] = '\\', ['/']='/' } 
    		json = json:gsub('([^\\])\\"', '%1\\Q'):gsub('"(.-)"', function(s) 
    			str[#str+1] = s:gsub("\\(.)", function(c) return escapes[c] end) 
    			return "$"..#str 	
    		end):gsub("%s", ""):gsub("%[","{"):gsub("%]","}"):gsub("null", "nil") 
    		json = json:gsub("(%$%d+):", "[%1]="):gsub("%$(%d+)", function(s) 
    		return ("%q"):format(str[tonumber(s)])
    		end)
    		return assert(loadstring("return "..json))()
    	end
    
    	local function log(text)
    		local id = PARENT_DEVICE or "unknown"
    			luup.log("HttpSwitch Plugin #" .. id .. " " .. text)
    		end
    	
    	local function InitSettings(address)
    		address = address or DEFAULT_ADDRESS
    		luup.variable_set(HS_SID, "Address", address, parentDevice)
    		luup.variable_set(HS_SID, "Poll", "120", parentDevice)
    		luup.variable_set(HS_SID, "GPIO", "1", parentDevice)
    		if (address == DEFAULT_ADDRESS) then
    			luup.variable_set(HS_SID, "LinkStatus", "SET IP!", parentDevice)
    		else
    			luup.variable_set(HS_SID, "LinkStatus", "...", parentDevice)
    		end
    		luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", "0", parentDevice)
    		luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Target", "0", parentDevice)
    
    		log("Initialized variable: 'Address' = " .. address)
    		log("Initialized variable: 'Target' = " .. Target)
    		log("Initialized variable: 'Status' = " .. Status)
    		log("Initialized variable: 'Poll' = " .. Poll)
    		
    		luup.task("Please restart Luup to initialize the plugin.", 1, "HttpSwitch Plugin", -1)
    		
    		return address
    	end
    	
    	local function readLocalSettings(parentDevice)
    	
    		local address = luup.variable_get(HS_SID, "Address", parentDevice)
    		local Poll = luup.variable_get(HS_SID, "Poll", parentDevice)
    		local GPIO = luup.variable_get(HS_SID, "GPIO", parentDevice)
    		
    		if (address == nil) then
    		log("Init Settings")
    			address = InitSettings(address)
    		end
    		
    		if (Poll == nil) then
    			Poll = InitSettings(address)
    		end
    		
    		if (GPIO == nil) then
    			GPIO = InitSettings(address)
    		end
    		
    		return address, Poll, GPIO
    		
    	end
    	
    	function GetRemoteStatus()
    		local address, Poll = readLocalSettings(parentDevice)
    		local GPIO = luup.variable_get(HS_SID, "GPIO", parentDevice)
    		--status command for ESP Easy
    		local url = "http://".. address .."/control?cmd=status,GPIO," .. GPIO
    		local status, result = luup.inet.wget(url,6)
    		
    		if status == 0 then
    			local data = decode_json(result)
    			local PowerState = data.state
    
    			luup.variable_set(HS_SID, "Status", PowerState, parentDevice)
    			luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", PowerState, parentDevice)
    			luup.variable_set(HS_SID, "LinkStatus", LinkStatus, parentDevice)
    		end
    		luup.call_delay ("GetRemoteStatus", Poll, "")
    	end
    	
    	function PingCheck()
    		local address, Poll = readLocalSettings(parentDevice)
    		pingcommand = "ping -c 1 " ..address
    		log("executing [ ping -c 1 " .. address .. " ]")
    		pingresponse = os.execute(pingcommand)
    		if (pingresponse == 0) then
    			luup.variable_set(HS_SID,"PingStatus","up",parentDevice)
    			luup.variable_set(HS_SID, "LinkStatus", "Online!", parentDevice)
    			log("Ping reply ")
    		else
    			luup.variable_set(HS_SID,"PingStatus","down",parentDevice)
    			luup.variable_set(HS_SID, "LinkStatus", "Offline!", parentDevice)
    			log("No ping reply ")
    		end
    		PingInterval = luup.variable_get(HS_SID,"Poll", parentDevice)
    		luup.call_delay("PingCheck", Poll, "")
    	end
    	
    	function main(parentDevice)
    		--
    		-- Note these are "pass-by-Global" values that refreshCache will later use.
    		--
    		PARENT_DEVICE = parentDevice
    
    		log("starting up..")
    		
    		luup.variable_set(HAD_SID, "LastUpdate", os.time(os.date('*t')), parentDevice)
    		luup.variable_set(HAD_SID, "Configured", "1", parentDevice)
    	  
    		--
    		-- Validate that the Address/Delay are configured in Vera, otherwise this
    		-- code wont work.
    		--
    		local address = readLocalSettings(parentDevice)
    		local Poll = readLocalSettings(parentDevice)
    		if (address == nil) then
    			log("could not be started.")
    			log("adress value " .. address)
    			luup.set_failure(true, parentDevice)
    			return false
    		end
          
    		luup.call_delay ("GetRemoteStatus", 30, "")
    		luup.call_delay("PingCheck", 10, "")
    		return true
    	end
    	
    	
    	local function FlipOn()
    		local address = readLocalSettings(parentDevice)
    		local GPIO = luup.variable_get(HS_SID, "GPIO", parentDevice)
        		luup.inet.wget("http://" .. address .. "/control?cmd=gpio," .. GPIO .. ",1")
    		luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", "1", parentDevice)
            	luup.variable_set(HS_SID, "Status", "1", parentDevice)
    		GetRemoteStatus()
    	end	
    	
    	local function FlipOff()
    		local address = readLocalSettings(parentDevice)
    		local GPIO = luup.variable_get(HS_SID, "GPIO", parentDevice)
        		luup.inet.wget("http://" .. address .. "/control?cmd=gpio," .. GPIO .. ",0")
    		luup.variable_set("urn:upnp-org:serviceId:SwitchPower1", "Status", "0", parentDevice)
            	luup.variable_set(HS_SID, "Status", "0", parentDevice)
    		GetRemoteStatus()
    	end
    
    -- last line 
    

    D_HttpSwitch1.json

    {
       "flashicon":"icons/Binary_Light.png",
       "imgIconBody":"",
       "imgIconDimmable":"",
       "imgIconTurnable":"",
       "imgIconMin":"icons/Binary_Light_0.png",
       "imgIconMax":"icons/Binary_Light.png",
       "halloIconsDir":"pics/hallo",
       "state_icons":[
          {
             "img":"binary_light_off.png",
             "conditions":[
                {
                   "service":"urn:upnp-org:serviceId:SwitchPower1",
                   "variable":"Status",
                   "operator":"==",
                   "value":0,
                   "subcategory_num":0
                }
             ]
          },
          {
             "img":"binary_light_on.png",
             "conditions":[
                {
                   "service":"urn:upnp-org:serviceId:SwitchPower1",
                   "variable":"Status",
                   "operator":"==",
                   "value":1,
                   "subcategory_num":0
                }
             ]
          }
       ],
       "x":"2",
       "y":"4",
       "inScene":"1",
       "DisplayStatus":{
          "Service":"urn:upnp-org:serviceId:SwitchPower1",
          "Variable":"Status",
          "MinValue":"0",
          "MaxValue":"1"
       },
       "doc_url":{
          "doc_language":1,
          "doc_manual":1,
          "doc_version":1,
          "doc_platform":0,
          "doc_page":"devices"
       },
       "ToggleButton":1,
       "Tabs":[
          {
             "Label":{
                "lang_tag":"tabname_control",
                "text":"Control"
             },
             "Position":"0",
             "TabType":"flash",
             "ControlGroup":[
                {
                   "id":"1",
                   "isSingle":"1",
                   "scenegroup":"1"
                },
                {
                   "id":"2",
                   "isSingle":"1",
                   "scenegroup":"1"
                },
                {
                   "id":"3",
                   "isSingle":"1",
                   "scenegroup":"2"
                },
                {
                   "id":"4",
                   "isSingle":"1",
                   "scenegroup":"3"
                }
             ],
             "SceneGroup":[
                {
                   "id":"1",
                   "top":"2",
                   "left":"0",
                   "x":"2",
                   "y":"1"
                },
                {
                   "id":"2",
                   "top":"-0.9",
                   "left":"-1.13",
                   "x":"2",
                   "y":"1"
                },
                {
                   "id":"3",
                   "top":"-0.4",
                   "left":"-1.13",
                   "x":"2",
                   "y":"1"
                }
             ],
             "Control":[
                {
                   "ControlGroup":"2",
                   "ControlType":"button",
                   "top":"0",
                   "left":"1",
                   "Label":{
                      "lang_tag":"cmd_on",
                      "text":"On"
                   },
                   "Display":{
                      "Service":"urn:upnp-org:serviceId:SwitchPower1",
                      "Variable":"Status",
                      "Value":"1",
                      "Top":20,
                      "Left":150,
                      "Width":75,
                      "Height":20
                   },
                   "Command":{
                      "Service":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                      "Action":"On",
                      "Parameters":[
                         {
                            "Name":"newTargetValue",
                            "Value":"1"
                         }
                      ]
                   }
                },
                {
                   "ControlGroup":"1",
                   "ControlType":"variable",
                   "top":"-1",
                   "left":"0",
                   "text_align":"left",
                   "Display":{
                      "Service":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                      "Variable":"LinkStatus",
                      "Top":21,
                      "Left":2,
                      "Width":240,
                      "Height":20
                   }
                },
                {
                   "ControlGroup":"1",
                   "ControlType":"button",
                   "top":"0",
                   "left":"0",
                   "Label":{
                      "lang_tag":"cmd_off",
                      "text":"Off"
                   },
                   "Display":{
                      "Service":"urn:upnp-org:serviceId:SwitchPower1",
                      "Variable":"Status",
                      "Value":"0",
                      "Top":20,
                      "Left":50,
                      "Width":75,
                      "Height":20
                   },
                   "Command":{
                      "Service":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                      "Action":"Off",
                      "Parameters":[
                         {
                            "Name":"newTargetValue",
                            "Value":"0"
                         }
                      ]
                   }
                }
             ]
          },
          {
             "Label":{
                "lang_tag":"advanced",
                "text":"Advanced"
             },
             "Position":"2",
             "TabType":"javascript",
             "ScriptName":"shared.js",
             "Function":"advanced_device"
          },
          {
             "Label":{
                "lang_tag":"notifications",
                "text":"Notifications"
             },
             "Position":"5",
             "TabType":"javascript",
             "ScriptName":"shared.js",
             "Function":"device_notifications"
          }
       ],
       "sceneList":{
          "group_1":{
             "cmd_1":{
                "label":"ON",
                "serviceId":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                "action":"On",
                "arguments":{
                   "newTargetValue":"1"
                },
                "display":{
                   "service":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                   "variable":"Status",
                   "value":"1"
                }
             },
             "cmd_2":{
                "label":"OFF",
                "serviceId":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                "action":"Off",
                "arguments":{
                   "newTargetValue":"0"
                },
                "display":{
                   "service":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
                   "variable":"Status",
                   "value":"0"
                }
             }
          }
       },
       "eventList2":[
          {
             "id":1,
             "label":{
                "lang_tag":"a_device_is_turned_on_off",
                "text":"A device is turned on or off"
             },
             "serviceId":"urn:mios-nullx8-com:serviceId:HttpSwitch1",
             "argumentList":[
                {
                   "id":1,
                   "dataType":"boolean",
                   "defaultValue":"1",
                   "allowedValueList":[
                      {
                         "Off":"0",
                         "HumanFriendlyText":{
                            "lang_tag":"hft_device_turned_off",
                            "text":"_DEVICE_NAME_ is turned off"
                         }
                      },
                      {
                         "On":"1",
                         "HumanFriendlyText":{
                            "lang_tag":"hft_device_turned_on",
                            "text":"_DEVICE_NAME_ is turned on"
                         }
                      }
                   ],
                   "name":"Status",
                   "comparisson":"=",
                   "prefix":{
                      "lang_tag":"which_mode",
                      "text":"Which mode"
                   },
                   "suffix":{
    
                   }
                }
             ]
          }
       ],
       "DeviceType":"urn:mios-nullx8-com:device:HttpSwitch:1"
    }
    

    D_HttpSwitch1.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <root xmlns="urn:schemas-upnp-org:device-1-0">
       <specVersion>
          <major>1</major>
          <minor>13</minor>
       </specVersion>
       <device>
          <deviceType>urn:upnp-org:serviceId:SwitchPower1</deviceType>
          <staticJson>D_HttpSwitch1.json</staticJson>
          <friendlyName>KK-SP3 Smart WiFi Switch</friendlyName>
          <manufacturer>nullx8</manufacturer>
          <protocol>cr</protocol>
          <handleChildren>0</handleChildren>
          <serviceList>
             <service>
                <serviceType>urn:mios-nullx8-com:service:HttpSwitch:1</serviceType>
                <serviceId>urn:mios-nullx8-com:serviceId:HttpSwitch1</serviceId>
                <SCPDURL>S_HttpSwitch1.xml</SCPDURL>
             </service>
             <service>
                <serviceType>urn:schemas-upnp-org:service:SwitchPower:1</serviceType>
                <serviceId>urn:upnp-org:serviceId:SwitchPower1</serviceId>
                <SCPDURL>S_SwitchPower1.xml</SCPDURL>
             </service>
          </serviceList>
          <implementationList>
             <implementationFile>I_HttpSwitch1.xml</implementationFile>
          </implementationList>
       </device>
    </root>
    


  • @dbemowsk Thanks!



  • @camadort Let me know if you have trouble. Someone else was emailing me about this issue and they mentioned this thread. I thought it was you, but it wasn't. I don't know if he got his going or not.

    Anyways, his email to me prompted me to do a blog post on my website about this topic.
    http://dan.bemowski.info/2017/07/04/using-a-sonoff-with-espeasy-and-a-vera-home-controller/
    I have a link to the zip file with the three HttpSwitch files. These files have exactly what I posted above, but they are the actual files pulled from my vera in the event that you have trouble creating your own with the above code. It also has instructions on configuring both the device and the Vera side of things.


Log in to reply
 

Looks like your connection to MySensors Forum was lost, please wait while we try to reconnect.