def case_assert_rel_error(case1, case2, test_case, tolerance):
    for tup1, tup2 in zip(case1.items(flatten=True), case2.items(flatten=True)):
        if tup1[0].endswith('itername') or tup2[0].endswith('itername'):
            continue
        if isinstance(tup1[1], float) and isinstance(tup2[1], float):
            assert_rel_error(test_case, tup1[1], tup2[1], tolerance)
        else:
            test_case.fail("Case entry values (%s:%s, %s:%s) are not both floats"
                           % (tup1[0], tup1[1], tup2[0], tup2[1]))
        if tup1[0] != tup2[0]:
            test_case.fail("Case entry names ('%s', '%s') don't match"
                           % (tup1[0], tup2[0]))
serializes Meter to python dict, JSON safe
dataset/ETHPy150Open OpenMDAO/OpenMDAO-Framework/openmdao.util/src/openmdao/util/testutil.py/case_assert_rel_error--crossover with--dataset/ETHPy150Open buildingenergy/buildingenergy-platform/seed/models.py/Meter.to_dict