Skip to content

Instantly share code, notes, and snippets.

@danielolsson100
Created November 11, 2024 18:55
Show Gist options
  • Save danielolsson100/f20cb9a01c11b9ea5850ccc4bff8d0c5 to your computer and use it in GitHub Desktop.
Save danielolsson100/f20cb9a01c11b9ea5850ccc4bff8d0c5 to your computer and use it in GitHub Desktop.
Ferroamp Modbus TCP
# Cred: Robin Östlund for the mapping
# Ref: https://ferroamp.com/wp-content/uploads/2023/04/Ferroamp-Modbus-TCP-Specification-RevD-2.pdf
---
modbus:
- name: ferroamp_modbus
type: tcp
host: 192.168.0.XXX
port: 502
delay: 5
message_wait_milliseconds: 30
timeout: 5
binary_sensors:
# Grid Power Data
- name: Ferroamp Limit Import System Value
address: 8000
scan_interval: 5
slave: 1
input_type: input
- name: Ferroamp Limit Export System Value
address: 8010
scan_interval: 5
slave: 1
input_type: input
sensors:
## Energy Hub Inverter Data
- name: Ferroamp Inverter Status
address: 2000
data_type: uint16
scan_interval: 1
state_class: measurement
device_class: enum
slave: 1
input_type: input
- name: Ferroamp Grid Frequency
address: 2016
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: Hz
state_class: measurement
device_class: frequency
slave: 1
input_type: input
- name: Ferroamp Grid Voltage L1
address: 2032
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: V
state_class: measurement
device_class: voltage
slave: 1
input_type: input
- name: Ferroamp Grid Voltage L2
address: 2036
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: V
state_class: measurement
device_class: voltage
slave: 1
input_type: input
- name: Ferroamp Grid Voltage L3
address: 2040
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: V
state_class: measurement
device_class: voltage
slave: 1
input_type: input
- name: Ferroamp Energy To DC-Nanogrid
address: 2064
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Energy From DC-Nanogrid
address: 2068
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Inverter Active Power
address: 2100
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kW
state_class: measurement
device_class: power
slave: 1
input_type: input
- name: Ferroamp Inverter Reactive Power
address: 2104
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kVAr
state_class: measurement
device_class: reactive_power
slave: 1
input_type: input
- name: Ferroamp Inverter Apparent Power
address: 2108
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kVa
state_class: measurement
device_class: apparent_power
slave: 1
input_type: input
- name: Ferroamp Inverter Active Current L1
address: 2112
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter Active Current L2
address: 2116
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter Active Current L3
address: 2120
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter Reactive Current L1
address: 2124
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter Reactive Current L2
address: 2128
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter Reactive Current L3
address: 2132
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter RMS Current L1
address: 2136
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter RMS Current L2
address: 2140
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Inverter RMS Current L3
address: 2144
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
## Energyhub facility Data
- name: Ferroamp Energy Exported To Grid
address: 3064
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
# state_class: measurement
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Energy Imported To Grid
address: 3068
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
# state_class: measurement
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Grid Active Power
address: 3100
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kW
state_class: measurement
device_class: power
slave: 1
input_type: input
- name: Ferroamp Grid Reactive Power
address: 3104
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kVAr
state_class: measurement
device_class: reactive_power
slave: 1
input_type: input
- name: Ferroamp Grid Apparent Power
address: 3108
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kVA
state_class: measurement
device_class: apparent_power
slave: 1
input_type: input
- name: Ferroamp Grid Active Current L1
address: 3112
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid Active Current L2
address: 3116
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid Active Current L3
address: 3120
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid Reactive Current L1
address: 3124
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid Reactive Current L2
address: 3128
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid Reactive Current L3
address: 3132
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid RMS Current L1
address: 3136
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid RMS Current L2
address: 3140
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
- name: Ferroamp Grid RMS Current L3
address: 3144
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: A
state_class: measurement
device_class: current
slave: 1
input_type: input
## PV Data
- name: Ferroamp Number Of Idle SSOs
address: 5000
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Number Of Running SSOs
address: 5002
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Number Of Faulty SSOs
address: 5004
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Energy Produced
address: 5064
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
# state_class: measurement
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Solar Power
address: 5100
data_type: float32
swap: word
scan_interval: 2
unit_of_measurement: kW
state_class: measurement
device_class: power
slave: 1
input_type: input
## Battery Control
- name: Ferroamp Battery Mode
address: 6000
data_type: uint16
scan_interval: 60
state_class: measurement
device_class: enum
slave: 1
input_type: holding
- name: Ferroamp Battery Power Reference
address: 6064
data_type: float32
swap: word
scan_interval: 2
unit_of_measurement: kW
state_class: measurement
device_class: power
slave: 1
input_type: holding
## Battery Data
- name: Ferroamp Number Of Idle Batteries
address: 6000
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Number Of Running Batteries
address: 6002
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Number Of Faulty Batteries
#address: 6068
address: 6004
data_type: uint16
scan_interval: 5
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Rated Capacity
address: 6008
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
state_class: measurement
device_class: energy_storage
slave: 1
input_type: input
- name: Ferroamp State Of Health
address: 6012
data_type: float32
swap: word
scan_interval: 2
unit_of_measurement: "%"
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp State Of Charge
address: 6016
data_type: float32
swap: word
scan_interval: 2
unit_of_measurement: "%"
state_class: measurement
device_class: battery
slave: 1
input_type: input
- name: Ferroamp Energy From Battery
address: 6064
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
# state_class: measurement
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Energy To Battery
address: 6068
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kWh
# state_class: measurement
state_class: total_increasing
device_class: energy
slave: 1
input_type: input
- name: Ferroamp Battery Power
address: 6100
data_type: float32
swap: word
scan_interval: 2
unit_of_measurement: kW
state_class: measurement
device_class: power
slave: 1
input_type: input
- name: Ferroamp Battery Mode System Value
address: 6104
data_type: uint16
scan_interval: 5
state_class: measurement
device_class: enum
slave: 1
input_type: input
- name: Ferroamp Battery Power Reference System Value
address: 6106
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: kW
state_class: measurement
# device_class: energy
device_class: power
slave: 1
input_type: input
## Grid Power Control
# TODO
## Grid Power Data
- name: Ferroamp Import Threshold System Value
address: 8002
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: W
device_class: power
state_class: measurement
slave: 1
input_type: input
- name: Ferroamp Export Threshold System Value
address: 8012
data_type: float32
swap: word
scan_interval: 5
unit_of_measurement: W
device_class: power
state_class: measurement
slave: 1
input_type: input
template:
- number:
- name: Ferroamp Battery Control
state: "{{ float(states('sensor.ferroamp_battery_power_reference'), 0) * 1000 }}"
availability: "{{ is_number(states('sensor.ferroamp_battery_power_reference')) }}"
set_value:
# set battery power reference
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 6064
slave: 1
value: >
{% set value = (value | float(0) / 1000) %}
{% set packed_value = pack(value, ">f") %}
{% set high_word = unpack(packed_value, ">H", offset=2) | abs %}
{% set low_word = unpack(packed_value, ">H") | abs %}
[ {{ high_word }}, {{ low_word }} ]
# set battery to power mode
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 6000
slave: 1
value: >-
{% if value == 0 %} 0
{% else %} 1
{% endif %}
# value:
# - 1
step: 1
min: -30000
max: 30000
- name: Ferroamp Import Threshold
state: "{{ states('sensor.ferroamp_import_threshold_system_value') }}"
availability: "{{ is_number(states('sensor.ferroamp_import_threshold_system_value')) }}"
set_value:
# set import threshold
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 8002
slave: 1
# value: "{{ value }}"
value:
- 0
- "{{ '%x' % (value) | pack('>f') | unpack('>hh') }}"
# apply import settings
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 8006
slave: 1
value:
- 1
step: 1
min: 0
max: 30000
- name: Ferroamp Export Threshold
state: "{{ states('sensor.ferroamp_export_threshold_system_value') }}"
availability: "{{ is_number(states('sensor.ferroamp_export_threshold_system_value')) }}"
set_value:
# set import threshold
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 8012
slave: 1
# value: "{{ value }}"
value:
- 0
- "{{ '%x' % (value) | pack('>f') | unpack('>hh') }}"
# apply import settings
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 8016
slave: 1
value:
- 1
step: 1
min: 0
max: 30000
switch:
- platform: template
switches:
ferroamp_battery_mode_default:
friendly_name: Ferroamp Battery Mode Default
value_template: "{{ is_state('sensor.ferroamp_battery_mode', '0') }}"
availability_template: >-
{%- if not is_state("sensor.ferroamp_battery_mode", "unavailable") %}
true
{%- endif %}
turn_on:
# set battery to default mode
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 6000
slave: 1
value: 0
turn_off:
# set battery to default mode
- action: modbus.write_register
data_template:
hub: ferroamp_modbus
address: 6000
slave: 1
value: 1
ferroamp_limit_import:
friendly_name: Ferroamp Limit Import
value_template: "{{ is_state('binary_sensor.ferroamp_limit_import_system_value', 'on') }}"
availability_template: >-
{%- if not is_state("binary_sensor.ferroamp_limit_import_system_value", "unavailable") %}
true
{%- endif %}
turn_on:
# set limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8000
slave: 1
value:
- 1
# apply limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8006
slave: 1
value:
- 1
turn_off:
# set limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8000
slave: 1
value:
- 0
# apply limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8006
slave: 1
value:
- 1
ferroamp_limit_export:
friendly_name: Ferroamp Limit Export
value_template: "{{ is_state('binary_sensor.ferroamp_limit_export_system_value', 'on') }}"
availability_template: >-
{%- if not is_state("binary_sensor.ferroamp_limit_export_system_value", "unavailable") %}
true
{%- endif %}
turn_on:
# set limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8010
slave: 1
value:
- 1
# apply limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8016
slave: 1
value:
- 1
turn_off:
# set limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8010
slave: 1
value:
- 0
# apply limit import
- action: modbus.write_register
data:
hub: ferroamp_modbus
address: 8016
slave: 1
value:
- 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment