velux kfl-200 - domotiqa - 19.09.2018
hello,
is there someone who already dealed with this interface with "hidden" ip api ?
I found someone who made a script:
Code: --[[
%% properties
%% events
%% globals
--]]
-- les variables globales ci-dessous sont initialisées avec des valeurs par défaut
-- ces valeurs seront normalement écrasées par le passage de paramètres lors de l'appel de la scène.
local VeluxDebug = true
local programme = "2"
local password = "xxxYYYzzz"
local KLF_ip = "192.168.yyy.zzz"
local params = fibaro:args()
if (params) then
for k, v in ipairs(params) do
if (v.programme) then
programme = v.programme
end
if (v.adresseIP) then
KLF_ip = v.adresseIP
end
if (v.password) then
password = v.password
end
end
end
local urlLogin = 'http://'.. KLF_ip .. '/api/v1/auth'
local urlLogout = 'http://'.. KLF_ip .. '/api/v1/auth'
local urlScenes = 'http://'.. KLF_ip .. '/api/v1/scenes'
local datasLogin = '{"action":"login","params":{"password":"'.. password .. '"}}'
local datasLogout = '{"action":"logout","params":{}}'
local datasAction = '{"action":"run","params":{"id":"' ..programme ..'"}}'
if (VeluxDebug) then
fibaro:debug("Démarrage de la scène avec les paramètres suivants")
fibaro:debug("adresse IP = " .. KLF_ip)
fibaro:debug("Password = " .. password)
fibaro:debug("Programme = " .. programme)
fibaro:debug(datasAction)
end
local klf = net.HTTPClient()
klf:request(urlLogin , {
success = function(response)
if tonumber(response.status) == 200 then
if (VeluxDebug) then
fibaro:debug("Call for LOGON successfull")
fibaro:debug("Valeur de response")
fibaro:debug(json.encode(response))
end
-- récupération du token
local temp = json.encode(response)
local token = temp:match('\\\"token\\\":\\\"(.+)\\\",\\\"result')
token = string.gsub(token, '\\', '')
if (VeluxDebug) then
fibaro:debug("Valeur du token : "..token)
end
klf:request(urlScenes, {
success = function(response)
if tonumber(response.status) == 200 then
if (VeluxDebug) then
fibaro:debug("Call for ACTION successful")
fibaro:debug("response\n")
fibaro:debug(json.encode(response))
end
klf:request(urlLogout , {
success = function(response)
if tonumber (response.status) == 200 then
if (VeluxDebug) then
fibaro:debug("Call for LOGOUT successful")
fibaro:debug("response\n")
fibaro:debug(json.encode(response))
-- fibaro:debug("response.data\n")
-- fibaro:debug(response.data)
end
else
if (VeluxDebug)then
fibaro:debug("LOGOUT Failed : Status =" .. response.status)
end
end
end,
error = function(err)
print ("Erreur de LOGOUT")
print('error = ' .. err)
end,
options = {
method = 'POST',
headers = {
["content-type"] = 'application/json, charset=utf-8',
["Authorization"] = "Bearer "..token,
["Connection"] = 'close',
},
data = datasLogout
}
})
else
if (VeluxDebug)then
fibaro:debug("RUN ACTION Failed : Status =" .. response.status)
end
end
end,
error = function(err)
print("Erreur lors du RUN ACTION")
print('error =' ..err)
end,
options = {
method = 'POST',
headers = {
["content-type"] = 'application/json, charset=utf-8',
["content-length"] = "34",
["Authorization"] = "Bearer "..token,
["Connection"] = 'Keep-Alive',
},
data = datasAction
}
})
else
if (VeluxDebug)then
fibaro:debug("Login Failed : Status =" .. response.status)
end
end
end,
error = function(err)
print ("Erreur lors du LOGIN")
print('error = ' .. err)
end,
options = {
method = 'POST',
headers = {
["content-type"] = 'application/json, charset=utf-8',
["connection"] = 'close',
},
data = datasLogin
}
})
RE: velux kfl-200 - admin - 01.10.2018
This code can be rewritten to run on LM, this thread has some similar examples of HTTP requests: https://forum.logicmachine.net/showthread.php?tid=993
RE: velux kfl-200 - domotiqa - 11.02.2019
looks like Velux changed the API of the KLF200
https://velcdn.azureedge.net/~/media/com/api/klf200/technical%20specification%20for%20klf%20200%20api-ver3-16.pdf
looks harder
an example
Code: ## ======================================================
## Script pour demarrer une scene de la box Velux KLF-200
## ------------------------------------------------------
## Version 0.1.1 - Last update : 03.11.18 by Christian R.
## ======================================================
import ssl, socket, time, struct
from time import sleep
# ===============================================================================
# Variables
# ===============================================================================
SCENE_ID = 1
KLF200_ADDRESS = "192.168.0.12"
PASSWORD = "Velux123"
PORT = 51200
LoopDelay = 1
# ===============================================================================
# slip
# ===============================================================================
END = b"\xC0" # SLIP escape character as per RFC 1055
ESC = b"\xDB" # SLIP escape character as per RFC 1055
ESC_END = b"\xDC" # SLIP escape character as per RFC 1055
ESC_ESC = b"\xDD" # SLIP escape character as per RFC 1055
def slip_pack(inputFrame):
data = inputFrame
data = data.replace(ESC, ESC + ESC_ESC)
data = data.replace(END, ESC + ESC_END)
return END + data + END
def slip_unpack(inputFrame):
data = inputFrame
if(data[0:1]==END and data[-1:]==END):
data = data.replace(ESC + ESC_END, END)
data = data.replace(ESC + ESC_ESC, ESC)
return data[1:-1]
else:
print("Error: No SLIP frame!\n")
return inputFrame # error -> return input
# ===============================================================================
# toolbox
# ===============================================================================
def getIndex(sourceDict, value):
return (k for k, v in sourceDict.items() if v == value).__next__()
def toHex(s):
return ":".join("{:02x}".format(c) for c in s)
# ===============================================================================
# ActivateScene
# ===============================================================================
def process_connection(conn):
conn.settimeout(10.0) # 10 sec
print("Send valid password")
conn.write(bytes(ST_GW_PASSWORD_ENTER_REQ(PASSWORD)))
print("Received: ", toHex(slip_unpack(conn.recv())), "\n")
time.sleep(LoopDelay)
print("Activate Scene with ID = ", SCENE_ID)
conn.write(bytes(ST_GW_ACTIVATE_SCENE_REQ(bSceneID=SCENE_ID)))
print("Received: ", toHex(slip_unpack(conn.recv())))
def main():
sock = socket.socket(socket.AF_INET)
sock.settimeout(10.0)
context = ssl.SSLContext(ssl.PROTOCOL_TLS)
context.check_hostname = False
#accept self-signed certificate
context.verify_mode = ssl.CERT_NONE
conn = context.wrap_socket(sock, server_hostname=KLF200_ADDRESS)
try:
conn.connect((KLF200_ADDRESS, PORT))
process_connection(conn)
except BaseException as e:
raise(e)
finally:
conn.close()
# ===============================================================================
# klf200api
# ===============================================================================
GW_ACTIVATE_SCENE_REQ = 0x0412
GW_ACTIVATE_SCENE_CFM = 0x0413
GW_PASSWORD_ENTER_REQ = 0x3000
GW_PASSWORD_ENTER_CFM = 0x3001
dictPriorityLevel = {
0: 'Human Protection',
1: 'Environment Protection',
2: 'User Level 1',
3: 'User Level 2',
4: 'Comfort Level 1',
5: 'Comfort Level 2',
6: 'Comfort Level 3',
7: 'Comfort Level 4',
}
dictCommandOriginator = {
0x00: "LOCAL_USER", # // User pressing button locally on actuator
0x01: "USER", # // User Remote control causing action on actuator
0x02: "RAIN", # // Sensor
0x03: "TIMER", # // Sensor
0x04: "SECURITY", # // SCD controlling actuator
0x05: "UPS", # // UPS unit
0x06: "SFC", # // Smart Function Controller
0x07: "LSC", # // Lifestyle Scenario Controller
0x08: "SAAC", # // Stand Alone Automatic Controls
0x09: "WIND", # // Wind detection
0x10: "MYSELF", # // Used when an actuator decides to move by itself
0xFE: "AUTOMATIC_CYCLE", # // Used in context with automatic cycle;
0xFF: "EMERGENCY" # // Used in context with emergency or security commands,
# // -this command originator should never be disabled
}
dictVelocity = {
0: 'DEFAULT',
1: 'SILENT',
2: 'FAST',
255: 'VELOCITY_NOT_AVAILABLE', #Only used in status reply
}
# ===============================================================================
class ST_GW_FRAME:
def __init__(self, Command):
self.DataLength = 0
self.Command = Command
self.binary_output = b"";
def __bytes__(self):
self.binary_output = struct.pack("BB", 0, self.DataLength + 3)
self.binary_output += struct.pack(">H", self.Command)
self.binary_output += self.pack_data()
self.binary_output += struct.pack("B", self.calc_crc())
return slip_pack(self.binary_output)
def calc_crc(self):
crc = 0
for sym in self.binary_output:
crc = crc ^ int(sym)
return crc
def pack_data(self):
return b""
class ST_GW_ACTIVATE_SCENE_REQ (ST_GW_FRAME):
def __init__(self,
wSessionID = 0x1234,
CommandOriginator = 'USER',
PriorityLevel = 'User Level 2',
bSceneID = 0,
Velocity = 'DEFAULT'):
ST_GW_FRAME.__init__(self, GW_ACTIVATE_SCENE_REQ)
self.DataLength = 6
self.wSessionID = wSessionID
self.bCommandOriginator = getIndex(dictCommandOriginator, CommandOriginator)
self.bPriorityLevel = getIndex(dictPriorityLevel, PriorityLevel)
self.bSceneID = bSceneID
self.bVelocity = getIndex(dictVelocity, Velocity)
def pack_data(self):
ret = struct.pack(">H", self.wSessionID)
ret += bytes([self.bCommandOriginator])
ret += bytes([self.bPriorityLevel])
ret += bytes([self.bSceneID])
ret += bytes([self.bVelocity])
return ret
class ST_GW_PASSWORD_ENTER_REQ (ST_GW_FRAME):
def __init__(self, Password):
ST_GW_FRAME.__init__(self, GW_PASSWORD_ENTER_REQ)
self.DataLength = 32
self.Password = Password
def pack_data(self):
binary_data = bytes(self.Password,encoding='ascii')
binary_len = len(binary_data)
ret = binary_data[:self.DataLength if binary_len > self.DataLength else binary_len]
while binary_len < self.DataLength:
ret += b'\x00'
binary_len = binary_len + 1
return ret
# ===============================================================================
# Start script
# ===============================================================================
main()
print("Finished")
RE: velux kfl-200 - admin - 13.02.2019
This is doable but quite hard to provide an working example without access to the device itself to test it.
RE: velux kfl-200 - domotiqa - 13.02.2019
adminThis is doable but quite hard to provide an working example without access to the device itself to test it.
yes
can you provide at least exemple for the part with the initialisation:
GW_PASSWORD_ENTER_REQ( Last byte of Password byte array must be null terminated )
defaut password is
Code: PASSWORD = "Velux123"
because in fact i only need, the authentification, then the command send
GW_COMMAND_SEND_REQ()
RE: velux kfl-200 - MichelDeLigne - 03.04.2019
Hi,
A full API made by Chris Traeger is available for Node.js. It is compatible with the latest versions of the KLF200 firmware
This would probably be a good base to implement something in LM.
It is available at: https://github.com/PLCHome/velux-klf200-api
Cheers.
Michel.
RE: velux kfl-200 - Joep - 21.06.2024
Here you can download the API documentation
The API password is the WLAN password of the KLF200
RE: velux kfl-200 - kgroenhoej - 15.07.2024
(13.02.2019, 06:33)admin Wrote: This is doable but quite hard to provide an working example without access to the device itself to test it.
Yes - understandable.
The integration would be a big benefit for projects that include both KNX (LM) and Velux. But maybe Velux is not interested in helping with this integration now they have their own KNX-integration: DISK (Domex)
RE: velux kfl-200 - gjniewenhuijse - 16.07.2024
Maybe using a Somfy Tahoma Switch with Velux IO products.
Somfy Tahoma Switch:
https://github.com/Somfy-Developer/Somfy-TaHoma-Developer-Mode
Velux other post:
https://forum.logicmachine.net/showthread.php?tid=1468&pid=21082#pid21082
RE: velux kfl-200 - kgroenhoej - 16.07.2024
Even the “knx-lite” ABB-free@home have an integration:
ABB-free@home Velux Interface KLF 200
Somehow abb was able to get a Velux-developer-test-setup
RE: velux kfl-200 - kgroenhoej - 13.06.2025
essential.tar.gz updated 19/06/2025 (added a note about using "Last instance only" with HomeKit)
Hi
This is an API for KLF 200. It is original based on the idea/code from threads in this forum – and further expanded to include the full API. Exclaimer: I’m not a script/code-developer and definitely not a LUA-developer, so the code is no doubt full of bugs or could have been done way better, faster, and smarter – but the code works as far as I can test. Use at your own risk.
In this document there’s a lot of detailed information – probably you don’t need it and/or it’s not useful for you – and maybe the level of detail is to low or high. But then again - it might be useful to some…
I had a plan to make an app for the LM5 but I never seems to find the time for it…
--
First some background information:
KLF 200 is an IO-Homecontrol ® gateway. It can control actuators (windows/blinds/shutters/and other IO-Homecontrol devices). If the actuator can be discovered by the KLF 200 then it should be able to control it. The KLF 200 can also be configured as a repeater (out of scope in this document). The pairing of the actuators with the KLF-200 is also out of scope of this document – but the PoC-commands/requests to the KLF 200 to do the discover is in included the attached files. The API also supports copying configuration from or to another controller (TCM/RCM). Please see the “Configuration service” section in the API-Technical-specification PDF included in the extra part file.
--
Tips:
- when connecting to KLF 200 web-interface for the first time – one of the first thing to do is to disable the WLAN timeout (it’s default only active for a short period of time after a reboot - you can change the timeout again later when you don’t need the web-access anymore (when your LM5 has access)). Use a static ip-address on the ethernet-port of the KLF 200 either statically configured on the device or on the DHCP-server (preferable). You will not be able to access the web-interface of the KLF 200 on the configured IP-address on the ethernet-port – the only way to access the web-interface is by using the WLAN-setup-SSID (might be firmware-dependent).
- Clear the log in KLF 200 after the LM5 have full access to it. All the old log (some of the logs is supposedly from the fabric) is of no use because the logs is with the wrong timestamps.
--
Extra background information:
KLF 200 can control actuators by either the 10 contact input relays or by requests/commands send by your LM5.
The contact input relays can activate either a single actuator, multiple actuators, a group of actuators or a scene. The contact input relays can be controlled by a shutter actuator – I used to use 2 JAL-0810.02 together with 3 KLF200 (to get enough input-relays to control all my actuators), but not anymore – with this code I can control all the actuators (and a lot more) with a single KLF 200 with an ethernet-connection :-)
When the actuators is discovered then all actuators get a unique NodeID within KLF 200.
KLF 200 can have up to 200 NodeIDs.
KLF 200 can send one request/command to each individual NodeID or multiple NodeIDs (maximum of 20) with a single request/command – when LM5 receives actuator feedback from KLF 200 it’s nodeID-specifik.
KLF 200 can have up to 100 GroupIDs – each group can contain (or point to) one or more of the 200 NodeIDs. It’s possible to have groups with the same NodeIDs – e.g., all the windows in the house and all the windows in a room – both groups include the room-windows.
A group can be of a certain type e.g., User_Group, Room or House. All actuators in a group must be of the same type. You can also set the placement of the node which can be anything – but the room-group-id or the house-group-id would be the logically choice.
KLF 200 can send one request/command to a group but when LM5 receives actuator-feedback from KLF 200 it’s still nodeID-specifik.
KLF 200 can also control actuators by scenes. A scene is a snapshot of the positions of relevant actuators – when LM5 receives actuator feedback from KLF 200 it’s still nodeID-specifik.
I don’t have the need to control more than 20 actuators with a single request/command. And I don’t have the need to group the actuators into room-groups or house-groups – a simple table in a user library is enough for me to keep in control of all the actuators. But if you don’t have a LM5 it might be another matter. I used to group the actuators in groups but that was when I controlled the actuators with input relays (before I even knew that LM5 existed).
I don’t have the need for scenes – if I want some of the actuators in one special position and other actuators to be in another special position – I can make a user library with the necessary tables and I’m ok with sending multiple requests/commands to get the actuators in the positions I want. Again – if you don’t have a LM5 it might be another matter if you want to use scenes.
--
Overall: the code consists of a handler which is about:
Handle a TCP-connection to a KLF 200
Listens on a UDP-port for incoming requests/commands and forward the requests to the KLF 200.
--
The attached files are divided in an essential part, Proof of Concept part and a extra part
The files in the essential part should be enough to get up and running if you just want to control actuators by using an already running and configured KLF 200.
The essential part file consists of:
Resident scripts:
- Resident handler (Velux KLF-200 Resident Handler VELUX_KLF_6DC8 ) – the main script (sleep interval 0 seconds).
- Start resident handler script (Velux KLF-200 Start Resident Handler Start VELUX_KLF_6DC8 ) – a resident script that will clean up storage and start up the handler. This is just an easy way to update all the necessary storage tables if the configuration of the KLF 200 is changed.
- After resident handler start script (Velux KLF-200 After Resident Handler Start VELUX_KLF_6DC8 ) – a resident script that will send a login-request with the password to the KLF 200 and make it ready to accept requests/commands
- After password is accepted script (Velux KLF-200 GW_PASSWORD_ENTER_CFM VELUX_KLF_6DC8 ) – a resident script that will be activated only when password is accepted. The script will request some table information from the KLF 200 and populate the storage. The script also sets the time of the KLF 200 (for e.g., log-timestamps – and yes – the KLF 200 do have logs) and enable monitor status so the handler will receive actuator statuses when actuators are moving/stop moving
Scheduled scripts:
- A keepalive script (Velux_KLF_200_GW_GET_STATE_REQ_VELUX_KLF_6DC8_Schedule ) – The KLF 200 will close the TCP-connection if there are no requests/commands for 15 minutes. Schedule the script to run every 10 minutes
User libraries:
- Actuator request/command (GW_COMMAND_SEND_REQ ) - a user library for event-scripts so the event-scripts seems clean of unnecessary fluff
- KLF 200 hostname library (VELUX_KLF_6DC8 ) – a user library used by the start handler script with all necessary information about the KLF 200 to communicate TCP with the KLF 200 and a UDP-port for listen for commands. The KLF200-table in this library is saved as “Hostname” in storage.
- KLF 200 handler library (Velux_KLF_200_Library ) – a library with all the API-functions and tables for the KLF 200 – used by the Resident handler script. Pack/unpack/decipher all communication with the KLF 200.
- KLF 200 Actuator library (Velux_KLF200NodeIDsTable ) – a library with a table with NodeIDs to GAs mapping. Used by the handler library to update GAs when the actuators move/stop moving. If you use HomeKit for LM5 you should recognize the GA naming-structure.
- KLF 200 Verify handler (Velux_KLF_200_Verify_Handler ) – a library used by a lot of scripts to verify that the handler is up and running and the communication with the KLF 200 is working
Event scripts:
- Node target position control (klf200 Node Target position control ) - a simple script that is sending a command to the handler for moving a single unit to a position
- Node target position state control (klf200 Node Target position state control ) - a simple script that is sending a command to the handler for moving a single unit to either move up, down, stop or continue the previous move action after a stop
A certificate file needed for secure TCP-communication between handler and KLF 200. You need to upload this file to the LM5 and use the full directory-path in Hostname library.
--
When you have your KLF 200 up and running with a static IP-address on the ethernet-port then you’re ready to proceed.
To get up and running the essential part scripts you need to:
- Get the certificate file in place – upload it to your LM5 and note the full directory-path
- Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200 in all script-texts and in all scripts-names
- Edit the Hostname library (user.VELUX_KLF_6DC8)
- First rename the scriptname to reflect the hostname of your KLF 200 device
- Edit the full directory-path for the certificate-file
- HostName – if you didn’t already replace it in an earlier step
- IPAddress – the IP-address of the KLF 200 – remember to make the IP-address static e.g., in the DHCP-server
- UDPPort – the listener UDP-port for handler if you know that you already use this port for something else e.g., another KLF 200 device :-)
- WIFIPassword – found on the back of your KLF 200 device
- Replace hostname in the 3 scriptfiles
- Edit the handler library (user.Velux_KLF_200_Library)
- Set the do_log to true if you want a lot of logs
- Set the do_alert to true if you want alerts (only in case of undocumented NodeID State and if there is a new log in the KLF 200)
- Set the do_storage to true if you want a lot of tables/communication-tables saved in the storage
- Edit the actuator library (user.Velux_KLF200NodeIDsTable)
- If you don’t know the NodeIDs of the actuators (yet) and/or you haven’t created the GAs yet – just delete all the content and save an empty file. You can build it later when you have the correct information (after the handler have been activated and updated the NodeID-storage-table). If you have the actuators in HomeKit for LM5 then you already have the GAs. If you want the handler to update GAs with actuator-positions when the actuator is moving/stopped moving – then you need to create the NodeIDs from the KLF200NodeIDsTable in storage (after the handler have been activated and updated the NodeID-storage-table) in actuator library and add the GAs to the NodeIDs.
- Edit the start resident handler script (Velux KLF-200 Start Resident Handler Start VELUX_KLF_6DC8)
- rename the scriptname to reflect the hostname of your KLF 200 device
- require hostname library - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the after resident handler start script (Velux KLF-200 After Resident Handler Start VELUX_KLF_6DC8)
- rename the scriptname to reflect the hostname of your KLF 200 device
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the resident handler start script (Velux KLF-200 Resident Handler VELUX_KLF_6DC8)
- rename the scriptname to reflect the hostname of your KLF 200 device
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the After password is accepted resident script (Velux KLF-200 GW_PASSWORD_ENTER_CFM VELUX_KLF_6DC8)
- rename the scriptname to reflect the hostname of your KLF 200 device
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the keepalive scheduled script (Velux_KLF_200_GW_GET_STATE_REQ_VELUX_KLF_6DC8_Schedule)
- rename the scriptname to reflect the hostname of your KLF 200 device
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the event scripts (klf200 Node Target position control/ klf200 Node Target position state control)
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Replace NodeID with the right IDs from the storage-tables (KLF200NodeIDsTable)
- (if using "Node Target position control" with HomeKit, please select "Last instance only" for "Execution mode")
--
The extra part file consists of:
Resident scripts:
- Create_GAs (Velux KLF-200 Create_GAs ) – a script to create GAs according to the mapping in the actuator-table in the actuator library; use at your own risk. Please make sure that _none_ of the GAs in the actuator-library-file: “KLF 200 Actuator library” is already in use.
- After Get Scene List Request (Velux KLF-200 GW_GET_SCENE_LIST_NTF VELUX_KLF_6DC8) - a resident script that will get activated after a request to get list of scenes. Just weird why the reply to Get_Scene_List doesn’t include the NodeIDs; to get the NodeIDs into the Scenelist each scene must be requested for NodeID-information. No need if you don’t use scenes. Uncomment the scene-stuff in the resident script: “Velux KLF-200 GW_PASSWORD_ENTER_CFM VELUX_KLF_6DC8” and restart the handler.
- Efter New Log Notify (Velux KLF-200 GW_ACTIVATION_LOG_UPDATED_NTF VELUX_KLF_6DC8) - a resident script that will get activated after a notification from KLF 200 that there’s a new log-line. The script get the new log-line and log it (if do_log is false then the line will not be logged, but the handler library will still alert the event (if do_alert is not false))
Event scripts (Event-tag-scripts use GA as an index for finding out the NodeIDs/groupID to send to the handler. The table is manuel built in GA2ID library)
- Group target position control (klf200 Group Target position control ) - a simple script that is sending a command to the handler for moving a group of units to a position
- Group target position state control (klf200 Group Target position state control ) - a simple script that is sending a command to the handler for moving a group of units to either move up, down, stop or continue the previous move action after a stop
- NodeIDs tag target position control (klf200 NodeIDs tag Target position control ) - a simple script that is sending a command to the handler for moving units (one or more - up to 20) to a position
- Group tag target position control (klf200 Group tag Target position control ) - a simple script that is sending a command to the handler for moving a group of units to a position
- NodeIDs tag target position state control (klf200 NodeIDs tag Target position state control ) - a simple script that is sending a command to the handler for moving units (one or more - up to 20) to either move up, down, stop or continue to previous move action after stop
- Group tag target position state control (klf200 Group tag Target position state control ) - a simple script that is sending a command to the handler for moving a group of units to either move up, down, stop or continue to previous move action after stop
User library:
- GA2ID library (Velux_KLF200GA2IDsTable ) – a library that has mapping of GAs 2 NodeIDs and/or GroupID; used by event-tag-scripts
- Group request/command (GW_ACTIVATE_PRODUCTGROUP_REQ ) - a user library for event-scripts so the event-scripts seems clean of unnecessary fluff. Uncomment the group-stuff in the resident script: “Velux KLF-200 GW_PASSWORD_ENTER_CFM VELUX_KLF_6DC8” and restart the handler.
- Scene request/command (GW_ACTIVATE_SCENE_REQ ) - a user library for event-scripts so the event-scripts seems clean of unnecessary fluff. No need if you don’t use scenes. Uncomment the Scene-stuff in the resident script: “Velux KLF-200 GW_PASSWORD_ENTER_CFM VELUX_KLF_6DC8” and restart the handler.
KLF 200 API PDF-file (Velux_technical specification for klf 200 api-ver3-18 ) for KLF 200 firmware version 2.0.0.71; the old API (ver3-16) is also attached and the previous versions of this code was based on ver3-16.
KLF 200-v2.0.0.71 binary file for upgrading the KLF 200 to version 2.0.0.71 – if in doubt what version your KLF 200 is running you can use the resident script GW_GET_VERSION_REQ – before doing so you need to enable do_log in top of the handler library and restart the handler. You can only upgrade the firmware in the KLF 200 in the web-interface when your PC is connected to the WLAN-setup-SSID.
--
Before using the extra part scripts:
- the Create_GAs resident script (Velux KLF-200 Create_GAs)
- use at your own risk
- the script will create GAs according to the mapping in actuator library (user.Velux_KLF200NodeIDsTable)
- if the GAs already exist it will rename the GAs
- edit the GA2ID library (Velux_KLF200GA2IDsTable) – if you want to use event-tags then you need to create mapping from GA to either NodeIDs or a GroupID in this library.
- You will need to edit the event-scripts (Hostname/NodeIDs/GroupIDs) in each one of them if you want to use them
a. tag target position control event scripts (klf200 NodeIDs(Group) tag Target position control) use the GA2ID library – this script converts the percent/scale event.value to KLF200 value and send the command to either a list of NodeIDs or a GroupID
b. tag target position state control event scripts (klf200 NodeIDs(Group) tag Target position state control) use the GA2ID library– this script uses event.value to request a list of NodeIDs or a GroupID to either move up, down, stop or continue the previous move action after a stop
--
The Proof of Concepts part file consists of:
- A bunch of Resident scripts named of the specific requests/command.
--
To get up and running the PoC part scripts you need to:
- HostName - Search and replace the hostname “VELUX_KLF_6DC8” with the hostname of your KLF 200
- Edit the NodeID/GroupID/SceneID/etc. depending on the script to what ever you want to request/command
--
Notes:
The handler library “KLF 200 handler library” will activate a resident script after the KLF 200 have accepted the requests (CFM) and when the KLF 200 have finished the request/command (NTF) e.g., if you send the request/command: “GW_GET_NODE_INFORMATION_REQ” then KLF 200 will acknowledge the request with a “GW_GET_NODE_INFORMATION_CFM” and if there’s a resident script named “GW_GET_NODE_INFORMATION_CFM” it will be activated. And likewise - when the KLF 200 is finished sending all the data in GW_GET_NODE_INFORMATION_NTF-packets and if there’s a resident script named “GW_GET_NODE_INFORMATION_NTF” it will be activated. That’s how the tables in storage gets updated when the password for login is correct.
The handler library “KLF 200 handler library” will log extensively (the parsed contents of all packets back and forth to the KLF 200) if do_log = true in top of the user-handler-library.
The handler library “KLF 200 handler library” will use the storage extensively (the last packet of all the transactions to the KLF 200 and built all the tables that’s configured in the KLF 200 if there’s a request for the table (e.g., GW_GET_ALL_NODES_INFORMATION_REQ)) if do_storage = true in top of the user-handler-library
Content from the hostname library needs to be saved in storage as “Hostname” – this is done by the Start resident handler script; almost all scripts use this storage. The storage table will be updated by the resident handler and the “After password is accepted script”
These tables will also be in storage:
KLF200NodeIDsTable – this table is copied from the actuator library (to get the NodeID2GA mapping) and will contain all the necessary information for all actuators. It will be updated by the handler library with name, state, and positions.
KLF200ContactInputIDsTable – if the KLF 200 contains any ContactInput tables. It will be updated by the handler library (extras part)
KLF200GroupIDsTable – if the KLF 200 contains any Group tables. It will be updated by the handler library (extras part)
KLF200SceneIDsTable – if the KLF 200 contains any Scene tables. It will be updated by the handler library (extras part)
If you use Multiple KLF 200 beware that you need to make a copy of the files and edit accordingly (both scriptname and Hostname in the scripts) so it reflects a new hostname (e.g.,: “VELUX_KLF_6DC8” to something else), the password, the IP-number and the UDP-port-number.
The resident handler is not made to handle multiple KLF 200 (because of the Hostname-statement in the script - you need to make a copy of the handler and change the Hostname) – but the handle library is multi-KLF-200-able.
Regards
Klaus
|