Ezlo Plugin - Network Error

Hi,

I’ve starting learning how to write plugins for the Ezlo platform. It’s been a while since I wrote the Yamaha Receiver plugin many years ago.

I followed all the documentation I could find (Ezlo Plugin Guide, LUA API, HUB API) and I was able to get a very basic plugin structure loaded on my Ezlo Plus.

When calling a test action that makes a network call, I’m getting the following error (in the ha-luad.log):

ERROR: LuaInterpreter: Couldn’t run a Lua code: [string “HUB:samsung-tv-serial/scripts/turn_tv_on”]:21: fail to send data to a connection with handle (1) : AsyncSocket: Resource temporarily unavailable
stack traceback:
=[C]
HUB:samsung-tv-serial/scripts/turn_tv_on:21
WARN : LuaAddon: a script: HUB:samsung-tv-serial/scripts/turn_tv_on has been terminated abnormally

Line 21 is the network.send() command, constructed as per the LUA API documentation:

conn = network.send( hndl, “hello world” )

I know the receiving device (a Digi Portserver) is receiving the connection as it shows up in it’s GUI as a connection established by the Plus’ ip address.

Any ideas as what to look at next to figure out what’s causing the error?
I’ve looked at all the logs in /tmp/log/firmware and didn’t find anything. Is there another way to surface more error details?
Is the “network” functionality just not ready yet on the Ezlo platform?

Thanks,
dgdev

2 Likes

Hi @dgdev,

One thing that is fundamentally different than with Vera is that on the Ezlo FW if fully event driven and your Lua code gets loaded and unloaded for each call. So if you have variable values to keep between events you will have to store them using the storage module. In your case it may be that network handle. Nearly all you will need to handle an event will be in the event data btw.

I did use the network module after the first release to do simple http as that bit was not included back then. So then it worked. I have not used it since there is http support, so you also may have stumbled on a bug.

Cheers Rene

1 Like

Hi @dgdev,
Its really great you started learning how to write plugins for the Ezlo platform.
Let me invite you to the skype group with developers and guys from community.
Sent you message in pm.
Can you share please the plugin you created for check it.

1 Like

Thanks for the feedback @reneboer and @Oleh. I’ve published my very simple test plugin here:
https://github.com/dgdevca/vera-samsung-tv-serial

There’s only one script I’m testing with and it’s pretty self-contained: /scripts/turn_tv_on.lua

Any ideas?

@dgdev,
Network module is asynchronous. You should subscribe to network events (either with network.set_handler or network.subscribe). Also need to send data in events handler script when you receive OUT (it’s possible to write to a TCP socket handle) event.

1 Like

Hi @dgdev,

Here some code used that might get you started:
This in startup.lua script, this runs when the plugin starts only.

		local net = require "network"

		if storage.exists( "conn" ) then storage.delete( "conn" ) end
		net.subscribe( "HUB:rb_plug/scripts/network_event" )

		local conn = net.connect{ ip = "10.50.18.8", port = "2001", connection_type = "TCP" }
		if not conn then
			print("Failed to connect -- WHY?")
		else
			print("CONNECTED! Connection is %1", conn)
		end

This is in network event. As you can see you can only send data when the CONNECTED event is ready.

--[[
	http_network_event.lua
--]]

local function handle_network_event( event )
	if event.event == "network" then
		-- We got a network event. Only option really
		local network = require "network"
		local ev = event.data
		if ev.event_type == "io_activity" then
			-- It is an io event
			local ev = ev.event
			if ev.io_activity_type == "CONNECTED" then
			    -- build the serial command to send via the Digi PortServer
                checksum = 0xFF - (0x08 + 0x22 + 0x00 + 0x00 + 0x00 + 0x02) + 1
                command = string.char(0x08,0x22,0x00,0x00,0x00,0x02,checksum)
                print("samsung-tv-serial: Sending data: " .. command)
                -- Send the command.  Script errors out on the network.send
                network.send( ev.handle, command )
			elseif ev.io_activity_type == "FAILED_TO_CONNECT" then
				print("network.event connection failed for handle ", ev.handle)
			elseif ev.io_activity_type == "IN" then
				-- Just receive the data and write it to the log
				print("network.event inbound data: ", network.receive(ev.handle))
			elseif ev.io_activity_type == "CLOSED" then
				network.close(ev.handle )
				print("network.event closing connection: ", ev.handle)
			else	
				-- Log some other event.
				print("network.event unknown activity type: ", ev.io_activity_type)
			end
		else
			print("Unexpected event type in network_event: ", event.event)
		end
	else
		print("Unexpected event type in http_network_event: ", event.event)
	end	
end

handle_network_event(...)

Cheers Rene

1 Like

I was able to get it working with your help - I successfully turned the TV on. Thanks @Oleh and @reneboer!

My next challenge is to figure out how to structure the plugin to best handle all the different commands (power, input, volume, etc). The current event handler only issues the Power On command - I should obviously abstract that code base to handle all the different commands. More thought required before I proceed. :thinking: I’ll sleep on it…

1 Like

Best Home Automation shopping experience. Shop at getvera!

© 2020 Vera Control Ltd., All Rights Reserved. Terms of Use | Privacy Policy | Forum Rules