Hi wgumaa!
I’ve only needed to update the main fuse value so far. This because the monitor clamps used by the Nibe S1255 can’t detect what “way” the current is flowing and this became a problem when I installed our solar panels. So I face a problem during high levels of sunshine where the Nibe refuses to heat any hot water as it’s thinking that there’s no room left for any additional load.
I have 20 A fuse and it’s controlled by the 103 holding register. I’ve setup a small Python script on the host:
#!/usr/bin/env python3
"""
Pymodbus write holding register
--------------------------------------------------------------------------
Author: Jörgen Andreasen <[email protected]>
"""
# --------------------------------------------------------------------------- #
# import the various client implementations
# --------------------------------------------------------------------------- #
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
# --------------------------------------------------------------------------- #
# configure the client logging
# --------------------------------------------------------------------------- #
import logging
import sys, getopt
FORMAT = ('%(asctime)-15s %(threadName)-15s '
'%(levelname)-8s %(module)-15s:%(lineno)-8s %(message)s')
logging.basicConfig(format=FORMAT)
log = logging.getLogger()
log.setLevel(logging.INFO)
UNIT = 0x1
def write_register(argv):
host = 'localhost'
port = 502
register = -1
value = -1
try:
opts, args = getopt.getopt(argv,"h:p:r:v:d",["host=","port=","register=", "value=", "debug"])
except getopt.GetoptError:
print('pymodbus.write_register -h <host> -p <port> -r <register> -v value')
sys.exit(2)
for opt, arg in opts:
if opt in ("-h", "--host"):
host = arg
elif opt in ("-p", "--port"):
port = int(arg)
elif opt in ("-r", "--register"):
register = int(arg)
elif opt in ("-v", "--value"):
value = int(arg)
elif opt in ("-d", "--debug"):
log.setLevel(logging.DEBUG)
client = ModbusClient(host, port=port)
client.connect()
log.debug("Write to a holding register and read back")
log.debug("register = " + str(register) + " value = " + str(value) )
rq = client.write_register(register, value, unit=UNIT)
rr = client.read_holding_registers(register, 1, unit=UNIT)
assert(not rq.isError()) # test that we are not an error
assert(not rr.isError()) # test that we are not an error
assert(rr.registers[0] == value) # test the expected value
if __name__ == "__main__":
write_register(sys.argv[1:])
That can update a single holding register. The script is called pymodbus.write_register and was installed in the /usr/local/bin directory on the host running the Docker containers.
The I created a wrapper script, called set_main_fuse, with the content:
#!/bin/bash
Fuse=$1
Server=<host name>
DataDir=/config/modbus
SSH="ssh -i $DataDir/ssh-id -oStrictHostKeyChecking=no -oUserKnownHostsFile=$DataDir/known_hosts"
$SSH $Server pymodbus.write_register --host=<Nibe host> --register=103 --value=$Fuse
The SSH public key corresponding to the SSH private key,ssh-id, needs to be present the authorized_keys file of the target account, in my case I’ve just used the system root account. The set_main_fuse wrapper script is present in the modbus sub directory of the HA configuration directory, normally /usr/share/hassio/homeassistant on the host (which corresponds to /config within the Docker container)
Two commands where then setup in the HA configuration:
shell_command:
solar_export_fuse: /config/modbus/set_main_fuse 40
no_solar_export_fuse: /config/modbus/set_main_fuse 20
The solar_export_fuse command raises the fuse the Nibe sees to 40 A whereas no_solar_export_fuse lowers it back to the original value. I then have two automations for raising and lowering the fuse depending on if I’m exporting energy or not. These automations are using the two defined commands.
Best regards,
Jörgen