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?
-
@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:
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.
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.
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.
-
@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.
-
@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:
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.