wildekek / rdtech-esphome

Add Home Assistant support to your RDTech power supply
MIT License
33 stars 7 forks source link

Set PSU date automatically on connnect #2

Closed wildekek closed 1 year ago

wildekek commented 2 years ago

If we'd sync the date/time on connecting, we would effectively use Home Assistants NTP server and always have a working clock, even without a battery.

roondar commented 2 years ago

Hello @wildekek, I could be possible to use these registers =>

    @property
    def date(self):
        """returns the date as tuple: (year, month, day)"""
        regs = self._read_registers(48, 3)
        year = regs[0]
        month = regs[1]
        day = regs[2]
        return (year, month, day)

    @date.setter
    def date(self, value):
        """Sets the date, needs tuple with (year, month, day) as argument"""
        year, month, day = value
        self._write_register(48, year)
        self._write_register(49, month)
        self._write_register(50, day)

    @property
    def time(self):
        """returns the time as tuple: (h, m, s)"""
        regs = self._read_registers(51, 3)
        h = regs[0]
        m = regs[1]
        s = regs[2]
        return (h, m, s)

    @time.setter
    def time(self, value):
        """sets the time, needs time with (h, m, s) as argument"""
        h, m, s = value
        self._write_register(51, h)
        self._write_register(52, m)
        self._write_register(53, s)

And how to use it in ESPhome => https://esphome.io/components/time.html#use-in-lambdas I hope it'll help you. :)

MDBInd commented 1 year ago

Hi @roondar, I have forked this repo to work with my RD6006P and I would like to implement this feature. Can I ask where you got this register information from?

The following lines produce 2023 which matches the year set on the RD6006P, so we are off to a good start!

  - platform: modbus_controller
    name: "Date"
    modbus_controller_id: powersupply
    entity_category: diagnostic
    register_type: holding
    address: 48
    register_count: 3
    value_type: U_WORD
wildekek commented 1 year ago

Hi @MDBInd, that's great news! I'm not actively doing anything with this repo, so I hope you can make it into something more useful. You can find the registers here: https://github.com/Baldanos/rd6006/blob/master/registers.md

roondar commented 1 year ago

Exactly 😀

MDBInd commented 1 year ago

Thanks for all the information guys. I have updated my repo just now to include reading Date & Time and implementing a triangle wave which is the main feature I wanted to create.

There is a snippet of code from ESPHome - Modbus Controller which looks like the kind of thing we need to update the date time.

// get local time and sync to controller
time_t now = ::time(nullptr);
struct tm *time_info = ::localtime(&now);
int seconds = time_info->tm_sec;
int minutes = time_info->tm_min;
int hour = time_info->tm_hour;
int day = time_info->tm_mday;
int month = time_info->tm_mon + 1;
int year = time_info->tm_year % 100;
esphome::modbus_controller::ModbusController *controller = id(epever);
// if there is no internet connection localtime returns year 70
if (year != 70) {
  // create the payload
  std::vector<uint16_t> rtc_data = {uint16_t((minutes << 8) | seconds), uint16_t((day << 8) | hour),
                                    uint16_t((year << 8) | month)};
  // Create a modbus command item with the time information as the payload
  esphome::modbus_controller::ModbusCommandItem set_rtc_command =
      esphome::modbus_controller::ModbusCommandItem::create_write_multiple_command(controller, 0x9013, 3, rtc_data);
  // Submit the command to the send queue
  epever->queue_command(set_rtc_command);
  ESP_LOGI("ModbusLambda", "EPSOLAR RTC set to %02d:%02d:%02d %02d.%02d.%04d", hour, minutes, seconds, day, month,
          year + 2000);
}

I understand most of that snippet but I do get lost around the ModbusLambda section. I would like to get this functionality working too so any help would be appreciated!

MDBInd commented 1 year ago

I have finally got round to implementing this feature on the RD6006P in the latest version of my firmware .

This extract will update the year on boot and keep it up to date every hour to compensate for any time drift:

time:
  - platform: sntp
    id: ntp_time
    timezone: "Europe/London"
    update_interval: 60min
    on_time_sync:
      then:
        - logger.log: "Time synchronizing [NTP]..."
        - lambda: |-
            auto year = id(ntp_time).now().year;

            auto a = id(date_year).make_call();
            a.set_value(year);
            a.perform();

number:
  - platform: modbus_controller
    name: "Year"
    id: date_year
    modbus_controller_id: powersupply
    entity_category: diagnostic
    register_type: holding
    address: 48
    value_type: U_WORD
    internal: true
wildekek commented 1 year ago

Hey @MDBInd, since you're actively developing and have improved on the docs, I think your repo is a better experience than this one. I'm thinking about archiving this repo and referring to yours in the README. Would you be okay with that? Shoot me a message on discord (@wildekek). I'd also be fine with keeping this repo updated with the latest version, but then a PR would be nice.

wildekek commented 1 year ago

Just added an uptime sensor to the v1.1.0 release. I'll use that to update the time over modbus in a future release.

MDBInd commented 1 year ago

Hi @wildekek, I am happy to help out as I am testing some hardware at the moment and have added new features to the firmware to help my work. I tried to find you on Discord but I need a 4digit tag, I am @thebeest#4902.

wildekek commented 1 year ago

Would it be possible to add a button that syncs the units date/time with home assistant, because even with the internal battery it never saves the time for me

Originally posted by @ShayBox in https://github.com/wildekek/rdtech-esphome/issues/5#issuecomment-1699681391

@ShayBox Why would you need a button? The on_time_sync in the config updates the time of the power supply whenever it gets an updated time from Home Assistant, so it should always be on time.

ShayBox commented 1 year ago

Oh, I see my units time is accurate since I updated. Thanks