This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Sauna RS485 connection with LM
#1
Hi,
I want to send command for sauna control over RS485
   

Comand list



   




How need to look my command in LM?
Code:
123456
require('serial') port = serial.open('/dev/RS485-1', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) port:flush() log = port:write (info) port:close()
Reply
#2
Code:
12
port:write('set sauna on\r') port:write('set sauna val 70\r')
Reply
#3
This is correct that I done in resident  for reading:
Code:
1234567
require('serial') port = serial.open('/dev/RS485-1', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) port:flush() grp.write('32/2/2', port:write(('get sauna val\r'), 'uint16')) port:close()

   
Reply
#4
If you want to query status periodically then things get more complicated. You need to have a single resident script which will handle both reading and writing because you cannot have multiple scripts accessing serial port at the same time.

You also need to parse the response because the reply will contain some additional characters.
This should log raw response of temperature value.
Code:
123456789101112131415161718192021
function readack()   local line = {}   while true do     local char, err = port:read(1, 5)     if char == nil then       return nil, err     elseif char == ';' then       break     else       line[ #line + 1 ] = char     end   end   return table.concat(line) end port:write('get sauna val\r') res, err = readack() log(res, err)
Reply
#5
Ok connection is working maybe you know why I get not correct value?
   
Reply
#6
Evrithing is good its working code:

Code:
12345678910111213141516171819202122232425262728
require('serial') port = serial.open('/dev/RS485-1', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) port:flush() function readack()  local line = {}  while true do    local char, err = port:read(1, 5)    if char == nil then      return nil, err    elseif char == ';' then      break    else      line[ #line + 1 ] = char    end  end  return table.concat(line) end port:write('get sauna\r') res, err = readack() log(res, err) port:close()
Reply
#7
Hi.

I get response timeout when running this script in wiser knx. is there any difference for RS-485 port?

I´ve tested this script over here and also with
This:
Code:
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
require('serial') local port, errorMsg = serial.open('/dev/RS485', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) -- Kontrollera om porten öppnades framgångsrikt if not port then     log("Kunde inte öppna porten: " .. (errorMsg or "Okänt fel"))     return end port:flush() -- Funktion för att läsa svar från bastun local function readack()   local line = {}   while true do     local char, err = port:read(1, 5)     if char == nil then       return nil, err     elseif char == ';' then       break     else       table.insert(line, char)     end   end   return table.concat(line) end -- Kontrollera om bastun ska vara PÅ eller AV local bastuState = grp.getvalue('37/1/1') if bastuState then     port:write('set sauna on\r') else     port:write('set sauna off\r') end -- Ställ in bastutemperaturen baserat på KNX-gruppadressen, värde mellan 30-110 grader local temperature = grp.getvalue('37/1/3') port:write('set sauna val ' .. temperature .. '\r') -- Läs tillbaka värdet från bastun port:write('get sauna val\r') local res, err = readack() if res then     log("Sauna värde: " .. res)     grp.checkwrite('37/1/0', res-- Skriver bastustatus till angiven adress     grp.checkwrite('37/1/4', res-- Skriver tillbaka temperaturstatus till den nya gruppadressen else     log("Fel vid läsning av bastu värde: " .. (err or "Okänt fel")) end -- Stäng porten port:close()
Anone who can see something wrong in this script?
Reply
#8
Script should call readack() after every command (both set and get). But this won't cause last readack() to return timeout. Something is wrong on the communication level. Try swapping A/B and see if GND is connected.
Reply
#9
(06.10.2023, 12:43)admin Wrote: Script should call readack() after every command (both set and get). But this won't cause last readack() to return timeout. Something is wrong on the communication level. Try swapping A/B and see if GND is connected.

Thanks this helped.

Now runs thhis script and its working.
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
require('serial') local port, errorMsg = serial.open('/dev/RS485', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) if not port then     log("Kunde inte öppna porten: " .. (errorMsg or "Okänt fel"))     return end port:flush() -- Funktion för att läsa svar från bastun local function readack()   local line = {}   local crlf_received = false   while not crlf_received do     local char, err = port:read(1, 5)     if char == nil then       return nil, err     elseif char == '\r' then       -- Ignorerar CR och väntar på LF     elseif char == '\n' then       crlf_received = true     else       table.insert(line, char)     end   end   local response = table.concat(line)   if string.sub(response, -1) == ';' then     response = string.sub(response, 1, -2-- Ta bort semikolon i slutet   end   return response end -- Loggar och skickar kommandon till bastustyrningen, läser sedan svaret local function sendAndRead(command)     log("Skickat kommando: " .. command)     port:write(command .. '\r\n')     return readack() end -- Kontrollera om bastun ska vara PÅ eller AV och läs svar local bastuState = grp.getvalue('37/1/1') sendAndRead(bastuState and 'set sauna on' or 'set sauna off') -- Ställ in bastutemperaturen baserat på KNX-gruppadressen och läs svar local temperature = grp.getvalue('37/1/3') local tempResponse = sendAndRead('set sauna val ' .. temperature) if tempResponse then     log("Svar på temperaturinställning: " .. tempResponse)     -- Uppdatera KNX-gruppadressen med det utlästa värdet     grp.checkwrite('37/1/4', temperature) end -- Läs bastuns nuvarande status local currentStatus = sendAndRead('get sauna') if currentStatus then     local status = string.match(currentStatus, "SAUNA%s(%w+)")     if status then         log("Bastuns nuvarande status: " .. status)         local knxStatus = (status == "on") and 1 or 0         grp.checkwrite('37/1/0', knxStatus)     else         log("Kunde inte tolka bastuns nuvarande status från svaret: " .. currentStatus)     end end -- Stäng porten port:close()


Build on more functions for the sauna with following script and with the new one it does not work, is there any solution you can see?
Code:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
require('serial') local port, errorMsg = serial.open('/dev/RS485', { baudrate = 57600, parity = 'none', duplex = 'half', databits = 8, stopbits = 1 }) if not port then     log("Kunde inte öppna porten: " .. (errorMsg or "Okänt fel"))     return end port:flush() -- Funktion för att läsa svar från bastun local function readack()   local line = {}   local crlf_received = false   while not crlf_received do     local char, err = port:read(1, 5)     if char == nil and err then       log("Läsfel: " .. err)       return nil, err     elseif char == '\r' or char == '\n' then       -- Hanterar CR, LF och potentiellt icke-skrivbara tecken       if char == '\n' then         crlf_received = true       end     elseif char then       table.insert(line, char)     end   end   local response = table.concat(line)   log("Mottaget svar: " .. response)   if string.sub(response, -1) == ';' then     response = string.sub(response, 1, -2)   end   return response end -- Loggar och skickar kommandon till bastustyrningen, läser sedan svaret local function sendAndRead(command)     log("Skickat kommando: " .. command)     port:write(command .. '\r\n')     return readack() end -- Hantera Timer-status (starta/stoppa) local function handleTimerStatus()     local timerStatus = grp.getvalue('37/1/5')     local response = sendAndRead(timerStatus and 'set timer on' or 'set timer off')     if response then         local status = string.match(response, "timer%s(%w+);")         grp.checkwrite('37/1/6', status == "on" and 1 or 0)     end end -- Sätta tid för Timer och hämta dess status local function setAndQueryTimerTime()     local timerTime = grp.getvalue('37/1/7')     sendAndRead('set timer val ' .. timerTime)     local timerTimeResponse = sendAndRead('get timer val')     if timerTimeResponse then         local timeValue = string.match(timerTimeResponse, "timer%s(%d+);")         grp.checkwrite('37/1/8', tonumber(timeValue))     end end -- Hantera Userprogram local function handleUserProgram()     local userProgram = grp.getvalue('37/1/9')     local response = sendAndRead(userProgram and 'set user-prog on' or 'set user-prog off')     if response then         local status = string.match(response, "user%-prog%s(%w+);")         grp.checkwrite('37/1/10', status == "on" and 1 or 0)     end     local programNumber = grp.getvalue('37/1/11')     local programResponse = sendAndRead('set user-prog val ' .. programNumber)     if programResponse then         local currentProgram = string.match(programResponse, "user%-prog%s(%d+);")         grp.checkwrite('37/1/12', tonumber(currentProgram))     end end -- Hämta bastu Control Unit Status local function getControlUnitStatus()     local response = sendAndRead('get status')     if response then         -- Matcha statusen efter "STATUS " utan att kräva ett semikolon i slutet         local status = string.match(response, "STATUS%s(%w+)")         if status then             -- Skickar statussvaret som en textsträng till KNX-gruppadressen             grp.checkwrite('37/1/20', "Bastu " .. status)         else             log("Kunde inte tolka Control Unit status från svaret: " .. response)         end     end end -- Anropa funktionerna handleTimerStatus() setAndQueryTimerTime() handleUserProgram() getControlUnitStatus() -- Stäng porten port:close()
Reply
#10
Do you get anything in logs? Any response from the readack() function?
Reply
#11
Gets this in my log, sorry for the swedish text in log Smile

Bastu Status REV 13.12.2023 09:25:16
* string: Skickat kommando: set timer val 240
Bastu Status REV 13.12.2023 09:25:16
* string: Mottaget svar: TIMER 240min ;
Bastu Status REV 13.12.2023 09:25:16
* string: Skickat kommando: get timer val
Bastu Status REV 13.12.2023 09:25:16
* string: Mottaget svar: TIMER 240min ;
Bastu Status REV 13.12.2023 09:25:16
* string: Skickat kommando: set user-prog val 1
Bastu Status REV 13.12.2023 09:25:16
* string: Mottaget svar: USER-PROG 1 ;
Bastu Status REV 13.12.2023 09:25:16
* string: Skickat kommando: get status
Bastu Status REV 13.12.2023 09:25:16
* string: Mottaget svar: STATUS OK;

The sauna activates with one relay but directly shuts off.
Reply
#12
The response is uppercase so your regexp won't work because it's lowercase. Use 'USER%-PROG%s+(%d+)' for user program detection and 'TIMER%s+(%w+)' for timer. Modify other regexps in a similar way.
Reply
#13
Okey, now gets this in Log.

Bastu Status REV 13.12.2023 09:52:22
* string: Skickat kommando: set timer val 240
Bastu Status REV 13.12.2023 09:52:22
* string: Mottaget svar: TIMER 240min ;
Bastu Status REV 13.12.2023 09:52:22
* string: Skickat kommando: get timer val
Bastu Status REV 13.12.2023 09:52:22
* string: Mottaget svar: �TIMER 240min ;
Bastu Status REV 13.12.2023 09:52:22
* string: Skickat kommando: set user-prog off
Bastu Status REV 13.12.2023 09:52:22
* string: Mottaget svar: USER-PROG off;
Bastu Status REV 13.12.2023 09:52:22
* string: Skickat kommando: set user-prog val 1
Bastu Status REV 13.12.2023 09:52:22
* string: Mottaget svar: USER-PROG 1 ;
Bastu Status REV 13.12.2023 09:52:22
* string: Skickat kommando: get status
Bastu Status REV 13.12.2023 09:52:22
* string: Mottaget svar: STATUS OK;
Reply
#14
Post you current script. What exactly is not working after the regexp changes?
Reply


Forum Jump: