Skip to content

Commit

Permalink
Merge branch 'master' of github.com:thingsboard/thingsboard-gateway
Browse files Browse the repository at this point in the history
  • Loading branch information
imbeacon committed Jan 28, 2025
2 parents 79dd6d6 + a890f4c commit 69e1f4c
Show file tree
Hide file tree
Showing 16 changed files with 1,007 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@ venv
/tests/storage/
/tests/blackbox/connectors/opcua/_trial_temp/
/tests/blackbox/connectors/modbus/_trial_temp/
*.DS_Store
71 changes: 71 additions & 0 deletions for_build/etc/thingsboard-gateway/config/knx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"logLevel": "INFO",
"client": {
"type": "AUTOMATIC",
"addressFormat": "LONG",
"localIp": "0.0.0.0",
"localPort": 3671,
"gatewayIP": "192.168.1.160",
"gatewayPort": 3671,
"individualAddress": "1.0.10",
"rateLimit": 0,
"autoReconnect": true,
"autoReconnectWait": 3,
"gatewaysScanner": {
"enabled": false,
"scanPeriod": 3,
"stopOnFound": false
}
},
"devices": [
{
"deviceInfo": {
"deviceNameDataType": "string",
"deviceNameExpressionSource": "expression",
"deviceNameExpression": "Device ${1/0/5}",
"deviceProfileDataType": "none",
"deviceProfileExpressionSource": "constant",
"deviceProfileNameExpression": "default"
},
"pollPeriod": 5000,
"attributes": [
{
"type": "temperature",
"key": "temperature",
"groupAddress": "1/0/6"
}
],
"timeseries": [
{
"type": "humidity",
"key": "humidity",
"groupAddress": "1/0/7"
}
]
}
],
"attributeUpdates": [
{
"deviceNameFilter": ".*",
"dataType": "precent_U8",
"groupAddress": "1/0/9",
"key": "brightness"
}
],
"serverSideRpc": [
{
"requestType": "read",
"deviceNameFilter": ".*",
"method": "get_name",
"dataType": "string",
"groupAddress": "1/0/5"
},
{
"requestType": "write",
"deviceNameFilter": ".*",
"method": "set_name",
"dataType": "string",
"groupAddress": "1/0/5"
}
]
}
13 changes: 13 additions & 0 deletions for_build/etc/thingsboard-gateway/extensions/knx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025. ThingsBoard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
'thingsboard_gateway.connectors.rest', 'thingsboard_gateway.extensions.rest',
'thingsboard_gateway.connectors.snmp', 'thingsboard_gateway.extensions.snmp',
'thingsboard_gateway.connectors.ftp', 'thingsboard_gateway.extensions.ftp',
'thingsboard_gateway.connectors.knx', 'thingsboard_gateway.extensions.knx',
'thingsboard_gateway.tb_utility', 'thingsboard_gateway.extensions',
'thingsboard_gateway.extensions.serial'
],
Expand Down
71 changes: 71 additions & 0 deletions thingsboard_gateway/config/knx.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
{
"logLevel": "INFO",
"client": {
"type": "AUTOMATIC",
"addressFormat": "LONG",
"localIp": "0.0.0.0",
"localPort": 3671,
"gatewayIP": "192.168.1.160",
"gatewayPort": 3671,
"individualAddress": "1.0.10",
"rateLimit": 0,
"autoReconnect": true,
"autoReconnectWait": 3,
"gatewaysScanner": {
"enabled": false,
"scanPeriod": 3,
"stopOnFound": false
}
},
"devices": [
{
"deviceInfo": {
"deviceNameDataType": "string",
"deviceNameExpressionSource": "expression",
"deviceNameExpression": "Device ${1/0/5}",
"deviceProfileDataType": "none",
"deviceProfileExpressionSource": "constant",
"deviceProfileNameExpression": "default"
},
"pollPeriod": 5000,
"attributes": [
{
"type": "temperature",
"key": "temperature",
"groupAddress": "1/0/6"
}
],
"timeseries": [
{
"type": "humidity",
"key": "humidity",
"groupAddress": "1/0/7"
}
]
}
],
"attributeUpdates": [
{
"deviceNameFilter": ".*",
"dataType": "precent_U8",
"groupAddress": "1/0/9",
"key": "brightness"
}
],
"serverSideRpc": [
{
"requestType": "read",
"deviceNameFilter": ".*",
"method": "get_name",
"dataType": "string",
"groupAddress": "1/0/5"
},
{
"requestType": "write",
"deviceNameFilter": ".*",
"method": "set_name",
"dataType": "string",
"groupAddress": "1/0/5"
}
]
}
13 changes: 13 additions & 0 deletions thingsboard_gateway/connectors/knx/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025. ThingsBoard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
13 changes: 13 additions & 0 deletions thingsboard_gateway/connectors/knx/entities/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright 2025. ThingsBoard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
75 changes: 75 additions & 0 deletions thingsboard_gateway/connectors/knx/entities/client_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# Copyright 2025. ThingsBoard
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from xknx.telegram.address import GroupAddressType
from xknx.io.const import DEFAULT_MCAST_PORT, DEFAULT_MCAST_GRP
from xknx.io.connection import ConnectionConfig, ConnectionType, SecureConfig

ADDRESS_FORMAT = {
"SHORT": GroupAddressType.SHORT,
"LONG": GroupAddressType.LONG,
"FREE": GroupAddressType.FREE
}

CONNECTION_TYPE = {
"AUTOMATIC": ConnectionType.AUTOMATIC,
"ROUTING": ConnectionType.ROUTING,
"ROUTING_SECURE": ConnectionType.ROUTING_SECURE,
"TUNNELING": ConnectionType.TUNNELING,
"TUNNELING_TCP": ConnectionType.TUNNELING_TCP,
"TUNNELING_TCP_SECURE": ConnectionType.TUNNELING_TCP_SECURE
}


class ClientConfig:
def __init__(self, config):
address_format_config = config.get('addressFormat', 'LONG').upper()
self.address_format = ADDRESS_FORMAT.get(address_format_config, GroupAddressType.LONG)
self.rate_limit = int(config.get('rateLimit', 0))
self.multicast_group = config.get('multicastGroup', DEFAULT_MCAST_GRP)
self.multicast_port = int(config.get('multicastPort', DEFAULT_MCAST_PORT))
self.state_updater = bool(config.get('stateUpdater', False))
self.connection_config = self.get_connection_config(config)

def get_connection_config(self, config):
security_config = self.get_security_config(config)

connection_type = config.get('type', 'AUTOMATIC').upper()
connection_config = ConnectionConfig(connection_type=CONNECTION_TYPE.get(connection_type, "AUTOMATIC"),
individual_address=config.get('individualAddress'),
local_ip=config.get('localIp'),
local_port=int(config.get('localPort', 0)),
gateway_ip=config.get('gatewayIp'),
gateway_port=int(config.get('gatewayPort', DEFAULT_MCAST_PORT)),
multicast_group=config.get('multicastGroup', DEFAULT_MCAST_GRP),
multicast_port=int(config.get('multicastPort', DEFAULT_MCAST_PORT)),
auto_reconnect=bool(config.get('autoReconnect', True)),
auto_reconnect_wait=int(config.get('autoReconnectWait', 3)),
secure_config=security_config)

return connection_config

def get_security_config(self, config):
if config.get('connectionType') in ('AUTOMATIC', 'ROUTING_SECURE', 'TUNNELING_TCP_SECURE'):
security_config_dict = config.get('security', {})
security_config = SecureConfig(backbone_key=security_config_dict.get('backboneKey'),
latency_ms=security_config_dict.get('latencyMs'),
user_id=security_config_dict.get('userId'),
device_authentication_password=security_config_dict.get('deviceAuthenticationPassword'), # noqa
user_password=security_config_dict.get('userPassword'),
knxkeys_file_path=security_config_dict.get('knxkeysFilePath'),
knxkeys_password=security_config_dict.get('knxkeysPassword'))
return security_config

return None
Loading

0 comments on commit 69e1f4c

Please sign in to comment.