diff --git a/docs/changelog.md b/docs/changelog.md index b42edf1..f2b8bd6 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -28,6 +28,26 @@ _In development._ Thanks to [Jan Kundrát](https://github.com/jktjkt) for reporting the issue along with a proposed fix ([PR #6](https://github.com/gertvdijk/PyKMP/pull/6)). +- The catalog of units and registers in [`pykmp.constants`][pykmp.constants] has been + expanded substantially: + + - The [register display names][pykmp.constants.REGISTERS] catalog has been expanded + for an **additional 108 register IDs**. 90 of which were found on MULTICAL® 603 + and MULTICAL® 303 meters and 18 on the 382 electricity meter. + - Eight new unit IDs have been added to the + [unit display names mapping][pykmp.constants.UNITS_NAMES]. + - Several unit display names have been corrected and extended, including fixes for + Kelvin and for watt- and var-based units. + - A few register display names have been refined with clearer suffixes to denote the + 'channel'. + + Thanks to [Jan Kundrát](https://github.com/jktjkt) for contributing the extensive + list of the MULTICAL® heat meter additions along with a proposed change + ([PR #4](https://github.com/gertvdijk/PyKMP/pull/4)). + + Thanks to [Benny Lyne Amorsen](https://github.com/amorsen) for listing the registers + on the electricity meter. + ### Tooling changes - Project documentation has been migrated from [MkDocs](https://www.mkdocs.org/) with @@ -37,6 +57,10 @@ _In development._ ### Development changes +- The [`constants`][pykmp.constants] module now uses decimal IDs for + [`REGISTERS`][pykmp.constants.REGISTERS] and + [`UNITS_NAMES`][pykmp.constants.UNITS_NAMES], matching the primary numbering used in + vendor documentation and the tool's default output more closely. - Pyright has been adopted as an additional strict type checker in `run-all-linters`, with configuration aligned more closely with the VS Code IDE experience. - Binary-heavy tests and related constants have been reformatted to use diff --git a/src/pykmp/constants.py b/src/pykmp/constants.py index f4de63a..eb0955b 100644 --- a/src/pykmp/constants.py +++ b/src/pykmp/constants.py @@ -14,109 +14,233 @@ from typing import Final # pragma: no cover -# Decimals of each variable in the GetRegister command request/response (CID=0x10) +# Register display names as used with GetRegister command request/response (CID=0x10) REGISTERS: Final[Mapping[int, str]] = { - 0x003C: "Heat Energy (E1)", - 0x0044: "Volume", - 0x004A: "Flow", - 0x0050: "Current Power", - 0x0056: "Temp1", - 0x0057: "Temp2", - 0x0059: "Tempdiff", - 0x0061: "Temp1xm3", - 0x006E: "Temp2xm3", - 0x0071: "Infoevent", - 0x007B: "MaxFlowDate_Y", - 0x007C: "MaxFlow_Y", - 0x007D: "MinFlowDate_Y", - 0x007E: "MinFlow_Y", - 0x007F: "MaxPowerDate_Y", - 0x0080: "MaxPower_Y", - 0x0081: "MinPowerDate_Y", - 0x0082: "MinPower_Y", - 0x008A: "MaxFlowDate_M", - 0x008B: "MaxFlow_M", - 0x008C: "MinFlowDate_M", - 0x008D: "MinFlow_M", - 0x008E: "MaxPowerDate_M", - 0x008F: "MaxPower_M", - 0x0090: "MinPowerDate_M", - 0x0091: "MinPower_M", - 0x0092: "AvgTemp1_Y", - 0x0093: "AvgTemp2_Y", - 0x0095: "AvgTemp1_M", - 0x0096: "AvgTemp2_M", - 0x010A: "E1HighRes", - 0x03EC: "HourCounter", + 1: "Energy in", + 2: "Energy out", + 13: "Energy in hires", + 14: "Energy out hires", + 60: "Heat Energy (E1)", + 61: "Inlet Energy E4", + 62: "Outlet Energy E5", + 63: "Cooling Energy E3", + 64: "Tariff TA2", + 65: "Tariff TA3", + 66: "Tariff limit 2", + 67: "Tariff limit 3", + 68: "Volume V1", + 69: "Volume V2", + 72: "Mass M1", + 73: "Mass M2", + 74: "Flow V1", + 75: "Flow V2", + 80: "Current Power", + 84: "Pulse input A1", + 85: "Pulse input B1", + 86: "Temp1", + 87: "Temp2", + 88: "Temp3", + 89: "Tempdiff", + 91: "Pressure P1", + 92: "Pressure P2", + 94: "Heat Energy E2", + 95: "Tap water energy E6", + 96: "Tap water energy E7", + 97: "Temp1xm3 E8", # V1 * t1 (inlet) + 98: "Target Date", + 99: "InfoCode", + 104: "Meter number for VB", + 110: "Temp2xm3 E9", # V2 * t2 (outlet) + 112: "Customer number 2", # 8 most-significant digits + 113: "Infoevent", + 114: "Meter number for VA", + 122: "Temp4", + 123: "MaxFlowDate_Y", + 124: "MaxFlow_Y", + 125: "MinFlowDate_Y", + 126: "MinFlow_Y", + 127: "MaxPowerDate_Y", + 128: "MaxPower_Y", + 129: "MinPowerDate_Y", + 130: "MinPower_Y", + 138: "MaxFlowDate_M", + 139: "MaxFlow_M", + 140: "MinFlowDate_M", + 141: "MinFlow_M", + 142: "MaxPowerDate_M", + 143: "MaxPower_M", + 144: "MinPowerDate_M", + 145: "MinPower_M", + 146: "AvgTemp1_Y", + 147: "AvgTemp2_Y", + 149: "AvgTemp1_M", + 150: "AvgTemp2_M", + 152: "Program number", # not seen on meters: ABCCCCCC + 153: "Config number 1", # config no. DDDEE + 154: "Software Checksum 1", + 168: "Config number 2", # config no. FFGGMN + 175: "Error hour counter", + 178: "Differential energy dE", + 179: "Control energy cE", + 180: "Differential volume dV", + 181: "Control volume cV", + # 183: looks like a meter S/N on Multical 603 + 184: "MbusPriAdrMod1", + 185: "MbusSekAdrMod1", + 218: "MbusPriAdrMod2", + 219: "MbusSekAdrMod2", + 222: "ConfigChangedEventCount", + 224: "Pulse input A2", + 225: "Pulse input B2", + 228: "Config number 3", + 229: "T1_average_autoint", + 230: "T2_average_autoint", + 234: "l/imp for VA", + 235: "l/imp for VB", + 239: "Volume V1 hires", + # Undocumented (259 and 260), but it matches the info given by Multical 603 in the + # diagnostics display + 259: "Nominal Q\N{LATIN SUBSCRIPT SMALL LETTER P} V1", + 260: "Nominal Q\N{LATIN SUBSCRIPT SMALL LETTER P} V2", + 266: "E1HighRes", + 267: "Cooling energy E3 hires", + 346: "Module SW rev", + 347: "Customer number", + 348: "Date and Time", # TODO: unknown unit 79, 28591984415535 + 355: "COP Year", + 362: "Tariff TA4", + 364: "Heat energy A1", # Heat energy with discount A1, t2 < t5 limit + 365: "Heat energy A2", # Heat energy with surcharge A2, t2 > t5 limit + 366: "T5 limit", + 367: "COP Month", + 368: "Config number 4", + 369: "Info bits", + 371: "COP", + 372: "Power input B1", + 379: "T1 time average day", + 380: "T2 time average day", + 381: "T1 time average hour", + 382: "T2 time average hour", + 383: "Flow V1 max year date", + # 384: something similar as 383? + 385: "Power max year date", + # 386: something similar as 385? + 387: "Flow V1 max month date", + # 388: something similar as 387? + 389: "Power max month date", + # 390: something similar as 389? + 398: "T1 actual (one decimal)", + 399: "T2 actual (one decimal)", + 400: "T1-T2 (one decimal)", # Undocumented, but appears as such on Multical 603 + 404: "Meter Type", + 473: "Energy E10", + 474: "Energy E11", + 477: "T3 time average day", + 478: "T3 time average hour", + 505: "P1 average day", + 506: "P2 average day", + 507: "P1 average hour", + 508: "P2 average hour", + # Undocumented, but it matches the actual interval on Multical 303 + 675: "wM-Bus transmission interval", + 1001: "Fabrication No", + 1002: "Time", + 1003: "Date", + 1004: "HourCounter", + 1005: "Software edition", + 1010: "Customer number 1", # 8 least-significant digits + 1023: "Power in", + 1024: "Power out", + 1032: "Operation Mode", + 1054: "Voltage L1", + 1055: "Voltage L2", + 1056: "Voltage L3", + 1076: "Current L1", + 1077: "Current L2", + 1078: "Current L3", + 1080: "Power in L1", + 1081: "Power in L2", + 1082: "Power in L3", + 1344: "Power out L1", + 1345: "Power out L2", + 1346: "Power out L3", } UNITS_NAMES: Final[Mapping[int, str]] = { - 0x00: "no unit (number)", - 0x01: "Wh", - 0x02: "kWh", - 0x03: "MWh", - 0x04: "GWh", - 0x05: "J", - 0x06: "kJ", - 0x07: "MJ", - 0x08: "GJ", - 0x09: "Cal", - 0x0A: "kCal", - 0x0B: "Mcal", - 0x0C: "Gcal", - 0x0D: "varh", - 0x0E: "kvarh", - 0x0F: "Mvarh", - 0x10: "Gvarh", - 0x11: "VAh", - 0x12: "kVAh", - 0x13: "MVAh", - 0x14: "GVAh", - 0x15: "kW", - 0x16: "kW", - 0x17: "MW", - 0x18: "GW", - 0x19: "kvar", - 0x1A: "kvar", - 0x1B: "Mvar", - 0x1C: "Gvar", - 0x1D: "VA", - 0x1E: "kVA", - 0x1F: "MVA", - 0x20: "GVA", - 0x21: "V", - 0x22: "A", - 0x23: "kV", - 0x24: "kA", - 0x25: "°C", - 0x26: "°K", - 0x27: "l", - 0x28: "m³", - 0x29: "l/h", - 0x2A: "m³/h", - 0x2B: "m³\N{MULTIPLICATION SIGN}C", - 0x2C: "ton", - 0x2D: "ton/h", - 0x2E: "h", - 0x2F: "hh:mm:ss", - 0x30: "yy:mm:dd", - 0x31: "yyyy:mm:dd", - 0x32: "mm:dd", - 0x33: "no unit (number)", - 0x34: "bar", - 0x35: "RTC", - 0x36: "ASCII", - 0x37: "m³ \N{MULTIPLICATION SIGN}10", - 0x38: "ton \N{MULTIPLICATION SIGN}10", - 0x39: "GJ \N{MULTIPLICATION SIGN}10", - 0x3A: "minutes", - 0x3B: "Bitfield", - 0x3C: "s", - 0x3D: "ms", - 0x3E: "days", - 0x3F: "RTC-Q", - 0x40: "Datetime", + 0: "no unit (number)", + 1: "Wh", + 2: "kWh", + 3: "MWh", + 4: "GWh", + 5: "J", + 6: "kJ", + 7: "MJ", + 8: "GJ", + 9: "Cal", + 10: "kCal", + 11: "Mcal", + 12: "Gcal", + 13: "varh", + 14: "kvarh", + 15: "Mvarh", + 16: "Gvarh", + 17: "VAh", + 18: "kVAh", + 19: "MVAh", + 20: "GVAh", + 21: "W", + 22: "kW", + 23: "MW", + 24: "GW", + 25: "var", + 26: "kvar", + 27: "Mvar", + 28: "Gvar", + 29: "VA", + 30: "kVA", + 31: "MVA", + 32: "GVA", + 33: "V", + 34: "A", + 35: "kV", + 36: "kA", + 37: "°C", + 38: "K", + 39: "l", + 40: "m³", + 41: "l/h", + 42: "m³/h", + 43: "m³\N{MULTIPLICATION SIGN}C", + 44: "ton", + 45: "ton/h", + 46: "h", + 47: "hh:mm:ss", + 48: "yy:mm:dd", + 49: "yyyy:mm:dd", + 50: "mm:dd", + 51: "no unit (number)", + 52: "bar", + 53: "RTC", + 54: "ASCII", + 55: "m³ \N{MULTIPLICATION SIGN}10", + 56: "ton \N{MULTIPLICATION SIGN}10", + 57: "GJ \N{MULTIPLICATION SIGN}10", + 58: "minutes", + 59: "Bitfield", + 60: "s", + 61: "ms", + 62: "days", + 63: "RTC-Q", + 64: "Datetime", + 65: "imp/l", + 66: "l/imp", + 85: "%RH", + 86: "%O\N{SUBSCRIPT TWO}", + 87: "m/s", + 88: "kJ/kg", + 89: "pH", + 90: "g/kg", }