On Thu, Nov 19, 2020 at 2:15 AM Martin Jansa <martin.ja...@gmail.com> wrote: > > python3-jsonpath-rw dependency was added to meta-python, but meta-oe doesn't > depend on meta-python, so either python3-jsonpath-rw needs to be moved to > meta-oe (if it doesn't depend on other stuff from meta-python) or > thingsboard-gateway needs to be moved to meta-python. >
perhaps move it to meta-python is fine > On Wed, Nov 18, 2020 at 12:04 AM Khem Raj <raj.k...@gmail.com> wrote: >> >> From: "hasan.men" <hasan....@bosphorusiss.com> >> >> Signed-off-by: Khem Raj <raj.k...@gmail.com> >> --- >> .../thingsboard-gateway/bacnet.json | 58 ++++++ >> .../thingsboard-gateway/ble.json | 53 ++++++ >> .../thingsboard-gateway/can.json | 89 +++++++++ >> .../thingsboard-gateway/custom_serial.json | 33 ++++ >> .../thingsboard-gateway/logs.conf | 77 ++++++++ >> .../thingsboard-gateway/modbus.json | 169 ++++++++++++++++++ >> .../thingsboard-gateway/modbus_serial.json | 29 +++ >> .../thingsboard-gateway/mqtt.json | 132 ++++++++++++++ >> .../thingsboard-gateway/odbc.json | 54 ++++++ >> .../thingsboard-gateway/opcua.json | 49 +++++ >> .../thingsboard-gateway/request.json | 146 +++++++++++++++ >> .../thingsboard-gateway/rest.json | 152 ++++++++++++++++ >> .../thingsboard-gateway/snmp.json | 138 ++++++++++++++ >> .../thingsboard-gateway/tb_gateway.yaml | 66 +++++++ >> .../thingsboard-gateway.service | 13 ++ >> .../thingsboard-gateway_2.5.2.bb | 68 +++++++ >> 16 files changed, 1326 insertions(+) >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/bacnet.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/ble.json >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/can.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/custom_serial.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/logs.conf >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus_serial.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/mqtt.json >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/odbc.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/opcua.json >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/request.json >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/rest.json >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/snmp.json >> create mode 100755 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/tb_gateway.yaml >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/thingsboard-gateway.service >> create mode 100644 >> meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway_2.5.2.bb >> >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/bacnet.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/bacnet.json >> new file mode 100644 >> index 0000000000..e36a2165d1 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/bacnet.json >> @@ -0,0 +1,58 @@ >> +{ >> + "general": { >> + "objectName": "TB_gateway", >> + "address": "192.168.188.181:1052", >> + "objectIdentifier": 599, >> + "maxApduLengthAccepted": 1024, >> + "segmentationSupported": "segmentedBoth", >> + "vendorIdentifier": 15 >> + }, >> + "devices": [ >> + { >> + "deviceName": "BACnet Device ${objectName}", >> + "deviceType": "default", >> + "address": "192.168.188.181:10520", >> + "pollPeriod": 10000, >> + "attributes": [ >> + { >> + "key": "temperature", >> + "type": "string", >> + "objectId": "analogOutput:1", >> + "propertyId": "presentValue" >> + } >> + ], >> + "timeseries": [ >> + { >> + "key": "state", >> + "type": "bool", >> + "objectId": "binaryValue:1", >> + "propertyId": "presentValue" >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "key": "brightness", >> + "requestType": "writeProperty", >> + "objectId": "analogOutput:1", >> + "propertyId": "presentValue" >> + } >> + ], >> + "serverSideRpc": [ >> + { >> + "method": "set_state", >> + "requestType": "writeProperty", >> + "requestTimeout": 10000, >> + "objectId": "binaryOutput:1", >> + "propertyId": "presentValue" >> + }, >> + { >> + "method": "get_state", >> + "requestType": "readProperty", >> + "requestTimeout": 10000, >> + "objectId": "binaryOutput:1", >> + "propertyId": "presentValue" >> + } >> + ] >> + } >> + ] >> + } >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/ble.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/ble.json >> new file mode 100755 >> index 0000000000..2a5da3f41d >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/ble.json >> @@ -0,0 +1,53 @@ >> +{ >> + "name": "BLE Connector", >> + "rescanIntervalSeconds": 100, >> + "checkIntervalSeconds": 100, >> + "scanTimeSeconds": 5, >> + "passiveScanMode": true, >> + "devices": [ >> + { >> + "name": "Temperature and humidity sensor", >> + "MACAddress": "4C:65:A8:DF:85:C0", >> + "addrType": "public", >> + "telemetry": [ >> + { >> + "key": "temperature", >> + "method": "notify", >> + "characteristicUUID": >> "226CAA55-6476-4566-7562-66734470666D", >> + "byteFrom": 2, >> + "byteTo": 6 >> + }, >> + { >> + "key": "humidity", >> + "method": "notify", >> + "characteristicUUID": >> "226CAA55-6476-4566-7562-66734470666D", >> + "byteFrom": 9, >> + "byteTo": 13 >> + } >> + ], >> + "attributes": [ >> + { >> + "key": "name", >> + "characteristicUUID": >> "00002A00-0000-1000-8000-00805F9B34FB", >> + "method": "read", >> + "byteFrom": 0, >> + "byteTo": -1 >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "attributeOnThingsBoard": "sharedName", >> + "characteristicUUID": >> "00002A00-0000-1000-8000-00805F9B34FB" >> + } >> + ], >> + "serverSideRpc": [ >> + { >> + "methodRPC": "rpcMethod1", >> + "withResponse": true, >> + "characteristicUUID": >> "00002A00-0000-1000-8000-00805F9B34FB", >> + "methodProcessing": "read" >> + } >> + ] >> + } >> + ] >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/can.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/can.json >> new file mode 100644 >> index 0000000000..b5cec0045a >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/can.json >> @@ -0,0 +1,89 @@ >> +{ >> + "interface": "socketcan", >> + "channel": "vcan0", >> + "backend": { >> + "fd": true >> + }, >> + "reconnectPeriod": 5, >> + "devices": [ >> + { >> + "name": "Car", >> + "sendDataOnlyOnChange": false, >> + "enableUnknownRpc": true, >> + "strictEval": false, >> + "attributes": [ >> + { >> + "key": "isDriverDoorOpened", >> + "nodeId": 41, >> + "command": "2:2:big:8717", >> + "value": "4:1:int", >> + "expression": "bool(value & 0b00000100)", >> + "polling": { >> + "type": "once", >> + "dataInHex": "AB CD AB CD" >> + } >> + } >> + ], >> + "timeseries": [ >> + { >> + "key": "rpm", >> + "nodeId": 1918, >> + "isExtendedId": true, >> + "command": "2:2:big:48059", >> + "value": "4:2:big:int", >> + "expression": "value / 4", >> + "polling": { >> + "type": "always", >> + "period": 5, >> + "dataInHex": "aaaa bbbb aaaa bbbb" >> + } >> + }, >> + { >> + "key": "milliage", >> + "nodeId": 1918, >> + "isExtendedId": true, >> + "value": "4:2:little:int", >> + "expression": "value * 10", >> + "polling": { >> + "type": "always", >> + "period": 30, >> + "dataInHex": "aa bb cc dd ee ff aa bb" >> + } >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "attributeOnThingsBoard": "softwareVersion", >> + "nodeId": 64, >> + "isExtendedId": true, >> + "dataLength": 4, >> + "dataExpression": "value + 5", >> + "dataByteorder": "little" >> + } >> + ], >> + "serverSideRpc": [ >> + { >> + "method": "sendSameData", >> + "nodeId": 4, >> + "isExtendedId": true, >> + "isFd": true, >> + "bitrateSwitch": true, >> + "dataInHex": "aa bb cc dd ee ff aa bb aa bb cc d ee ff" >> + }, >> + { >> + "method": "setLightLevel", >> + "nodeId": 5, >> + "dataLength": 2, >> + "dataByteorder": "little", >> + "dataBefore": "00AA" >> + }, >> + { >> + "method": "setSpeed", >> + "nodeId": 16, >> + "dataAfter": "0102", >> + "dataExpression": "userSpeed if maxAllowedSpeed > userSpeed >> else maxAllowedSpeed" >> + } >> + ] >> + } >> + ] >> + } >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/custom_serial.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/custom_serial.json >> new file mode 100755 >> index 0000000000..0aee5cb765 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/custom_serial.json >> @@ -0,0 +1,33 @@ >> +{ >> + "name": "Custom serial connector", >> + "devices": [ >> + { >> + "name": "CustomSerialDevice1", >> + "type": "default", >> + "port": "/dev/ttyUSB0", >> + "baudrate": 9600, >> + "converter": "CustomSerialUplinkConverter", >> + "telemetry": [ >> + { >> + "type": "byte", >> + "key": "humidity", >> + "untilDelimiter": "\r" >> + } >> + ], >> + "attributes":[ >> + { >> + "key": "SerialNumber", >> + "type": "string", >> + "fromByte": 4, >> + "toByte": -1 >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "attributeOnThingsBoard": "attr1", >> + "stringToDevice": "value = ${attr1}\n" >> + } >> + ] >> + } >> + ] >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/logs.conf >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/logs.conf >> new file mode 100755 >> index 0000000000..d66c2b84a8 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/logs.conf >> @@ -0,0 +1,77 @@ >> +[loggers] >> +keys=root, service, connector, converter, tb_connection, storage, extension >> +[handlers] >> +keys=consoleHandler, serviceHandler, connectorHandler, converterHandler, >> tb_connectionHandler, storageHandler, extensionHandler >> +[formatters] >> +keys=LogFormatter >> +[logger_root] >> +level=ERROR >> +handlers=consoleHandler >> +[logger_connector] >> +level=INFO >> +handlers=connectorHandler >> +formatter=LogFormatter >> +qualname=connector >> +[logger_storage] >> +level=INFO >> +handlers=storageHandler >> +formatter=LogFormatter >> +qualname=storage >> +[logger_tb_connection] >> +level=INFO >> +handlers=tb_connectionHandler >> +formatter=LogFormatter >> +qualname=tb_connection >> +[logger_service] >> +level=INFO >> +handlers=serviceHandler >> +formatter=LogFormatter >> +qualname=service >> +[logger_converter] >> +level=INFO >> +handlers=converterHandler >> +formatter=LogFormatter >> +qualname=converter >> +[logger_extension] >> +level=INFO >> +handlers=connectorHandler >> +formatter=LogFormatter >> +qualname=extension >> +[handler_consoleHandler] >> +class=StreamHandler >> +level=INFO >> +formatter=LogFormatter >> +args=(sys.stdout,) >> +[handler_connectorHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/connector.log", "d", 1, 7,) >> +[handler_storageHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/storage.log", "d", 1, 7,) >> +[handler_serviceHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/service.log", "d", 1, 7,) >> +[handler_converterHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/converter.log", "d", 1, 3,) >> +[handler_extensionHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/extension.log", "d", 1, 3,) >> +[handler_tb_connectionHandler] >> +level=INFO >> +class=logging.handlers.TimedRotatingFileHandler >> +formatter=LogFormatter >> +args=("./logs/tb_connection.log", "d", 1, 3,) >> +[formatter_LogFormatter] >> +format="%(asctime)s - %(levelname)s - [%(filename)s] - %(module)s - >> %(lineno)d - %(message)s" >> +datefmt="%Y-%m-%d %H:%M:%S" >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus.json >> new file mode 100755 >> index 0000000000..479d8aa4d0 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus.json >> @@ -0,0 +1,169 @@ >> +{ >> + "server": { >> + "type": "tcp", >> + "host": "127.0.0.1", >> + "port": 5020, >> + "timeout": 35, >> + "method": "socket", >> + "byteOrder": "BIG", >> + "devices": [ >> + { >> + "unitId": 1, >> + "deviceName": "Temp Sensor", >> + "attributesPollPeriod": 5000, >> + "timeseriesPollPeriod": 5000, >> + "sendDataOnlyOnChange": true, >> + "attributes": [ >> + { >> + "tag": "string_read", >> + "type": "string", >> + "functionCode": 4, >> + "objectsCount": 4, >> + "address": 1 >> + }, >> + { >> + "tag": "bits_read", >> + "type": "bits", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 5 >> + }, >> + { >> + "tag": "8int_read", >> + "type": "8int", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 6 >> + }, >> + { >> + "tag": "16int_read", >> + "type": "16int", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 7 >> + }, >> + { >> + "tag": "32int_read_divider", >> + "type": "32int", >> + "functionCode": 4, >> + "objectsCount": 2, >> + "address": 8, >> + "divider": 10 >> + }, >> + { >> + "tag": "8int_read_multiplier", >> + "type": "8int", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 10, >> + "multiplier": 10 >> + }, >> + { >> + "tag": "32int_read", >> + "type": "32int", >> + "functionCode": 4, >> + "objectsCount": 2, >> + "address": 11 >> + }, >> + { >> + "tag": "64int_read", >> + "type": "64int", >> + "functionCode": 4, >> + "objectsCount": 4, >> + "address": 13 >> + } >> + ], >> + "timeseries": [ >> + { >> + "tag": "8uint_read", >> + "type": "8uint", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 17 >> + }, >> + { >> + "tag": "16uint_read", >> + "type": "16uint", >> + "functionCode": 4, >> + "objectsCount": 2, >> + "address": 18 >> + }, >> + { >> + "tag": "32uint_read", >> + "type": "32uint", >> + "functionCode": 4, >> + "objectsCount": 4, >> + "address": 20 >> + }, >> + { >> + "tag": "64uint_read", >> + "type": "64uint", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 24 >> + }, >> + { >> + "tag": "16float_read", >> + "type": "16float", >> + "functionCode": 4, >> + "objectsCount": 1, >> + "address": 25 >> + }, >> + { >> + "tag": "32float_read", >> + "type": "32float", >> + "functionCode": 4, >> + "objectsCount": 2, >> + "address": 26 >> + }, >> + { >> + "tag": "64float_read", >> + "type": "64float", >> + "functionCode": 4, >> + "objectsCount": 4, >> + "address": 28 >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "tag": "shared_attribute_write", >> + "type": "32int", >> + "functionCode": 6, >> + "objectsCount": 2, >> + "address": 29 >> + } >> + ], >> + "rpc": [ >> + { >> + "tag": "setValue", >> + "type": "bits", >> + "functionCode": 5, >> + "objectsCount": 1, >> + "address": 31 >> + }, >> + { >> + "tag": "getValue", >> + "type": "bits", >> + "functionCode": 1, >> + "objectsCount": 1, >> + "address": 31 >> + }, >> + { >> + "tag": "setCPUFanSpeed", >> + "type": "32int", >> + "functionCode": 16, >> + "objectsCount": 2, >> + "address": 33 >> + }, >> + { >> + "tag":"getCPULoad", >> + "type": "32int", >> + "functionCode": 4, >> + "objectsCount": 2, >> + "address": 35 >> + } >> + ] >> + } >> + ] >> + } >> +} >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus_serial.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus_serial.json >> new file mode 100755 >> index 0000000000..19b38e3f7b >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/modbus_serial.json >> @@ -0,0 +1,29 @@ >> +{ >> + "server": { >> + "name": "Modbus Default Server", >> + "type": "serial", >> + "method": "rtu", >> + "port": "/dev/ttyUSB0", >> + "baudrate": 19200, >> + "timeout": 35, >> + "devices": [ >> + { >> + "unitId": 1, >> + "deviceName": "Temp Sensor", >> + "attributesPollPeriod": 5000, >> + "timeseriesPollPeriod": 5000, >> + "sendDataOnlyOnChange": true, >> + "attributes": [ >> + { >> + "byteOrder": "BIG", >> + "tag": "test", >> + "type": "long", >> + "functionCode": 4, >> + "registerCount": 1, >> + "address": 4 >> + } >> + ] >> + } >> + ] >> + } >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/mqtt.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/mqtt.json >> new file mode 100755 >> index 0000000000..6b78a7cec9 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/mqtt.json >> @@ -0,0 +1,132 @@ >> +{ >> + "broker": { >> + "name":"Default Local Broker", >> + "host":"127.0.0.1", >> + "port":1883, >> + "clientId": "ThingsBoard_gateway", >> + "security": { >> + "type": "basic", >> + "username": "user", >> + "password": "password" >> + } >> + }, >> + "mapping": [ >> + { >> + "topicFilter": "/sensor/data", >> + "converter": { >> + "type": "json", >> + "deviceNameJsonExpression": "${serialNumber}", >> + "deviceTypeJsonExpression": "${sensorType}", >> + "timeout": 60000, >> + "attributes": [ >> + { >> + "type": "string", >> + "key": "model", >> + "value": "${sensorModel}" >> + }, >> + { >> + "type": "string", >> + "key": "${sensorModel}", >> + "value": "on" >> + } >> + ], >> + "timeseries": [ >> + { >> + "type": "double", >> + "key": "temperature", >> + "value": "${temp}" >> + }, >> + { >> + "type": "double", >> + "key": "humidity", >> + "value": "${hum}" >> + } >> + ] >> + } >> + }, >> + { >> + "topicFilter": "/sensor/+/data", >> + "converter": { >> + "type": "json", >> + "deviceNameTopicExpression": "(?<=sensor\/)(.*?)(?=\/data)", >> + "deviceTypeTopicExpression": "Thermometer", >> + "timeout": 60000, >> + "attributes": [ >> + { >> + "type": "string", >> + "key": "model", >> + "value": "${sensorModel}" >> + } >> + ], >> + "timeseries": [ >> + { >> + "type": "double", >> + "key": "temperature", >> + "value": "${temp}" >> + }, >> + { >> + "type": "double", >> + "key": "humidity", >> + "value": "${hum}" >> + } >> + ] >> + } >> + }, >> + { >> + "topicFilter": "/custom/sensors/+", >> + "converter": { >> + "type": "custom", >> + "extension": "CustomMqttUplinkConverter", >> + "extension-config": { >> + "temperatureBytes" : 2, >> + "humidityBytes" : 2, >> + "batteryLevelBytes" : 1 >> + } >> + } >> + } >> + ], >> + "connectRequests": [ >> + { >> + "topicFilter": "sensor/connect", >> + "deviceNameJsonExpression": "${SerialNumber}" >> + }, >> + { >> + "topicFilter": "sensor/+/connect", >> + "deviceNameTopicExpression": "(?<=sensor\/)(.*?)(?=\/connect)" >> + } >> + ], >> + "disconnectRequests": [ >> + { >> + "topicFilter": "sensor/disconnect", >> + "deviceNameJsonExpression": "${SerialNumber}" >> + }, >> + { >> + "topicFilter": "sensor/+/disconnect", >> + "deviceNameTopicExpression": "(?<=sensor\/)(.*?)(?=\/disconnect)" >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "deviceNameFilter": "SmartMeter.*", >> + "attributeFilter": "uploadFrequency", >> + "topicExpression": "sensor/${deviceName}/${attributeKey}", >> + "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}" >> + } >> + ], >> + "serverSideRpc": [ >> + { >> + "deviceNameFilter": ".*", >> + "methodFilter": "echo", >> + "requestTopicExpression": >> "sensor/${deviceName}/request/${methodName}/${requestId}", >> + "responseTopicExpression": >> "sensor/${deviceName}/response/${methodName}/${requestId}", >> + "responseTimeout": 10000, >> + "valueExpression": "${params}" >> + }, >> + { >> + "deviceNameFilter": ".*", >> + "methodFilter": "no-reply", >> + "requestTopicExpression": >> "sensor/${deviceName}/request/${methodName}/${requestId}", >> + "valueExpression": "${params}" >> + } >> + ] >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/odbc.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/odbc.json >> new file mode 100644 >> index 0000000000..c93992a262 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/odbc.json >> @@ -0,0 +1,54 @@ >> +{ >> + "connection": { >> + "str": >> "Driver={PostgreSQL};Server=localhost;Port=5432;Database=thingsboard;Uid=postgres;Pwd=postgres;", >> + "attributes": { >> + "autocommit": true, >> + "timeout": 0 >> + }, >> + "encoding": "utf-8", >> + "decoding": { >> + "char": "utf-8", >> + "wchar": "utf-8", >> + "metadata": "utf-16le" >> + }, >> + "reconnect": true, >> + "reconnectPeriod": 60 >> + }, >> + "pyodbc": { >> + "pooling": false >> + }, >> + "polling": { >> + "query": "SELECT bool_v, str_v, dbl_v, long_v, entity_id, ts FROM >> ts_kv WHERE ts > ? ORDER BY ts ASC LIMIT 10", >> + "period": 10, >> + "iterator": { >> + "column": "ts", >> + "query": "SELECT MIN(ts) - 1 FROM ts_kv", >> + "persistent": false >> + } >> + }, >> + "mapping": { >> + "device": { >> + "type": "postgres", >> + "name": "'ODBC ' + entity_id" >> + }, >> + "sendDataOnlyOnChange": false, >> + "attributes": "*", >> + "timeseries": [ >> + { >> + "name": "value", >> + "value": "[i for i in [str_v, long_v, dbl_v,bool_v] if i is not >> None][0]" >> + } >> + ] >> + }, >> + "serverSideRpc": { >> + "enableUnknownRpc": false, >> + "overrideRpcConfig": true, >> + "methods": [ >> + "procedureOne", >> + { >> + "name": "procedureTwo", >> + "args": [ "One", 2, 3.0 ] >> + } >> + ] >> + } >> + } >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/opcua.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/opcua.json >> new file mode 100755 >> index 0000000000..1deed7d524 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/opcua.json >> @@ -0,0 +1,49 @@ >> +{ >> + "server": { >> + "name": "OPC-UA Default Server", >> + "url": "localhost:4840/freeopcua/server/", >> + "timeoutInMillis": 5000, >> + "scanPeriodInMillis": 5000, >> + "disableSubscriptions":false, >> + "subCheckPeriodInMillis": 100, >> + "showMap": false, >> + "security": "Basic128Rsa15", >> + "identity": { >> + "type": "anonymous" >> + }, >> + "mapping": [ >> + { >> + "deviceNodePattern": "Root\\.Objects\\.Device1", >> + "deviceNamePattern": "Device >> ${Root\\.Objects\\.Device1\\.serialNumber}", >> + "attributes": [ >> + { >> + "key": "temperature °C", >> + "path": "${ns=2;i=5}" >> + } >> + ], >> + "timeseries": [ >> + { >> + "key": "humidity", >> + "path": >> "${Root\\.Objects\\.Device1\\.TemperatureAndHumiditySensor\\.Humidity}" >> + }, >> + { >> + "key": "batteryLevel", >> + "path": "${Battery\\.batteryLevel}" >> + } >> + ], >> + "rpc_methods": [ >> + { >> + "method": "multiply", >> + "arguments": [2, 4] >> + } >> + ], >> + "attributes_updates": [ >> + { >> + "attributeOnThingsBoard": "deviceName", >> + "attributeOnDevice": "Root\\.Objects\\.Device1\\.serialNumber" >> + } >> + ] >> + } >> + ] >> + } >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/request.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/request.json >> new file mode 100644 >> index 0000000000..43237a7dc0 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/request.json >> @@ -0,0 +1,146 @@ >> +"job": "leader" >> +}, >> +"allowRedirects": true, >> +"timeout": 0.5, >> +"scanPeriod": 5, >> +"converter": { >> + "type": "json", >> + "deviceNameJsonExpression": "SD8500", >> + "deviceTypeJsonExpression": "SD", >> + "attributes": [ >> + { >> + "key": "serialNumber", >> + "type": "string", >> + "value": "${serial}" >> + } >> + ], >> + "telemetry": [ >> + { >> + "key": "Maintainer", >> + "type": "string", >> + "value": "${Developer}" >> + } >> + ] >> +} >> +}, >> +{ >> +"url": "get_info", >> +"httpMethod": "GET", >> +"httpHeaders": { >> + "ACCEPT": "application/json" >> +}, >> +"allowRedirects": true, >> +"timeout": 0.5, >> +"scanPeriod": 100, >> +"converter": { >> + "type": "custom", >> + "deviceNameJsonExpression": "SD8500", >> + "deviceTypeJsonExpression": "SD", >> + "extension": "CustomRequestUplinkConverter", >> + "extension-config": [ >> + { >> + "key": "Totaliser", >> + "type": "float", >> + "fromByte": 0, >> + "toByte": 4, >> + "byteorder": "big", >> + "signed": true, >> + "multiplier": 1 >> + }, >> + { >> + "key": "Flow", >> + "type": "int", >> + "fromByte": 4, >> + "toByte": 6, >> + "byteorder": "big", >> + "signed": true, >> + "multiplier": 0.01 >> + }, >> + { >> + "key": "Temperature", >> + "type": "int", >> + "fromByte": 8, >> + "toByte": 10, >> + "byteorder": "big", >> + "signed": true, >> + "multiplier": 0.01 >> + }, >> + { >> + "key": "Pressure", >> + "type": "int", >> + "fromByte": 12, >> + "toByte": 14, >> + "byteorder": "big", >> + "signed": true, >> + "multiplier": 0.01 >> + }, >> + { >> + "key": "deviceStatus", >> + "type": "int", >> + "byteAddress": 15, >> + "fromBit": 4, >> + "toBit": 8, >> + "byteorder": "big", >> + "signed": false >> + }, >> + { >> + "key": "OUT2", >> + "type": "int", >> + "byteAddress": 15, >> + "fromBit": 1, >> + "toBit": 2, >> + "byteorder": "big" >> + }, >> + { >> + "key": "OUT1", >> + "type": "int", >> + "byteAddress": 15, >> + "fromBit": 0, >> + "toBit": 1, >> + "byteorder": "big" >> + } >> + ] >> +} >> +} >> +], >> +"attributeUpdates": [ >> +{ >> + "httpMethod": "POST", >> + "httpHeaders": { >> + "CONTENT-TYPE": "application/json" >> + }, >> + "timeout": 0.5, >> + "tries": 3, >> + "allowRedirects": true, >> + "deviceNameFilter": "SD.*", >> + "attributeFilter": "send_data", >> + "requestUrlExpression": "sensor/${deviceName}/${attributeKey}", >> + "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}" >> +} >> +], >> +"serverSideRpc": [ >> +{ >> +"deviceNameFilter": ".*", >> +"methodFilter": "echo", >> +"requestUrlExpression": >> "sensor/${deviceName}/request/${methodName}/${requestId}", >> +"responseTimeout": 1, >> +"httpMethod": "GET", >> +"valueExpression": "${params}", >> +"timeout": 0.5, >> +"tries": 3, >> +"httpHeaders": { >> + "Content-Type": "application/json" >> +} >> +}, >> +{ >> +"deviceNameFilter": ".*", >> +"methodFilter": "no-reply", >> +"requestUrlExpression": >> "sensor/${deviceName}/request/${methodName}/${requestId}", >> +"httpMethod": "POST", >> +"valueExpression": "${params}", >> +"httpHeaders": { >> + "Content-Type": "application/json" >> +} >> +} >> +] >> +} >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/rest.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/rest.json >> new file mode 100644 >> index 0000000000..be6c6ff18e >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/rest.json >> @@ -0,0 +1,152 @@ >> +{ >> + "host": "127.0.0.1", >> + "port": "5000", >> + "mapping":[ >> + { >> + "endpoint": "/device1", >> + "HTTPMethods": [ >> + "POST" >> + ], >> + "security": >> + { >> + "type": "basic", >> + "username": "user", >> + "password": "passwd" >> + }, >> + "converter": { >> + "type": "json", >> + "deviceNameExpression": "Device ${name}", >> + "deviceTypeExpression": "default", >> + "attributes": [ >> + { >> + "type": "string", >> + "key": "model", >> + "value": "${sensorModel}" >> + } >> + ], >> + "timeseries": [ >> + { >> + "type": "double", >> + "key": "${sensorModel}", >> + "value": "${temp}" >> + }, >> + { >> + "type": "double", >> + "key": "humidity", >> + "value": "${hum}" >> + } >> + ] >> + } >> + }, >> + { >> + "endpoint": "/anon1", >> + "HTTPMethods": [ >> + "GET", >> + "POST" >> + ], >> + "security": >> + { >> + "type": "anonymous" >> + }, >> + "converter": { >> + "type": "json", >> + "deviceNameExpression": "Device 2", >> + "deviceTypeExpression": "default", >> + "attributes": [ >> + { >> + "type": "string", >> + "key": "model", >> + "value": "Model2" >> + } >> + ], >> + "timeseries": [ >> + { >> + "type": "double", >> + "key": "temperature", >> + "value": "${temp}" >> + }, >> + { >> + "type": "double", >> + "key": "humidity", >> + "value": "${hum}" >> + } >> + ] >> + } >> + }, >> + { >> + "endpoint": "/anon2", >> + "HTTPMethods": [ >> + "POST" >> + ], >> + "security": >> + { >> + "type": "anonymous" >> + }, >> + "converter": { >> + "type": "custom", >> + "deviceNameExpression": "SuperAnonDevice", >> + "deviceTypeExpression": "default", >> + "extension": "CustomRestUplinkConverter", >> + "extension-config": [ >> + { >> + "key": "Totaliser", >> + "datatype": "float", >> + "fromByte": 0, >> + "toByte": 4, >> + "byteorder": "big", >> + "signed": true, >> + "multiplier": 1 >> + }] >> + } >> + } >> + ], >> + "attributeUpdates": [ >> + { >> + "HTTPMethod": "POST", >> + "SSLVerify": false, >> + "httpHeaders": { >> + "CONTENT-TYPE": "application/json" >> + }, >> + "security": { >> + "type": "basic", >> + "username": "user", >> + "password": "passwd" >> + }, >> + "timeout": 0.5, >> + "tries": 3, >> + "allowRedirects": true, >> + "deviceNameFilter": ".*REST$", >> + "attributeFilter": "data", >> + "requestUrlExpression": "sensor/${deviceName}/${attributeKey}", >> + "valueExpression": "{\"${attributeKey}\":\"${attributeValue}\"}" >> + } >> + ], >> + "serverSideRpc": [ >> + { >> + "deviceNameFilter": ".*", >> + "methodFilter": "echo", >> + "requestUrlExpression": "http://127.0.0.1:5001/${deviceName}", >> + "responseTimeout": 1, >> + "HTTPMethod": "GET", >> + "valueExpression": "${params}", >> + "timeout": 0.5, >> + "tries": 3, >> + "httpHeaders": { >> + "Content-Type": "application/json" >> + }, >> + "security": { >> + "type": "anonymous" >> + } >> + }, >> + { >> + "deviceNameFilter": ".*", >> + "methodFilter": "no-reply", >> + "requestUrlExpression": >> "sensor/${deviceName}/request/${methodName}/${requestId}", >> + "HTTPMethod": "POST", >> + "valueExpression": "${params}", >> + "httpHeaders": { >> + "Content-Type": "application/json" >> + } >> + } >> + ] >> + } >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/snmp.json >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/snmp.json >> new file mode 100644 >> index 0000000000..b4ddb42645 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/snmp.json >> @@ -0,0 +1,138 @@ >> +{ >> + "devices": [ >> + { >> + "deviceName": "SNMP router", >> + "deviceType": "snmp", >> + "ip": "snmp.live.gambitcommunications.com", >> + "port": 161, >> + "pollPeriod": 5000, >> + "community": "public", >> + "attributes": [ >> + { >> + "key": "ReceivedFromGet", >> + "method": "get", >> + "oid": "1.3.6.1.2.1.1.1.0", >> + "timeout": 6 >> + }, >> + { >> + "key": "ReceivedFromMultiGet", >> + "method": "multiget", >> + "oid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.1.2.1.1.2.0" >> + ], >> + "timeout": 6 >> + }, >> + { >> + "key": "ReceivedFromGetNext", >> + "method": "getnext", >> + "oid": "1.3.6.1.2.1.1.1.0", >> + "timeout": 6 >> + }, >> + { >> + "key": "ReceivedFromMultiWalk", >> + "method": "multiwalk", >> + "oid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.0.1.2.1" >> + ] >> + }, >> + { >> + "key": "ReceivedFromBulkWalk", >> + "method": "bulkwalk", >> + "oid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.1.2.1.1.2.0" >> + ] >> + }, >> + { >> + "key": "ReceivedFromBulkGet", >> + "method": "bulkget", >> + "scalarOid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.1.2.1.1.2.0" >> + ], >> + "repeatingOid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.1.2.1.1.2.0" >> + ], >> + "maxListSize": 10 >> + } >> + ], >> + "telemetry": [ >> + { >> + "key": "ReceivedFromWalk", >> + "community": "private", >> + "method": "walk", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + }, >> + { >> + "key": "ReceivedFromTable", >> + "method": "table", >> + "oid": "1.3.6.1.2.1.1" >> + } >> + ], >> + "attributeUpdateRequests": [ >> + { >> + "attributeFilter": "dataToSet", >> + "method": "set", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + }, >> + { >> + "attributeFilter": "dataToMultiSet", >> + "method": "multiset", >> + "mappings": { >> + "1.2.3": "10", >> + "2.3.4": "${attribute}" >> + } >> + } >> + ], >> + "serverSideRpcRequests": [ >> + { >> + "requestFilter": "setData", >> + "method": "set", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + }, >> + { >> + "requestFilter": "multiSetData", >> + "method": "multiset" >> + }, >> + { >> + "requestFilter": "getData", >> + "method": "get", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + }, >> + { >> + "requestFilter": "runBulkWalk", >> + "method": "bulkwalk", >> + "oid": [ >> + "1.3.6.1.2.1.1.1.0", >> + "1.3.6.1.2.1.1.2.0" >> + ] >> + } >> + ] >> + }, >> + { >> + "deviceName": "SNMP router", >> + "deviceType": "snmp", >> + "ip": "127.0.0.1", >> + "pollPeriod": 5000, >> + "community": "public", >> + "converter": "CustomSNMPConverter", >> + "attributes": [ >> + { >> + "key": "ReceivedFromGetWithCustomConverter", >> + "method": "get", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + } >> + ], >> + "telemetry": [ >> + { >> + "key": "ReceivedFromTableWithCustomConverter", >> + "method": "table", >> + "oid": "1.3.6.1.2.1.1.1.0" >> + } >> + ] >> + } >> + ] >> + } >> \ No newline at end of file >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/tb_gateway.yaml >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/tb_gateway.yaml >> new file mode 100755 >> index 0000000000..e3eb8f1fc7 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/tb_gateway.yaml >> @@ -0,0 +1,66 @@ >> +thingsboard: >> + host: demo.thingsboard.io >> + port: 1883 >> + remoteConfiguration: false >> + security: >> + accessToken: PUT_YOUR_GW_ACCESS_TOKEN_HERE >> +storage: >> + type: memory >> + read_records_count: 100 >> + max_records_count: 100000 >> +# type: file >> +# data_folder_path: ./data/ >> +# max_file_count: 10 >> +# max_read_records_count: 10 >> +# max_records_per_file: 10000 >> +connectors: >> + - >> + name: MQTT Broker Connector >> + type: mqtt >> + configuration: mqtt.json >> + >> +# - >> +# name: Modbus Connector >> +# type: modbus >> +# configuration: modbus.json >> +# >> +# - >> +# name: Modbus Connector >> +# type: modbus >> +# configuration: modbus_serial.json >> +# >> +# - >> +# name: OPC-UA Connector >> +# type: opcua >> +# configuration: opcua.json >> +# >> +# - >> +# name: BLE Connector >> +# type: ble >> +# configuration: ble.json >> +# >> +# - >> +# name: REQUEST Connector >> +# type: request >> +# configuration: request.json >> +# >> +# - >> +# name: CAN Connector >> +# type: can >> +# configuration: can.json >> +# >> +# - >> +# name: BACnet Connector >> +# type: bacnet >> +# configuration: bacnet.json >> +# >> +# - >> +# name: ODBC Connector >> +# type: odbc >> +# configuration: odbc.json >> +# >> +# - >> +# name: Custom Serial Connector >> +# type: serial >> +# configuration: custom_serial.json >> +# class: CustomSerialConnector >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/thingsboard-gateway.service >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/thingsboard-gateway.service >> new file mode 100644 >> index 0000000000..5dd352a553 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway/thingsboard-gateway.service >> @@ -0,0 +1,13 @@ >> +[Unit] >> +Description = Systemd service for Thingsboard Gateway >> +After = network.target >> + >> +[Service] >> +ExecStart = /usr/bin/python3 /usr/bin/thingsboard-gateway >> +ExecStop = /bin/kill -INT $MAINPID >> +ExecReload = /bin/kill -TERM $MAINPID >> +Restart = always >> +Type = simple >> + >> +[Install] >> +WantedBy=multi-user.target >> diff --git >> a/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway_2.5.2.bb >> >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway_2.5.2.bb >> new file mode 100644 >> index 0000000000..2f0ef16c80 >> --- /dev/null >> +++ >> b/meta-oe/recipes-connectivity/thingsboard-gateway/thingsboard-gateway_2.5.2.bb >> @@ -0,0 +1,68 @@ >> +SUMMARY = "Open-source IoT platform for data collection, processing, >> visualization, and device management" >> +DESCRIPTION = "\ >> +The Thingsboard IoT Gateway is an open-source solution that allows you \ >> +to integrate devices connected to legacy and third-party systems with >> Thingsboard." >> +HOMEPAGE = "https://thingsboard.io/" >> + >> +LICENSE = "Apache-2.0" >> +LIC_FILES_CHKSUM = >> "file://${COMMON_LICENSE_DIR}/Apache-2.0;md5=89aea4e17d99a7cacdbeed46a0096b10" >> + >> +SRC_URI[md5sum] = "469c8b5cd1c16c20ef40f0a97a3a0fda" >> +SRC_URI[sha256sum] = >> "b328f4e315c3541ac80a4931974a34a81afe4d1f382f48e8604669a55816c0d7" >> + >> +inherit pypi setuptools3 >> + >> +PYPI_PACKAGE = "thingsboard-gateway" >> + >> +RDEPENDS_${PN} += " python3-jsonpath-rw \ >> + python3-regex \ >> + python3-paho-mqtt \ >> + python3-pyyaml \ >> + python3-simplejson \ >> + python3-requests \ >> + python3-pip \ >> + python3-pyrsistent \ >> +" >> + >> +SRC_URI += "file://bacnet.json \ >> + file://ble.json \ >> + file://can.json \ >> + file://custom_serial.json \ >> + file://modbus.json \ >> + file://modbus_serial.json \ >> + file://mqtt.json \ >> + file://opcua.json \ >> + file://odbc.json \ >> + file://request.json \ >> + file://rest.json \ >> + file://snmp.json \ >> + file://tb_gateway.yaml \ >> + file://logs.conf \ >> + file://thingsboard-gateway.service \ >> + " >> + >> + >> +inherit systemd >> + >> +SYSTEMD_PACKAGES = "${PN}" >> +SYSTEMD_SERVICE_${PN} = "thingsboard-gateway.service" >> + >> +FILES_${PN} += "/etc \ >> + /lib \ >> + /usr \ >> +" >> + >> +do_install_append(){ >> + >> + install -d ${D}${sysconfdir}/thingsboard-gateway/config >> + >> + for file in $(find ${WORKDIR} -maxdepth 1 -type f -name *.json); do >> + install -m 0644 "$file" ${D}${sysconfdir}/thingsboard-gateway/config >> + done >> + >> + install -m 0644 ${WORKDIR}/tb_gateway.yaml >> ${D}${sysconfdir}/thingsboard-gateway/config >> + install -m 0644 ${WORKDIR}/logs.conf >> ${D}${sysconfdir}/thingsboard-gateway/config >> + >> + install -d ${D}${systemd_unitdir}/system/ >> + install -m 0644 ${WORKDIR}/thingsboard-gateway.service >> ${D}${systemd_system_unitdir}/thingsboard-gateway.service >> +} >> \ No newline at end of file >> -- >> 2.29.2 >> >> >>
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#88021): https://lists.openembedded.org/g/openembedded-devel/message/88021 Mute This Topic: https://lists.openembedded.org/mt/78328694/21656 Group Owner: openembedded-devel+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-