Author Topic: Automatically adjust the read value returned via serial connection ?  (Read 553 times)

Online akbooer

  • Master Member
  • *******
  • Posts: 5971
  • Karma: +258/-69
  • "Less is more"
Re: Automatically adjust the read value returned via serial connection ?
« Reply #15 on: June 23, 2018, 06:10:50 am »
Yes.  You need either:

Code: [Select]
local result = string.match (data, "%o%d+%s%i%d+") or "error"

or

Code: [Select]
local result = data:match ("%o%d+%s%i%d+") or "error"
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Automatically adjust the read value returned via serial connection ?
« Reply #16 on: June 23, 2018, 06:03:21 pm »
Thanks @akbooer

Is there a better way I can read each line, and then capture the key information that each line provides?

Code: [Select]
function send_command_to_hdmi_matrix(...)
   local socket = require("socket")
   host = "192.168.1.147"
   c = assert(socket.connect(host, 4002))
   c:settimeout(5)
   -- read matrix status
   local sres, serr = c:send(string.char(...))
   print("Send:", sres, serr)
   local data1, rerr1 = c:receive('*l')
   local data2, rerr2 = c:receive('*l')
   local data3, rerr3 = c:receive('*l')
   local data4, rerr4 = c:receive('*l')
   local data5, rerr5 = c:receive('*l')
   local line1 = string.match (data1, "%o%d+%s%i%d+") or "error"
   local line2 = string.match (data2, "%o%d+%s%i%d+") or "error"
   local line3 = string.match (data3, "%o%d+%s%i%d+") or "error"
   local line4 = string.match (data4, "%o%d+%s%i%d+") or "error"
   local line5 = string.match (data5, "%o%d+%s%i%d+") or "error"
   print ("line 1:", data1, rerr1)
   print ("line 2:", data2, rerr2)
   print ("line 3:", data3, rerr3)
   print ("line 4:", data4, rerr4)
   print ("line 5:", data5, rerr5)
   print ("" ..line1)
   print ("" ..line2)
   print ("" ..line3)
   print ("" ..line4)
   print ("" ..line5)
   c:close()
   return line2, line3    -- return the result can I store more than one to use elsewhere?
end

Print output

Quote
Send:     6     
line 1:     read Command OK     
line 2:     o01 i02 video on audio on CEC off     
line 3:     o02 i01 video on audio on CEC off     
line 4:     o03 i01 video on audio on CEC off     
line 5:     o04 i01 video on audio on CEC off     
error     
o01 i02     
o02 i01     
o03 i01     
o04 i01   


The objective is to to capture the key information from each line and translate it with this function.


Code: [Select]
local function interpret_reply_from_hdmi_matrix(status)
  local message = {
-- error
["error"] = "Something else happened, it likely failed",
-- Output 1
["o01 i01"] = "Ouput 1 is showing input 1",
["o01 i02"] = "Ouput 1 is showing input 2",
["o01 i03"] = "Ouput 1 is showing input 3",
["o01 i04"] = "Ouput 1 is showing input 4",
-- Output 2
["o02 i01"] = "Ouput 2 is showing input 1",
["o02 i02"] = "Ouput 2 is showing input 2",
["o02 i03"] = "Ouput 2 is showing input 3",
["o02 i04"] = "Ouput 2 is showing input 4",
}
  return message[status] or "Unexpected status code received"
end


« Last Edit: June 23, 2018, 07:21:25 pm by parkerc »

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Automatically adjust the read value returned via serial connection ?
« Reply #17 on: June 24, 2018, 04:42:34 am »
Ok, here is my finished code, a bit rough  - but it works and  makes a call to the ATEN hdmi matrix for its status, extracting the first 5 lines. - which it then translates  and  presents the resulting information  into the UI5 messaging/task window. (Once again thanks to @akbooer for the basis of this workflow)

Code: [Select]
function send_command_to_hdmi_matrix(...)
local socket = require("socket")
host = "192.168.1.147"
c = assert(socket.connect(host, 4002))
c:settimeout(5)
-- read matrix status
local sres, serr = c:send(string.char(...))
print("Send:", sres, serr)
local data1, rerr1 = c:receive('*l')
local data2, rerr2 = c:receive('*l')
local data3, rerr3 = c:receive('*l')
local data4, rerr4 = c:receive('*l')
local data5, rerr5 = c:receive('*l')
local line1 = string.match (data1, "%u%a+%s%a+") or "error"
local line2 = string.match (data2, "%o%d+%s%i%d+") or "error"
local line3 = string.match (data3, "%o%d+%s%i%d+") or "error"
local line4 = string.match (data4, "%o%d+%s%i%d+") or "error"
local line5 = string.match (data5, "%o%d+%s%i%d+") or "error"
print ("line 1:", data1, rerr1)
print ("line 2:", data2, rerr2)
print ("line 3:", data3, rerr3)
print ("line 4:", data4, rerr4)
print ("line 5:", data5, rerr5)
print ("" ..line1)
print ("" ..line2)
print ("" ..line3)
print ("" ..line4)
print ("" ..line5)
c:close()
return line2, line3, line4, line5    -- return the result
end


local function interpret_reply_from_hdmi_matrix(status)
  local message = {
-- error
["error"] = "Something else happened, it likely failed",
-- Output 1
["o01 i01"] = "Ouput 1 is showing input 1",
["o01 i02"] = "Ouput 1 is showing input 2",
["o01 i03"] = "Ouput 1 is showing input 3",
["o01 i04"] = "Ouput 1 is showing input 4",
-- Output 2
["o02 i01"] = "Ouput 2 is showing input 1",
["o02 i02"] = "Ouput 2 is showing input 2",
["o02 i03"] = "Ouput 2 is showing input 3",
["o02 i04"] = "Ouput 2 is showing input 4",
-- Output 3
["o03 i01"] = "Ouput 3 is showing input 1",
["o03 i02"] = "Ouput 3 is showing input 2",
["o03 i03"] = "Ouput 3 is showing input 3",
["o03 i04"] = "Ouput 3 is showing input 4",
-- Output 4
["o04 i01"] = "Ouput 4 is showing input 1",
["o04 i02"] = "Ouput 4 is showing input 2",
["o04 i03"] = "Ouput 4 is showing input 3",
["o04 i04"] = "Ouput 4 is showing input 4",
}
  return message[status] or "Unexpected status code received"
end

-- here's the message in the UI5 panel
local function present_results_of_hdmi_matrix_interaction(result)
  print (result)
  local handle = luup.task("" .. result, 1, "ATEN 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 the main 'workflow'
local l1, l2, l3, l4 = send_command_to_hdmi_matrix(0x72,0x65,0x61,0x64,0x0d,0x0a)
local message1 = interpret_reply_from_hdmi_matrix(l1)
local message2 = interpret_reply_from_hdmi_matrix(l2)
local message3 = interpret_reply_from_hdmi_matrix(l3)
local message4 = interpret_reply_from_hdmi_matrix(l4)
present_results_of_hdmi_matrix_interaction(message1)
present_results_of_hdmi_matrix_interaction(message2)
present_results_of_hdmi_matrix_interaction(message3)
present_results_of_hdmi_matrix_interaction(message4)


print (l1, l2, l3, l4)
print (message1, message2, message3, message4)

Here is the Lua Test output, happy to hear any recommendations on code improvement - Im also looking to see if I can create a basic visual representation  of each output/input e.g [1] [2] [1] [1]

Quote
LuaTest 1.7

Lua file: /nas/luatest/aten_matrix-read-v2.lua

Results
No errors
Runtime: 124.0 ms
Code returned: nil

Print output
Send:     6     
line 1:     read Command OK     
line 2:     o01 i02 video on audio on CEC off     
line 3:     o02 i01 video on audio on CEC off     
line 4:     o03 i01 video on audio on CEC off     
line 5:     o04 i01 video on audio on CEC off     
Command OK     
o01 i02     
o02 i01     
o03 i01     
o04 i01     
Ouput 1 is showing input 2     
Ouput 2 is showing input 1     
Ouput 3 is showing input 1     
Ouput 4 is showing input 1     
o01 i02     o02 i01     o03 i01     o04 i01     
Ouput 1 is showing input 2     Ouput 2 is showing input 1     Ouput 3 is showing input 1     Ouput 4 is showing input 1     

Code
   1   function send_command_to_hdmi_matrix(...)
   2        local socket = require("socket")
   3        host = "192.168.1.147"
   4        c = assert(socket.connect(host, 4002))
   5        c:settimeout(5)
   6        -- read matrix status
   7        local sres, serr = c:send(string.char(...))
   8        print("Send:", sres, serr)
   9        local data1, rerr1 = c:receive('*l')
  10        local data2, rerr2 = c:receive('*l')
  11        local data3, rerr3 = c:receive('*l')
  12        local data4, rerr4 = c:receive('*l')
  13        local data5, rerr5 = c:receive('*l')
  14        local line1 = string.match (data1, "%u%a+%s%a+") or "error"
  15        local line2 = string.match (data2, "%o%d+%s%i%d+") or "error"
  16        local line3 = string.match (data3, "%o%d+%s%i%d+") or "error"
  17        local line4 = string.match (data4, "%o%d+%s%i%d+") or "error"
  18        local line5 = string.match (data5, "%o%d+%s%i%d+") or "error"
  19        print ("line 1:", data1, rerr1)
  20        print ("line 2:", data2, rerr2)
  21        print ("line 3:", data3, rerr3)
  22        print ("line 4:", data4, rerr4)
  23        print ("line 5:", data5, rerr5)
  24        print ("" ..line1)
  25        print ("" ..line2)
  26        print ("" ..line3)
  27        print ("" ..line4)
  28        print ("" ..line5)
  29        c:close()
  30        return line2, line3, line4, line5    -- return the result
  31   end
  32   
  33   
  34   local function interpret_reply_from_hdmi_matrix(status)
  35     local message = {
  36   -- error
  37   ["error"] = "Something else happened, it likely failed",
  38   -- Output 1
  39   ["o01 i01"] = "Ouput 1 is showing input 1",
  40   ["o01 i02"] = "Ouput 1 is showing input 2",
  41   ["o01 i03"] = "Ouput 1 is showing input 3",
  42   ["o01 i04"] = "Ouput 1 is showing input 4",
  43   -- Output 2
  44   ["o02 i01"] = "Ouput 2 is showing input 1",
  45   ["o02 i02"] = "Ouput 2 is showing input 2",
  46   ["o02 i03"] = "Ouput 2 is showing input 3",
  47   ["o02 i04"] = "Ouput 2 is showing input 4",
  48   -- Output 3
  49   ["o03 i01"] = "Ouput 3 is showing input 1",
  50   ["o03 i02"] = "Ouput 3 is showing input 2",
  51   ["o03 i03"] = "Ouput 3 is showing input 3",
  52   ["o03 i04"] = "Ouput 3 is showing input 4",
  53   -- Output 4
  54   ["o04 i01"] = "Ouput 4 is showing input 1",
  55   ["o04 i02"] = "Ouput 4 is showing input 2",
  56   ["o04 i03"] = "Ouput 4 is showing input 3",
  57   ["o04 i04"] = "Ouput 4 is showing input 4",
  58   }
  59     return message[status] or "Unexpected status code received"
  60   end
  61   
  62   -- here's the message in the UI5 panel
  63   local function present_results_of_hdmi_matrix_interaction(result)
  64     print (result)
  65     local handle = luup.task("" .. result, 1, "ATEN HDMI Matrix", -1)
  66           luup.call_delay("clearTaskMsg",5,handle)
  67   end
  68   
  69   function clearTaskMsg(strHandle)  -- this HAS to be non-local for call_delay to work
  70     luup.task("",4,"",tonumber(strHandle))
  71   end
  72   
  73   -- here's the main 'workflow'
  74   local l1, l2, l3, l4 = send_command_to_hdmi_matrix(0x72,0x65,0x61,0x64,0x0d,0x0a)
  75   local message1 = interpret_reply_from_hdmi_matrix(l1)
  76   local message2 = interpret_reply_from_hdmi_matrix(l2)
  77   local message3 = interpret_reply_from_hdmi_matrix(l3)
  78   local message4 = interpret_reply_from_hdmi_matrix(l4)
  79   present_results_of_hdmi_matrix_interaction(message1)
  80   present_results_of_hdmi_matrix_interaction(message2)
  81   present_results_of_hdmi_matrix_interaction(message3)
  82   present_results_of_hdmi_matrix_interaction(message4)
  83   
  84   
  85   print (l1, l2, l3, l4)
  86   print (message1, message2, message3, message4)
« Last Edit: June 24, 2018, 04:51:55 am by parkerc »

Online akbooer

  • Master Member
  • *******
  • Posts: 5971
  • Karma: +258/-69
  • "Less is more"
Re: Automatically adjust the read value returned via serial connection ?
« Reply #18 on: June 24, 2018, 05:12:28 am »
Glad it works. 

It's normal to use functions and loops to cut down on the repetition, but it's OK.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Automatically adjust the read value returned via serial connection ?
« Reply #19 on: June 24, 2018, 06:37:31 am »
Thanks @akbooer

Please could you give me an example of what would improve/ change within my code above via a function/loop?

Online akbooer

  • Master Member
  • *******
  • Posts: 5971
  • Karma: +258/-69
  • "Less is more"
Re: Automatically adjust the read value returned via serial connection ?
« Reply #20 on: June 24, 2018, 08:53:33 am »
Please could you give me an example of what would improve/ change within my code above via a function/loop?

Well, I haven't tested it, but I'm imagining something like this:

Code: [Select]
local socket = require("socket")

local function send_command_to_hdmi_matrix(...)
local host = "192.168.1.147"
local c = assert(socket.connect(host, 4002))
c:settimeout(5)
-- read matrix status
local sres, serr = c:send(string.char(...))
print("Send:", sres, serr)
  local line = {}
  for i = 1,5 do
    local data, rerr = c:receive('*l')
    print ("line " ..i, data, rerr)
    local o,i = string.match (data, "o(%d+)%si(%d+)")
    if o and i then line[tonumber(o)] = tonumber(i) end
  end
c:close()
return line    -- return the result
end

-- here's the message in the UI5 panel
local function present_results_of_hdmi_matrix_interaction(result)
  print (result)
  local handle = luup.task("" .. result, 1, "ATEN 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 the main 'workflow'
local line = "Output %d is showing input %d"
local info = send_command_to_hdmi_matrix(0x72,0x65,0x61,0x64,0x0d,0x0a)
for output, input in pairs (info) do
  local message = line: format (output, input)
  present_results_of_hdmi_matrix_interaction(message)
end
« Last Edit: June 24, 2018, 06:09:09 pm by akbooer »
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline parkerc

  • Sr. Hero Member
  • ******
  • Posts: 2411
  • Karma: +33/-45
  • Life Moves Pretty Fast....
Re: Automatically adjust the read value returned via serial connection ?
« Reply #21 on: June 24, 2018, 02:50:28 pm »
Wow, it works - and its so much shorter and more compact than mine.. (many thanks for doing that)

Ill try to see if I can understand the code you?ve used and the approach youve taken