Skip to content

Conversation

@zulufoxtrot
Copy link

@zulufoxtrot zulufoxtrot commented Jan 12, 2026

Alright. Support for ME3000SP desired battery charge/discharge power in passive mode.

Summary of changes:

  • json: added read flag. if true or absent: read it. if false: don't read it. needed for charge_discharge_power that is write only (as far as I can tell)
  • json: created new register: "battery power". uses read register 0x020d which was originally believed to contain charge_discharge_power.
  • l'll comment other changes in the code

Checks (serial number checks bypassed):

  • only works in passive mode ✅
  • positive value triggers a charge ✅
  • negative value triggers a discharge 💹
  • a zero value disconnects the battery (relay click) ✅
  • shows up correctly in Home Assistant ✅
  • battery power correctly reported ✅

Not working yet:

  • serial number 🛑 (and therefore the program can't start)
  • MQTT read is broken for charge_discharge_power for the ME3000SP: since we don't read the register (because we can't, as far as I know), we don't publish a topic for this register to MQTT, so it does not show up in Home Assistant, so we can't set it directly in HA. Workaround for now: create an Input Number, then an automation to publish the value of this number to the MQTT topic.

@zulufoxtrot zulufoxtrot marked this pull request as ready for review January 12, 2026 18:39
f"Received a request for {register['name']} but mode value: {new_value} is not a known mode. Ignoring")
if 'function' not in register:
logging.error(f"No function was provided for register {register['name']} skipping write operation. Check the JSON is configured correctly.")
continue
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is just a syntax change, the logic stays the same.

instead of "if, then, else", i use a "if not" and the continue keyword.

the rest of the diff is just just indentation changes, each line is unindented by 1 increment.

register, raw_value)
while retry > 0:
if self.raw_data[register['name']] == int(new_raw_value):
if int(self.raw_data[register['name']]) == int(new_raw_value):
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this change and the 2 that follow, I think the LLM wrote this. it's cosmetic, I can remove them if you want


def update_state(self):
for register in self.config['registers']:
if not register.get('read', True):
Copy link
Author

@zulufoxtrot zulufoxtrot Jan 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this one is for the charge_discharge_power register that can't be read from, only written to (supposedly)

from_raw = self.raw_data.get(register.get('name'))
from_value = self.translate_from_raw_value(
register, from_raw)
try:
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Catching any conversion errors here to allow the rest of the registers to be processed normally.

start_register = int(block['start_register'], 16)
required_length = int(block['length'])
values = []
raw_value = None
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused variables.

@zulufoxtrot
Copy link
Author

The result is beautiful 🥲

Screen.Recording.2026-01-14.at.20.49.08-1.mov
Screen.Recording.2026-01-14.at.20.49.08.mov

I used an input number and an automation in HA to bind the slider to the MQTT topic.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant