Author Topic: Act on response from usb to serial device command.  (Read 709 times)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #15 on: September 08, 2017, 10:37:50 am »
I'm not sure that this very iterative approach is quite the way forward.

I'm just a simple man, with limited (bit thankfully improving) Lua abilities - i'm not sure what is the best way - step by step felt the best :)

The code structure we're now discussing has evolved quite a bit from where I started - which is good as it helps me to learn. But it must be painful for everyone else reading this thread :)

Tell you what - I'll try and pull the whole thing together (and sadly I only get pocket of time to focus on tweaking things on my Vera due to myjob) - I will try to keep it simpler too for now and look to make a new connection every time.
« Last Edit: September 08, 2017, 10:52:56 am by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #16 on: September 08, 2017, 11:41:35 am »
Ok, I think I have all the elements now, I'm just not able to link/pass elements between the functions - Help :-(

To try and keep this simple - the workflow aims to be  - 1) HDMI Matrix command sent, 2) response from matrix captured/assessed, and 3) appropriate message presented.

Code: [Select]
local function send_command_to_hdmi_matrix(...)
   local socket = require("socket")
   host = "192.168.1.204"
   c = assert(socket.connect(host, 4002))
   c:settimeout(5)
   local sres, serr = c:send(string.char(...))
   local data, rerr = c:receive(205)
   local result = data: match "Status code:(%d+)" or "error"
   print ("Receive:", data, rerr)
   print ("" ..result)
   c:close()
end

local function interpret_reply_from_hdmi_matrix()
   message = {
     ["error"] = "Something else happened, it likely failed",
     ["100011111110101"] = "Input 1 was selected successfully for Output A",
     ["100021111110101"] = "Input 2 was selected successfully for Output A",
     ["100031111110101"] = "Input 3 was selected successfully for Output A",
     ["100041111110101"] = "Input 4 was selected successfully for Output A",
     ["100024231110101"] = "Port scan completed successfully",
     -- extend this with new codes when needed
   }
end

local function present_results_of_hdmi_matrix_interaction()

   print (message[result] or "Unexpected status code received")

   local handle = luup.task("Octava HDMI Matrix: " .. result, 1, "Vera", -1)
        luup.call_delay("clearTaskMsg",2,handle)
   
-- Help - I need the luup.task to use the text that's looked up via the interpret_reply_from_hdmi_matrix function e.g ""Input 1 was selected successfully for Output A","

end

local function clearTaskMsg(strHandle)
        luup.task("",4,"",tonumber(strHandle))
end


send_command_to_hdmi_matrix(0x02,0x32,0x31,0x32,0x03)
« Last Edit: September 08, 2017, 11:46:29 am by parkerc »

Online akbooer

  • Master Member
  • *******
  • Posts: 5233
  • Karma: +226/-67
  • "Less is more"
Re: Act on response from usb to serial device command.
« Reply #17 on: September 08, 2017, 12:40:03 pm »
Well, nearly there.  You just had to link it all together with the appropriate parameter passing...

Code: [Select]
local host = "192.168.1.204"
local port  = 4002

local socket = require("socket")


local function send_command_to_hdmi_matrix(...)
   local c = assert(socket.connect(host, port))
   c:settimeout(5)
   local sres, serr = c:send(string.char(...))
   local data, rerr = c:receive(205)
   local result = data: match "Status code:(%d+)" or "error"
   print ("Receive:", data, rerr)
   print ("" ..result)
   c:close()
   return result    -- return the result
end

local function interpret_reply_from_hdmi_matrix(status)
  local message = {
     ["error"] = "Something else happened, it likely failed",
     ["100011111110101"] = "Input 1 was selected successfully for Output A",
     ["100021111110101"] = "Input 2 was selected successfully for Output A",
     ["100031111110101"] = "Input 3 was selected successfully for Output A",
     ["100041111110101"] = "Input 4 was selected successfully for Output A",
     ["100024231110101"] = "Port scan completed successfully",
     -- extend this with new codes when needed
   }
  return message[status] or "Unexpected status code received"
end

local function present_results_of_hdmi_matrix_interaction(result)
  print (result)
  local handle = luup.task("Octava HDMI Matrix: " .. result, 1, "Vera", -1)
        luup.call_delay("clearTaskMsg",2,handle)
end

function clearTaskMsg(strHandle)  -- this HAS to be non-local for call_delay to work
  luup.task("",4,"",tonumber(strHandle))
end

-- here's your main 'workflow'

local status = send_command_to_hdmi_matrix(0x02,0x32,0x31,0x32,0x03)
local message = interpret_reply_from_hdmi_matrix(status)
present_results_of_hdmi_matrix_interaction(message)

-- done
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #18 on: September 08, 2017, 01:10:26 pm »
Wow !! - It works ... ;D  (Thanks so much)

I have to be honest, I'm struggling to understand how all the functions are connected, plus it looks like you have done it so it sort of reverse order ?

It seems you start off by calling the function called present_results_of_hdmi_matrix_interaction(message) outright  - which in turn calls the function assigned to 'message' which is interpret_reply_from_hdmi_matrix(status) - and then that calls the final function which has been assigned to 'status', and has the required attribute in it status = send_command_to_hdmi_matrix(0x02,0x32,0x31,0x32,0x03)

Am i close ?
« Last Edit: September 08, 2017, 01:31:07 pm by parkerc »

Online akbooer

  • Master Member
  • *******
  • Posts: 5233
  • Karma: +226/-67
  • "Less is more"
Re: Act on response from usb to serial device command.
« Reply #19 on: September 08, 2017, 01:37:54 pm »
No, not at all.

The functions, which can be defined in any order, are called by the sequence I labelled as your workflow, at the bottom of the code.

Definitely time to learn Lua programming properly by reading this: https://www.lua.org/pil/
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #20 on: September 08, 2017, 01:58:33 pm »
??? - I wish I was better at reading, i'm sadly not a text/book person :-(  I do my very best to dip in and out of specifc chapters in the Lua manaul, but the wording just grates on me, as I struggle to understand it all - so far I seem to learn better by experimenting and using real world testing/examples..

QQ - As the others in the workflow at the bottom start with 'local' - doesn't that me you are calling the present_results_of_hdmi_matrix_interaction() first ?
« Last Edit: September 08, 2017, 02:02:15 pm by parkerc »

Online akbooer

  • Master Member
  • *******
  • Posts: 5233
  • Karma: +226/-67
  • "Less is more"
Re: Act on response from usb to serial device command.
« Reply #21 on: September 08, 2017, 02:32:02 pm »
No, local has nothing to do with it.  Statements are executed in order (unlike some other languages, like Prolog.)

A function statement, is just the same.  In fact

Code: [Select]
function f(a)
 return 2*a
end

is actually just shorthand for

Code: [Select]
f = function (a)
 return 2*a
end

...a statement which defines what the function actually is.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #22 on: September 08, 2017, 02:44:39 pm »
OK, I think I understand - I had understood 'local' to be a way to make something easier to reference/call within your code - e.g to allocate a keyword to a retrievable variable or function.

What confused me was within the Workflow section, you had only applied 'local' to the beginning of 2 of the 3 functions, therefore I assumed the one that was not designated as local would be invoked, so would run first.

Code: [Select]
-- here's your main 'workflow'

local status = send_command_to_hdmi_matrix(0x02,0x32,0x31,0x32,0x03)
local message = interpret_reply_from_hdmi_matrix(status)
present_results_of_hdmi_matrix_interaction(message)

-- done

So I hope I have it - is what you're saying - that just the association of a 'local' reference word e.g status, message etc. will still result in it being executed ?

if that's the case, why were all 3 not designated as being local e.g

Code: [Select]
-- here's your main 'workflow'

local status = send_command_to_hdmi_matrix(0x02,0x32,0x31,0x32,0x03)
local message = interpret_reply_from_hdmi_matrix(status)
local results = present_results_of_hdmi_matrix_interaction(message)

-- done

Sorry - I really must be driving you crazy :-)
« Last Edit: September 08, 2017, 02:46:28 pm by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #23 on: September 08, 2017, 02:48:20 pm »
Would you believe it, it seems the Status Code: values can change after a port scan or if more than one output is in action, but thankfully I think I have found something that is more consistent within the response, so have updated the code.

Code: [Select]
local host = "192.168.1.204"
local port  = 4002

local socket = require("socket")


local function send_command_to_hdmi_matrix(...)
   local c = assert(socket.connect(host, port))
   c:settimeout(5)
   local sres, serr = c:send(string.char(...))
   local data, rerr = c:receive(205)
   local result = data: match "S(%d+)E" or "error"
   print ("Receive:", data, rerr)
   print ("" ..result)
   c:close()
   return result    -- return the result
end

local function interpret_reply_from_hdmi_matrix(status)
  local message = {
-- error
["error"] = "Something else happened, it likely failed",
-- Output A
["211"] = "Input 1 was selected successfully for Output A",
["212"] = "Input 2 was selected successfully for Output A",
["213"] = "Input 3 was selected successfully for Output A",
["214"] = "Input 4 was selected successfully for Output A",
-- Output B
["221"] = "Input 1 was selected successfully for Output B",
["222"] = "Input 2 was selected successfully for Output B",
["223"] = "Input 3 was selected successfully for Output B",
["224"] = "Input 4 was selected successfully for Output B",
-- Output C
["231"] = "Input 1 was selected successfully for Output C",
["232"] = "Input 2 was selected successfully for Output C",
["233"] = "Input 3 was selected successfully for Output C",
["234"] = "Input 4 was selected successfully for Output C",
-- Output D
["241"] = "Input 1 was selected successfully for Output D",
["242"] = "Input 2 was selected successfully for Output D",
["243"] = "Input 3 was selected successfully for Output D",
-- Port Scan
["001"] = "Port scan completed successfully",
-- LED OFF
["004"] = "Port scan completed successfully",
-- LED ON
["003"] = "Port scan completed successfully",
-- Power OFF
["006"] = "Port scan completed successfully",
-- Power ON
["005"] = "Port scan completed successfully",

}
  return message[status] or "Unexpected status code received"
end

local function present_results_of_hdmi_matrix_interaction(result)
  print (result)
  local handle = luup.task("" .. result, 1, "Octava HDMI Matrix", -1)
        luup.call_delay("clearTaskMsg",5,handle)
end

function clearTaskMsg(strHandle)  -- this HAS to be non-local for call_delay to work
  luup.task("",4,"",tonumber(strHandle))
end

-- here's your main 'workflow'
local status = send_command_to_hdmi_matrix(0x02,0x32,0x32,0x34,0x03)
local message = interpret_reply_from_hdmi_matrix(status)
present_results_of_hdmi_matrix_interaction(message)

-- done

It seems there are these SxxxE values returned too when a successful request is completed. So I have updated those within the code above. using this expression seems to work "local result = data: match "S(%d+)E" or "error""

Quote
LuaTest 1.5.2

Lua file: /nas/luatest/matrix-startup4.lua

Results
No errors
Runtime: 252.1 ms
Code returned: nil

Print output
Receive:     ????????
ser2net port 4002 device /dev/ttyUSB0 [9600 N81] (Debian GNU/Linux)

S224E

Status code:100014131110101

**Refer to Install Guide or FAQ (www.octavainc.com)for serial control protocol.
« Last Edit: September 08, 2017, 02:51:49 pm by parkerc »

Online akbooer

  • Master Member
  • *******
  • Posts: 5233
  • Karma: +226/-67
  • "Less is more"
Re: Act on response from usb to serial device command.
« Reply #24 on: September 08, 2017, 03:23:04 pm »
Quote
if that's the case, why were all 3 not designated as being local e.g

The first two were, the third does not return a result.  See my original code.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #25 on: September 08, 2017, 06:07:25 pm »
Quote
if that's the case, why were all 3 not designated as being local e.g

The first two were, the third does not return a result.  See my original code.


Ok, and by 'result' you mean that particular function did not generate anything that was needed by anything else , it was just a function to display the required notification message.?

I still need to get my head around how a function's argument/parameter () is used. It seems you can specify a value, call a local element or provide guidance on values you want. I've read this article (https://www.tutorialspoint.com/lua/lua_functions.htm) many times to help but it's a slow process. :)

Online jswim788

  • Hero Member
  • *****
  • Posts: 537
  • Karma: +29/-2
Re: Act on response from usb to serial device command.
« Reply #26 on: September 08, 2017, 06:22:08 pm »
Ok, and by 'result' you mean that particular function did not generate anything that was needed by anything else , it was just a function to display the required notification message.?
The usage of a function is up to you.  You can have a statement:
Code: [Select]
myFunc(var1, var2)Although you may have defined a return value for myFunc, here it is ignored.  You didn't put the return value in a variable.

Or you can have an expression:
Code: [Select]
result = myFunc(var1, var2)In this case, you do use the result, and it is put into the global variable named "result".  But likely you don't want to use a global variable, you want to use a local variable.  So now add the "local" to the result variable:
Code: [Select]
local result = myFunc(var1, var2)

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #27 on: September 10, 2017, 04:47:50 am »
Thanks for that @jswim788, (and also for everyone's else's patience on this)

Things are getting a bit clearer, but it's just not as easy as I had hoped it would be to grasp. :(. - It really is like learning another language   :)

It's perhaps the types of things you can put into the brackets/parentheses that confuses me. As it seems it can be a value e.g.(0x20, 0x30, 0x31), or it can been a reference word to a local variable or a function e.g  (deviceID) or it can have multiple references all comma separated e.g  (this, that, theother).

It's the rule of what to use where and when
« Last Edit: September 10, 2017, 04:58:12 am by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2364
  • Karma: +33/-45
  • Life Moves Pretty Fast....
    • Node Central
Re: Act on response from usb to serial device command.
« Reply #28 on: September 10, 2017, 05:08:16 am »
This is what I was asking previously.  If you want to make a new connection each time, you need the connect within the function.  I wouldn't use assert.  As it is you've got the variable 'host' undefined at the point it's used.

As a side learning point - If I wanted to have a permanent open connection with the HDMI Matrix, would this be the correct approach?  e.g move the assert socket connect out of the function and delete the close() request.

Code: [Select]
local host = "192.168.1.204"
local port  = 4002
local socket = require("socket")
local c = assert(socket.connect(host, port))

local function send_command_to_hdmi_matrix(...)
   local sres, serr = c:send(string.char(...))
   local data, rerr = c:receive(205)
   local result = data: match "S(%d+)E" or "error"
   print ("Receive:", data, rerr)
   print ("" ..result)
   return result    -- return the result
end

Online akbooer

  • Master Member
  • *******
  • Posts: 5233
  • Karma: +226/-67
  • "Less is more"
Re: Act on response from usb to serial device command.
« Reply #29 on: September 10, 2017, 05:21:51 am »
Basically, yes.

You may run into several problems, though:
  • your device may not actually keep the connection open
  • since you haven't read the whole of the output, you may not receive what you think

However, if a permanent connection does work, you could possibly abandon the direct use of sockets and use instead the luup.io functions.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P.
Razberry, MySensors Arduino, HomeWave, AltUI, DataYours, openLuup, ZWay, ZeroBrane Studio.