Vedbusitem import / GetItems timeout issue on Venus OS 3.72 (worked fine on 3.71)

Title: vedbusitem import / GetItems timeout issue on Venus OS 3.72 (worked fine on 3.71)

Hi everyone,

I’m facing an issue after upgrading to Venus OS 3.72.

Previously, on Venus OS 3.71, everything was working fine. I have a custom battery service running on multiple interfaces (ttyUSB0, ttyUSB1), and I fetch data using vedbusitem (via DBus).

After upgrading to 3.72, I’m consistently seeing these errors:

GetItems failed for com.victronenergy.battery.ttyUSB0:
org.freedesktop.DBus.Error.NoReply: Did not receive a reply.

WARNING:GetItems failed for com.victronenergy.battery.ttyUSB1:
org.freedesktop.DBus.Error.NoReply: Did not receive a reply.

The error suggests:

  • No reply from the service

  • Timeout expired

  • Possible DBus policy or communication issue

Observations:

  • The same service and code worked without issues on 3.71

  • No major changes were made on my side

  • The issue appears when fetching data via GetItems (vedbusitem import)

Questions:

  1. Were there any changes in DBus handling or timeouts in Venus OS 3.72?

  2. Has anything changed in vedbusitem / velib_python behavior?

  3. Do we now need to handle async calls or increase timeouts explicitly?

  4. Could this be related to service startup timing or load issues?

  5. are there new requirements for vebusitem import to work with.

Any insights or suggestions would be really helpful. If needed, I can share more logs or code snippets.

Thanks!

What modifications or drivers have you loaded?

i am using 4 batteries as serial connection with Venus os Gx device and each battery poll data at interval of 5 seconds. All these battery data pushed to dbus paths.

  1. Battery 1 : com.victronenergy.battery.ttyUSB0
  2. Battery 2 : com.victronenergy.battery.ttyUSB1
  3. Battery 3 : com.victronenergy.battery.ttyUSB2
  4. Battery 4 : com.victronenergy.battery.ttyUSB3

these all being read by a service which accumulate all data to make it a virual battery like , with avg function ,max function , min function for volts, current , temps and all the other data from a battery. in this service i am using Vedbusitemimport from vedbus.py as to read all these dbus service paths and value.

def fetch(self, services):
        log_info(f"[fetch] ============================================================")
        log_info(f"[fetch] START - total services to read: {len(services)}")
        log_info(f"[fetch] Services list: {services}")
        log_info(f"[fetch] ============================================================")
        data = {p: [] for p in battery_paths}
        self.per_battery_values = data  # Save all per-battery lists for this cycle
        fetch_ok = True                  # <-- track overall success

        for svc in services:
            log_info(f"[fetch] [{svc}] --- START processing service ---")
            items = {}
            getitems_failed = False

            # Try GetItems first
            log_info(f"[fetch] [{svc}] Calling GetItems...")
            try:
                items = self.bus.call_blocking(
                    svc, '/', None, 'GetItems', '', [], timeout=1
                )
                if not isinstance(items, dict) or not items:
                    log_warning(f"[fetch] [{svc}] GetItems returned empty or non-dict - falling back to direct reads")
                    items = {}
            except Exception as e:
                log_warning('GetItems failed for %s: %s', svc, e)
                items = {}
                getitems_failed = True   # <-- note the failure

            svc_got_any_value = False    # <-- did fallback recover anything
            log_info(f"[fetch] [{svc}] getitems_failed={getitems_failed} - starting path loop...")

            for p in battery_paths:
                val = None
                # Try to get from GetItems result
                entry = items.get(p)
                if isinstance(entry, dict) and 'Value' in entry:
                    try:
                        val = unwrap_dbus_value(entry['Value'])
                        svc_got_any_value = True
                    except Exception as e:
                        log_warning(f"Failed to unwrap value for {svc} {p}: {e}")
                else:
                    # Fallback: fetch path directly
                    try:
                        raw = VeDbusItemImport(self.bus, svc, p).get_value()
                        val = unwrap_dbus_value(raw)
                        svc_got_any_value = True
                    except Exception as e:
                        log_debug(f"Direct fetch failed for {svc} {p}: {e}")
                        continue
                if val is not None:
                    data[p].append(val)
                else:
                    log_debug(f"Path {p} not found or value is None in {svc}")
            log_info(f"[fetch] [{svc}] Path loop done - svc_got_any_value={svc_got_any_value}")

            # If GetItems failed AND direct fallback got nothing → signal retry
            if getitems_failed and not svc_got_any_value:
                log_warning(f"[fetch] GetItems failed and direct fallback empty for {svc} - marking fetch as failed")
                fetch_ok = False
            elif getitems_failed and svc_got_any_value:
                log_info(f"[fetch] [{svc}] GetItems failed but direct fallback recovered values - no retry needed")
            else:
                log_info(f"[fetch] [{svc}] Read completed OK via GetItems")
                
            log_info(f"[fetch] [{svc}] fetch_ok so far={fetch_ok}")
            log_info(f"[fetch] [{svc}] --- END processing service ---")
            log_info(f"[fetch] ---------------------------------------------")

ok thanks. Moving to modifications section.
Hopefully someone can point you in a direction as there is little to no support for this that we can ask for.