Skip to content

Commit

Permalink
feat: Add KOSTAL INVEOR (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexandershalin authored Oct 18, 2023
1 parent fbb815c commit da0c42e
Show file tree
Hide file tree
Showing 7 changed files with 275 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .categories/motor_controllers.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
10 changes: 10 additions & 0 deletions .marketplace/devices/devices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,16 @@
- blueprint: hvac/vitobloc
verification_level: ready_for_testing

- id: inveor
display_name: KOSTAL INVEOR MP/MP Modular/MPP/M
description: Variable frequency drive.
icon: enapter-motor-controller
vendor: kostal
category: motor_controllers
blueprint_options:
- blueprint: motor_controllers/kostal_inveor
verification_level: ready_for_testing

- id: igd_toc_635
display_name: IGD TOC 635
description: Addressable gas-detector control panel.
Expand Down
Binary file added .marketplace/vendors/icons/kostal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions .marketplace/vendors/vendors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,11 @@
icon_url: https://raw.githubusercontent.com/Enapter/marketplace/main/.marketplace/vendors/icons/viessmann.png
website: https://www.viessmann.family/

- id: kostal
display_name: KOSTAL
icon_url: https://raw.githubusercontent.com/Enapter/marketplace/main/.marketplace/vendors/icons/kostal.png
website: https://www.kostal.com/

- id: igd
display_name: International Gas Detectors Ltd
icon_url: https://raw.githubusercontent.com/Enapter/marketplace/main/.marketplace/vendors/icons/igd.png
Expand Down
15 changes: 15 additions & 0 deletions motor_controllers/kostal_inveor/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# KOSTAL INVEOR MP/MP Modular/MPP/M

This [Enapter Device Blueprint](https://go.enapter.com/marketplace-readme) integrates **KOSTAL INVEOR** - variable frequency drives with [ModBus RTU](https://go.enapter.com/developers-enapter-modbus) over [RS-485 communication interface](https://go.enapter.com/developers-enapter-rs485).

## Connect to Enapter

- Sign up to the Enapter Cloud using the [Web](https://cloud.enapter.com/) or mobile app ([iOS](https://apps.apple.com/app/id1388329910), [Android](https://play.google.com/store/apps/details?id=com.enapter&hl=en)).
- Use the [Enapter ENP-RS485](https://go.enapter.com/handbook-enp-rs485) module for physical connection. See [connection instructions](https://go.enapter.com/handbook-enp-rs485-conn) in the module manual.
- [Add ENP-RS485 to your site](https://go.enapter.com/handbook-mobile-app) using the mobile app.
- [Upload](https://go.enapter.com/developers-upload-blueprint) this blueprint to ENP-RS485.

## References

- [KOSTAL INVEOR Products Page](https://go.enapter.com/kostal_inveor_products_page)
- [KOSTAL INVEOR Modbus Manual](https://go.enapter.com/kostal_inveor_modbus_manual)
115 changes: 115 additions & 0 deletions motor_controllers/kostal_inveor/firmware.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
local config = require('enapter.ucm.config')

ADDRESS_CONFIG = 'address'
BAUDRATE_CONFIG = 'baudrate'
DATA_BITS_CONFIG = 'data_bits'
STOP_BITS_CONFIG = 'stop_bits'
PARITY_CONFIG = 'parity_bits'

function main()
config.init({
[ADDRESS_CONFIG] = { type = 'number', required = true, default = 1 },
[BAUDRATE_CONFIG] = { type = 'number', required = true, default = 9600 },
[DATA_BITS_CONFIG] = { type = 'number', required = true, default = 8 },
[STOP_BITS_CONFIG] = { type = 'number', required = true, default = 1 },
[PARITY_CONFIG] = { type = 'string', required = true, default = 'N' },
})

local values, err = config.read_all()
if err then
enapter.log('cannot read config: ' .. tostring(err), 'error')
return nil, 'cannot_read_config'
else
for _, value in pairs(values) do
if not value then
return nil, 'not_configured'
end
end
end

local baudrate = values[BAUDRATE_CONFIG]
local data_bits = values[DATA_BITS_CONFIG]
local parity_bits = values[PARITY_CONFIG]
local stop_bits = values[STOP_BITS_CONFIG]

local result = rs485.init(baudrate, data_bits, parity_bits, stop_bits)
if result ~= 0 then
enapter.log('RS485 init failed: ' .. result .. ' ' .. rs485.err_to_str(result), 'error', true)
end

scheduler.add(30000, send_properties)
scheduler.add(1000, send_telemetry)
end

function send_properties()
enapter.send_properties({ vendor = 'KOSTAL', model = 'INVEOR' })
end

function send_telemetry()
local telemetry = {}
local status = 'ok'

local values, err = config.read_all()
if err then
enapter.log('cannot read config: ' .. tostring(err), 'error')
return nil, 'cannot_read_config'
else
for _, value in pairs(values) do
if not value then
return nil, 'not_configured'
end
end
end

local address = values[ADDRESS_CONFIG]

local data, result = modbus.read_inputs(address, 1999, 2, 1000) -- REAL
if data then
telemetry['actual_freq'] = tofloat(data)
else
enapter.log('Register 1999 reading failed: ' .. modbus.err_to_str(result))
status = 'read_error'
end

local data, result = modbus.read_inputs(address, 2001, 2, 1000) -- REAL
if data then
telemetry['output_volt'] = tofloat(data)
else
enapter.log('Register 2001 reading failed: ' .. modbus.err_to_str(result))
status = 'read_error'
end

local data, result = modbus.read_inputs(address, 2003, 2, 1000) -- REAL
if data then
telemetry['motor_curr'] = tofloat(data) * telemetry['volt_l1n']
else
enapter.log('Register 2003 reading failed: ' .. modbus.err_to_str(result))
status = 'read_error'
end

local data, result = modbus.read_inputs(address, 2009, 2, 1000) -- REAL
if data then
telemetry['target_freq'] = tofloat(data)
else
enapter.log('Register 2009 reading failed: ' .. modbus.err_to_str(result))
status = 'read_error'
end

local data, result = modbus.read_inputs(address, 2015, 2, 1000) -- REAL
if data then
telemetry['inner_temp'] = tofloat(data)
else
enapter.log('Register 2015 reading failed: ' .. modbus.err_to_str(result))
status = 'read_error'
end

telemetry['status'] = status
enapter.send_telemetry(telemetry)
end

function tofloat(register)
local raw_str = string.pack('BBBB', register[1] >> 8, register[1] & 0xff, register[2] >> 8, register[2] & 0xff)
return string.unpack('>f', raw_str)
end

main()
124 changes: 124 additions & 0 deletions motor_controllers/kostal_inveor/manifest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
blueprint_spec: device/1.0

display_name: KOSTAL INVEOR
description: Variable frequency drive and motor controller
icon: enapter-motor-controller
vendor: kostal
author: enapter
contributors:
- anataty
- alexandershalin
support:
url: https://go.enapter.com/enapter-blueprint-support
email: support@enapter.com
license: MIT
verification_level: ready_for_testing

communication_module:
product: ENP-RS485
lua:
file: firmware.lua
dependencies:
- enapter-ucm ~> 0.3.2-1

properties:
vendor:
type: string
display_name: Vendor
model:
type: string
display_name: Model

telemetry:
status:
display_name: Status
type: string
enum:
- ok
- read_error
target_freq:
type: float
unit: Hz
display_name: Target Frequency
actual_freq:
type: float
unit: Hz
display_name: Actual Frequency
output_volt:
type: float
unit: V
display_name: Output Voltage
motor_curr:
type: float
unit: A
display_name: Motor Current
inner_temp:
type: float
unit: Β°C
display_name: Inner Temperature

command_groups:
config:
display_name: Configuration
commands:
write_configuration:
populate_values_command: read_configuration
display_name: Configure
group: config
ui:
icon: wrench-outline
arguments:
address:
display_name: Modbus address
description: 1-247
type: integer
min: 1
max: 247
required: true
baudrate:
display_name: Baudrate
type: integer
required: true
enum:
- 9600
- 19200
- 38400
- 57600
- 115200
- 2400
- 4800
data_bits:
display_name: Data bits
type: integer
required: true
enum:
- 8
parity_bits:
display_name: None
type: string
enum:
- N
- O
- E
required: true
stop_bits:
display_name: Stop bits
type: integer
required: true
enum:
- 1
- 2
read_configuration:
display_name: Read Configuration
group: config
ui:
icon: wrench-outline

.cloud:
category: power_meters
mobile_telemetry:
- target_freq
- actual_freq
- output_volt
- motor_curr
- inner_temp

0 comments on commit da0c42e

Please sign in to comment.