diff --git a/prototypes/panasonic_heatpump/code-gen-result.md b/prototypes/panasonic_heatpump/code-gen-result.md
new file mode 100644
index 0000000..ca6f4e7
--- /dev/null
+++ b/prototypes/panasonic_heatpump/code-gen-result.md
@@ -0,0 +1,129 @@
+| Topic | SensorType | CodeGen Part 1 | CodeGen Part 2 |
+| ----- | ------------- | ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
+| 0 | binary_sensor | id(top0).publish_state(getBoolState(getBit7and8(bytes[4]))); | \- platform: template
id: top0
name: "Heatpump State"
lambda: "return {};" |
+| 1 | sensor | id(top1).publish_state(getPumpFlow(bytes[169], bytes[170])); | \- platform: template
id: top1
name: "Pump Flow"
unit_of_measurement: l/min
lambda: "return {};" |
+| 2 | binary_sensor | id(top2).publish_state(getBoolState(getBit1and2(bytes[4]))); | \- platform: template
id: top2
name: "Force DHW State"
lambda: "return {};" |
+| 3 | binary_sensor | id(top3).publish_state(getBoolState(getBit1and2(bytes[7]))); | \- platform: template
id: top3
name: "Quiet Mode Schedule"
lambda: "return {};" |
+| 4 | text_sensor | id(top4).publish_state(getTextState(OpModeDesc, getOpMode(bytes[6]))); | \- platform: template
id: top4
name: "Operating Mode State"
lambda: "return {};" |
+| 5 | sensor | id(top5).publish_state(getIntMinus128(bytes[143]) + getFractional(bytes[118], 0)); | \- platform: template
id: top5
name: "Main Inlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 6 | sensor | id(top6).publish_state(getIntMinus128(bytes[144]) + getFractional(bytes[118], 3)); | \- platform: template
id: top6
name: "Main Outlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 7 | sensor | id(top7).publish_state(getIntMinus128(bytes[153])); | \- platform: template
id: top7
name: "Main Target Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 8 | sensor | id(top8).publish_state(getIntMinus1(bytes[166])); | \- platform: template
id: top8
name: "Compressor Freq"
unit_of_measurement: Hz
lambda: "return {};" |
+| 9 | sensor | id(top9).publish_state(getIntMinus128(bytes[42])); | \- platform: template
id: top9
name: "DHW Target Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 10 | sensor | id(top10).publish_state(getIntMinus128(bytes[141])); | \- platform: template
id: top10
name: "DHW Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 11 | sensor | id(top11).publish_state(getWord(bytes[182], bytes[183])); | \- platform: template
id: top11
name: "Operations Hours"
unit_of_measurement: h
lambda: "return {};" |
+| 12 | sensor | id(top12).publish_state(getWord(bytes[179], bytes[180])); | \- platform: template
id: top12
name: "Operations Counter"
lambda: "return {};" |
+| 13 | binary_sensor | id(top13).publish_state(getBoolState(getBit1and2(bytes[5]))); | \- platform: template
id: top13
name: "Main Schedule State"
lambda: "return {};" |
+| 14 | sensor | id(top14).publish_state(getIntMinus128(bytes[142])); | \- platform: template
id: top14
name: "Outside Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 15 | sensor | id(top15).publish_state(getPower(bytes[194])); | \- platform: template
id: top15
name: "Heat Power Production"
unit_of_measurement: W
lambda: "return {};" |
+| 16 | sensor | id(top16).publish_state(getPower(bytes[193])); | \- platform: template
id: top16
name: "Heat Power Consumption"
unit_of_measurement: W
lambda: "return {};" |
+| 17 | text_sensor | id(top17).publish_state(getTextState(Powerfulmode, getRight3bits(bytes[7]))); | \- platform: template
id: top17
name: "Powerful Mode Time"
lambda: "return {};" |
+| 18 | text_sensor | id(top18).publish_state(getTextState(Quietmode, getBit3and4and5(bytes[7]))); | \- platform: template
id: top18
name: "Quiet Mode Level"
lambda: "return {};" |
+| 19 | text_sensor | id(top19).publish_state(getTextState(HolidayState, getBit3and4(bytes[5]))); | \- platform: template
id: top19
name: "Holiday Mode State"
lambda: "return {};" |
+| 20 | text_sensor | id(top20).publish_state(getTextState(Valve, getBit7and8(bytes[111]))); | \- platform: template
id: top20
name: "ThreeWay Valve State"
lambda: "return {};" |
+| 21 | sensor | id(top21).publish_state(getIntMinus128(bytes[158])); | \- platform: template
id: top21
name: "Outside Pipe Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 22 | sensor | id(top22).publish_state(getIntMinus128(bytes[99])); | \- platform: template
id: top22
name: "DHW Heat Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 23 | sensor | id(top23).publish_state(getIntMinus128(bytes[84])); | \- platform: template
id: top23
name: "Heat Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 24 | sensor | id(top24).publish_state(getIntMinus128(bytes[94])); | \- platform: template
id: top24
name: "Cool Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 25 | sensor | id(top25).publish_state(getIntMinus128(bytes[44])); | \- platform: template
id: top25
name: "DHW Holiday Shift Temp"
unit_of_measurement: K
lambda: "return {};" |
+| 26 | binary_sensor | id(top26).publish_state(getBoolState(getBit5and6(bytes[111]))); | \- platform: template
id: top26
name: "Defrosting State"
lambda: "return {};" |
+| 27 | sensor | id(top27).publish_state(getIntMinus128(bytes[38])); | \- platform: template
id: top27
name: "Z1 Heat Request Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 28 | sensor | id(top28).publish_state(getIntMinus128(bytes[39])); | \- platform: template
id: top28
name: "Z1 Cool Request Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 29 | sensor | id(top29).publish_state(getIntMinus128(bytes[75])); | \- platform: template
id: top29
name: "Z1 Heat Curve Target High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 30 | sensor | id(top30).publish_state(getIntMinus128(bytes[76])); | \- platform: template
id: top30
name: "Z1 Heat Curve Target Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 31 | sensor | id(top31).publish_state(getIntMinus128(bytes[78])); | \- platform: template
id: top31
name: "Z1 Heat Curve Outside High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 32 | sensor | id(top32).publish_state(getIntMinus128(bytes[77])); | \- platform: template
id: top32
name: "Z1 Heat Curve Outside Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 33 | sensor | id(top33).publish_state(getIntMinus128(bytes[156])); | \- platform: template
id: top33
name: "Room Thermostat Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 34 | sensor | id(top34).publish_state(getIntMinus128(bytes[40])); | \- platform: template
id: top34
name: "Z2 Heat Request Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 35 | sensor | id(top35).publish_state(getIntMinus128(bytes[41])); | \- platform: template
id: top35
name: "Z2 Cool Request Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 36 | sensor | id(top36).publish_state(getIntMinus128(bytes[145])); | \- platform: template
id: top36
name: "Z1 Water Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 37 | sensor | id(top37).publish_state(getIntMinus128(bytes[146])); | \- platform: template
id: top37
name: "Z2 Water Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 38 | sensor | id(top38).publish_state(getPower(bytes[196])); | \- platform: template
id: top38
name: "Cool Power Production"
unit_of_measurement: W
lambda: "return {};" |
+| 39 | sensor | id(top39).publish_state(getPower(bytes[195])); | \- platform: template
id: top39
name: "Cool Power Consumption"
unit_of_measurement: W
lambda: "return {};" |
+| 40 | sensor | id(top40).publish_state(getPower(bytes[198])); | \- platform: template
id: top40
name: "DHW Power Production"
unit_of_measurement: W
lambda: "return {};" |
+| 41 | sensor | id(top41).publish_state(getPower(bytes[197])); | \- platform: template
id: top41
name: "DHW Power Consumption"
unit_of_measurement: W
lambda: "return {};" |
+| 42 | sensor | id(top42).publish_state(getIntMinus128(bytes[147])); | \- platform: template
id: top42
name: "Z1 Water Target Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 43 | sensor | id(top43).publish_state(getIntMinus128(bytes[148])); | \- platform: template
id: top43
name: "Z2 Water Target Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 44 | text_sensor | id(top44).publish_state(getErrorInfo(bytes[113], bytes[114])); | \- platform: template
id: top44
name: "Error"
lambda: "return {};" |
+| 45 | sensor | id(top45).publish_state(getIntMinus128(bytes[43])); | \- platform: template
id: top45
name: "Room Holiday Shift Temp"
unit_of_measurement: K
lambda: "return {};" |
+| 46 | sensor | id(top46).publish_state(getIntMinus128(bytes[149])); | \- platform: template
id: top46
name: "Buffer Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 47 | sensor | id(top47).publish_state(getIntMinus128(bytes[150])); | \- platform: template
id: top47
name: "Solar Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 48 | sensor | id(top48).publish_state(getIntMinus128(bytes[151])); | \- platform: template
id: top48
name: "Pool Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 49 | sensor | id(top49).publish_state(getIntMinus128(bytes[154])); | \- platform: template
id: top49
name: "Main Hex Outlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 50 | sensor | id(top50).publish_state(getIntMinus128(bytes[155])); | \- platform: template
id: top50
name: "Discharge Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 51 | sensor | id(top51).publish_state(getIntMinus128(bytes[157])); | \- platform: template
id: top51
name: "Inside Pipe Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 52 | sensor | id(top52).publish_state(getIntMinus128(bytes[159])); | \- platform: template
id: top52
name: "Defrost Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 53 | sensor | id(top53).publish_state(getIntMinus128(bytes[160])); | \- platform: template
id: top53
name: "Eva Outlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 54 | sensor | id(top54).publish_state(getIntMinus128(bytes[161])); | \- platform: template
id: top54
name: "Bypass Outlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 55 | sensor | id(top55).publish_state(getIntMinus128(bytes[162])); | \- platform: template
id: top55
name: "Ipm Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 56 | sensor | id(top56).publish_state(getIntMinus128(bytes[139])); | \- platform: template
id: top56
name: "Z1 Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 57 | sensor | id(top57).publish_state(getIntMinus128(bytes[140])); | \- platform: template
id: top57
name: "Z2 Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 58 | text_sensor | id(top58).publish_state(getTextState(BlockedFree, getBit5and6(bytes[9]))); | \- platform: template
id: top58
name: "DHW Heater State"
lambda: "return {};" |
+| 59 | text_sensor | id(top59).publish_state(getTextState(BlockedFree, getBit7and8(bytes[9]))); | \- platform: template
id: top59
name: "Room Heater State"
lambda: "return {};" |
+| 60 | binary_sensor | id(top60).publish_state(getBoolState(getBit7and8(bytes[112]))); | \- platform: template
id: top60
name: "Internal Heater State"
lambda: "return {};" |
+| 61 | binary_sensor | id(top61).publish_state(getBoolState(getBit5and6(bytes[112]))); | \- platform: template
id: top61
name: "External Heater State"
lambda: "return {};" |
+| 62 | sensor | id(top62).publish_state(getIntMinus1Times10(bytes[173])); | \- platform: template
id: top62
name: "Fan1 Motor Speed"
unit_of_measurement: r/min
lambda: "return {};" |
+| 63 | sensor | id(top63).publish_state(getIntMinus1Times10(bytes[174])); | \- platform: template
id: top63
name: "Fan2 Motor Speed"
unit_of_measurement: r/min
lambda: "return {};" |
+| 64 | sensor | id(top64).publish_state(getIntMinus1Div5(bytes[163])); | \- platform: template
id: top64
name: "High Pressure"
unit_of_measurement: kgf/cm²
lambda: "return {};" |
+| 65 | sensor | id(top65).publish_state(getIntMinus1Times50(bytes[171])); | \- platform: template
id: top65
name: "Pump Speed"
unit_of_measurement: r/min
lambda: "return {};" |
+| 66 | sensor | id(top66).publish_state(getIntMinus1Times50(bytes[164])); | \- platform: template
id: top66
name: "Low Pressure"
unit_of_measurement: kgf/cm²
lambda: "return {};" |
+| 67 | sensor | id(top67).publish_state(getIntMinus1Div5(bytes[165])); | \- platform: template
id: top67
name: "Compressor Current"
unit_of_measurement: A
lambda: "return {};" |
+| 68 | binary_sensor | id(top68).publish_state(getBoolState(getBit5and6(bytes[5]))); | \- platform: template
id: top68
name: "Force Heater State"
lambda: "return {};" |
+| 69 | binary_sensor | id(top69).publish_state(getBoolState(getBit5and6(bytes[117]))); | \- platform: template
id: top69
name: "Sterilization State"
lambda: "return {};" |
+| 70 | sensor | id(top70).publish_state(getIntMinus128(bytes[100])); | \- platform: template
id: top70
name: "Sterilization Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 71 | sensor | id(top71).publish_state(getIntMinus1(bytes[101])); | \- platform: template
id: top71
name: "Sterilization Max Time"
unit_of_measurement: min
lambda: "return {};" |
+| 72 | sensor | id(top72).publish_state(getIntMinus128(bytes[86])); | \- platform: template
id: top72
name: "Z1 Cool Curve Target High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 73 | sensor | id(top73).publish_state(getIntMinus128(bytes[87])); | \- platform: template
id: top73
name: "Z1 Cool Curve Target Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 74 | sensor | id(top74).publish_state(getIntMinus128(bytes[89])); | \- platform: template
id: top74
name: "Z1 Cool Curve Outside High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 75 | sensor | id(top75).publish_state(getIntMinus128(bytes[88])); | \- platform: template
id: top75
name: "Z1 Cool Curve Outside Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 76 | text_sensor | id(top76).publish_state(getTextState(HeatCoolModeDesc, getBit7and8(bytes[28]))); | \- platform: template
id: top76
name: "Heating Mode"
lambda: "return {};" |
+| 77 | sensor | id(top77).publish_state(getIntMinus128(bytes[83])); | \- platform: template
id: top77
name: "Heating Off Outdoor Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 78 | sensor | id(top78).publish_state(getIntMinus128(bytes[85])); | \- platform: template
id: top78
name: "Heater On Outdoor Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 79 | sensor | id(top79).publish_state(getIntMinus128(bytes[95])); | \- platform: template
id: top79
name: "Heat To Cool Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 80 | sensor | id(top80).publish_state(getIntMinus128(bytes[96])); | \- platform: template
id: top80
name: "Cool To Heat Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 81 | text_sensor | id(top81).publish_state(getTextState(HeatCoolModeDesc, getBit5and6(bytes[28]))); | \- platform: template
id: top81
name: "Cooling Mode"
lambda: "return {};" |
+| 82 | sensor | id(top82).publish_state(getIntMinus128(bytes[79])); | \- platform: template
id: top82
name: "Z2 Heat Curve Target High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 83 | sensor | id(top83).publish_state(getIntMinus128(bytes[80])); | \- platform: template
id: top83
name: "Z2 Heat Curve Target Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 84 | sensor | id(top84).publish_state(getIntMinus128(bytes[82])); | \- platform: template
id: top84
name: "Z2 Heat Curve Outside High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 85 | sensor | id(top85).publish_state(getIntMinus128(bytes[81])); | \- platform: template
id: top85
name: "Z2 Heat Curve Outside Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 86 | sensor | id(top86).publish_state(getIntMinus128(bytes[90])); | \- platform: template
id: top86
name: "Z2 Cool Curve Target High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 87 | sensor | id(top87).publish_state(getIntMinus128(bytes[91])); | \- platform: template
id: top87
name: "Z2 Cool Curve Target Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 88 | sensor | id(top88).publish_state(getIntMinus128(bytes[93])); | \- platform: template
id: top88
name: "Z2 Cool Curve Outside High Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 89 | sensor | id(top89).publish_state(getIntMinus128(bytes[92])); | \- platform: template
id: top89
name: "Z2 Cool Curve Outside Low Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 90 | sensor | id(top90).publish_state(getWord(bytes[185], bytes[186])); | \- platform: template
id: top90
name: "Room Heater Operations Hours"
unit_of_measurement: h
lambda: "return {};" |
+| 91 | sensor | id(top91).publish_state(getWord(bytes[188], bytes[189])); | \- platform: template
id: top91
name: "DHW Heater Operations Hours"
unit_of_measurement: h
lambda: "return {};" |
+| 92 | text_sensor | id(top92).publish_state(getTextState(ModelNames, getModel(bytes, 129))); | \- platform: template
id: top92
name: "Heat Pump Model"
lambda: "return {};" |
+| 93 | sensor | id(top93).publish_state(getIntMinus1(bytes[172])); | \- platform: template
id: top93
name: "Pump Duty"
lambda: "return {};" |
+| 94 | text_sensor | id(top94).publish_state(getTextState(ZonesState, getBit1and2(bytes[6]))); | \- platform: template
id: top94
name: "Zones State"
lambda: "return {};" |
+| 95 | sensor | id(top95).publish_state(getIntMinus1(bytes[45])); | \- platform: template
id: top95
name: "Max Pump Duty"
lambda: "return {};" |
+| 96 | sensor | id(top96).publish_state(getIntMinus1(bytes[104])); | \- platform: template
id: top96
name: "Heater Delay Time"
unit_of_measurement: min
lambda: "return {};" |
+| 97 | sensor | id(top97).publish_state(getIntMinus128(bytes[105])); | \- platform: template
id: top97
name: "Heater Start Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 98 | sensor | id(top98).publish_state(getIntMinus128(bytes[106])); | \- platform: template
id: top98
name: "Heater Stop Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 99 | binary_sensor | id(top99).publish_state(getBoolState(getBit5and6(bytes[24]))); | \- platform: template
id: top99
name: "Buffer Installed"
lambda: "return {};" |
+| 100 | binary_sensor | id(top100).publish_state(getBoolState(getBit7and8(bytes[24]))); | \- platform: template
id: top100
name: "DHW Installed"
lambda: "return {};" |
+| 101 | text_sensor | id(top101).publish_state(getTextState(SolarModeDesc, getBit3and4(bytes[24]))); | \- platform: template
id: top101
name: "Solar Mode"
lambda: "return {};" |
+| 102 | sensor | id(top102).publish_state(getIntMinus128(bytes[61])); | \- platform: template
id: top102
name: "Solar On Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 103 | sensor | id(top103).publish_state(getIntMinus128(bytes[62])); | \- platform: template
id: top103
name: "Solar Off Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 104 | sensor | id(top104).publish_state(getIntMinus128(bytes[63])); | \- platform: template
id: top104
name: "Solar Frost Protection"
unit_of_measurement: °C
lambda: "return {};" |
+| 105 | sensor | id(top105).publish_state(getIntMinus128(bytes[64])); | \- platform: template
id: top105
name: "Solar High Limit"
unit_of_measurement: °C
lambda: "return {};" |
+| 106 | text_sensor | id(top106).publish_state(getTextState(PumpFlowRateMode, getBit3and4(bytes[29]))); | \- platform: template
id: top106
name: "Pump Flowrate Mode"
lambda: "return {};" |
+| 107 | text_sensor | id(top107).publish_state(getTextState(LiquidType, getBit1(bytes[20]))); | \- platform: template
id: top107
name: "Liquid Type"
lambda: "return {};" |
+| 108 | binary_sensor | id(top108).publish_state(getBoolState(getBit3and4(bytes[20]))); | \- platform: template
id: top108
name: "Alt External Sensor"
lambda: "return {};" |
+| 109 | binary_sensor | id(top109).publish_state(getBoolState(getBit5and6(bytes[20]))); | \- platform: template
id: top109
name: "Anti Freeze Mode"
lambda: "return {};" |
+| 110 | binary_sensor | id(top110).publish_state(getBoolState(getBit7and8(bytes[20]))); | \- platform: template
id: top110
name: "Optional PCB"
lambda: "return {};" |
+| 111 | text_sensor | id(top111).publish_state(getTextState(ZonesSensorType, getSecondByte(bytes[22]))); | \- platform: template
id: top111
name: "Z1 Sensor Settings"
lambda: "return {};" |
+| 112 | text_sensor | id(top112).publish_state(getTextState(ZonesSensorType, getFirstByte(bytes[22]))); | \- platform: template
id: top112
name: "Z2 Sensor Settings"
lambda: "return {};" |
+| 113 | sensor | id(top113).publish_state(getIntMinus128(bytes[59])); | \- platform: template
id: top113
name: "Buffer Tank Delta"
unit_of_measurement: K
lambda: "return {};" |
+| 114 | text_sensor | id(top114).publish_state(getTextState(ExtPadHeaterType, getBit3and4(bytes[25]))); | \- platform: template
id: top114
name: "External Pad Heater"
lambda: "return {};" |
+| 115 | sensor | id(top115).publish_state(getIntMinus1Div50(bytes[125])); | \- platform: template
id: top115
name: "Water Pressure"
unit_of_measurement: bar
lambda: "return {};" |
+| 116 | sensor | id(top116).publish_state(getIntMinus128(bytes[126])); | \- platform: template
id: top116
name: "Second Inlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 117 | sensor | id(top117).publish_state(getIntMinus128(bytes[127])); | \- platform: template
id: top117
name: "Economizer Outlet Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 118 | sensor | id(top118).publish_state(getIntMinus128(bytes[128])); | \- platform: template
id: top118
name: "Second Room Thermostat Temp"
unit_of_measurement: °C
lambda: "return {};" |
+| 119 | sensor | id(top119).publish_state(getIntMinus128(bytes[65])); | \- platform: template
id: top119
name: "Bivalent Heating Start Temperature"
unit_of_measurement: °C
lambda: "return {};" |
+| 120 | sensor | id(top120).publish_state(getIntMinus128(bytes[66])); | \- platform: template
id: top120
name: "Bivalent Heating Parallel Adv Starttemp"
unit_of_measurement: °C
lambda: "return {};" |
+| 121 | sensor | id(top121).publish_state(getIntMinus128(bytes[68])); | \- platform: template
id: top121
name: "Bivalent Heating Parallel Adv Stoptemp"
unit_of_measurement: °C
lambda: "return {};" |
+| 122 | sensor | id(top122).publish_state(getIntMinus1(bytes[67])); | \- platform: template
id: top122
name: "Bivalent Heating Parallel Adv Start Delay"
unit_of_measurement: min
lambda: "return {};" |
+| 123 | sensor | id(top123).publish_state(getIntMinus1(bytes[69])); | \- platform: template
id: top123
name: "Bivalent Heating Parallel Adv Stop Delay"
unit_of_measurement: min
lambda: "return {};" |
+| 124 | text_sensor | id(top124).publish_state(getTextState(Bivalent, getBivalent(bytes[26]))); | \- platform: template
id: top124
name: "Bivalent Heating Setting"
lambda: "return {};" |
+| 125 | sensor | id(top125).publish_state(getIntMinus1(bytes[177])); | \- platform: template
id: top125
name: "2 Zone mixing valve 1 opening"
lambda: "return {};" |
+| 126 | sensor | id(top126).publish_state(getIntMinus1(bytes[178])); | \- platform: template
id: top126
name: "2 Zone mixing valve 2 opening"
lambda: "return {};" |
diff --git a/prototypes/panasonic_heatpump/decode.cpp b/prototypes/panasonic_heatpump/decode.cpp
new file mode 100644
index 0000000..4c4436c
--- /dev/null
+++ b/prototypes/panasonic_heatpump/decode.cpp
@@ -0,0 +1,236 @@
+#include "decode.h"
+
+int getBit1(uint8_t input)
+{
+ return (input >> 7);
+}
+
+int getBit1and2(uint8_t input)
+{
+ return ((input >> 6) - 1);
+}
+
+int getBit3and4(uint8_t input)
+{
+ return (((input >> 4) & 0b11) - 1);
+}
+
+int getBit5and6(uint8_t input)
+{
+ return (((input >> 2) & 0b11) - 1);
+}
+
+int getBit7and8(uint8_t input)
+{
+ return ((input & 0b11) - 1);
+}
+
+int getBit3and4and5(uint8_t input)
+{
+ return (((input >> 3) & 0b111) - 1);
+}
+
+int getLeft5bits(uint8_t input)
+{
+ return ((input >> 3) - 1);
+}
+
+int getRight3bits(uint8_t input)
+{
+ return ((input & 0b111) - 1);
+}
+
+int getIntMinus1(uint8_t input)
+{
+ int value = (int)input - 1;
+ return value;
+}
+
+int getIntMinus128(uint8_t input)
+{
+ int value = (int)input - 128;
+ return value;
+}
+
+float getIntMinus1Div5(uint8_t input)
+{
+ return ((((float)input - 1) / 5), 1);
+}
+
+float getIntMinus1Div50(uint8_t input)
+{
+ return ((((float)input - 1) / 50), 2);
+}
+
+int getIntMinus1Times10(uint8_t input)
+{
+ int value = (int)input - 1;
+ return (value * 10);
+}
+
+int getIntMinus1Times50(uint8_t input)
+{
+ int value = (int)input - 1;
+ return (value * 50);
+}
+
+int getFirstByte(uint8_t input)
+{
+ return ((input >> 4) - 1);
+}
+
+int getSecondByte(uint8_t input)
+{
+ return ((input & 0b1111) - 1);
+}
+
+int getWord(uint8_t low, uint8_t hi)
+{
+ return ((hi << 8) + low) - 1;
+}
+
+int getUintt16(uint8_t input1, uint8_t input2)
+{
+ uint16_t value = static_cast((input2 << 8) | input1);
+ return (value - 1);
+}
+
+// TOP15, TOP16, TOP38, TOP39, TOP40, TOP41 //
+int getPower(uint8_t input)
+{
+ int value = ((int)input - 1) * 200;
+ return value;
+}
+
+// TOP4 //
+int getOpMode(uint8_t input)
+{
+ switch ((int)(input & 0b111111))
+ {
+ case 18:
+ return 0;
+ case 19:
+ return 1;
+ case 25:
+ return 2;
+ case 33:
+ return 3;
+ case 34:
+ return 4;
+ case 35:
+ return 5;
+ case 41:
+ return 6;
+ case 26:
+ return 7;
+ case 42:
+ return 8;
+ default:
+ return -1;
+ }
+}
+
+// TOP124 //
+int getBivalent(uint8_t input)
+{
+ switch ((int)input)
+ {
+ case 0x55:
+ return 0;
+ case 0x56:
+ return 1;
+ case 0x57:
+ return 2;
+ case 0x58:
+ return 3;
+ case 0x59:
+ return 4;
+ case 0x5A:
+ return 5;
+ default:
+ return -1;
+ }
+}
+
+// TOP92 //
+int getModel(std::vector &data, uint8_t index)
+{
+ uint8_t model[10] = { data[index], data[index+1], data[index+2], data[index+3], data[index+4], data[index+5], data[index+6], data[index+7], data[index+8], data[index+9] };
+ int result = -1;
+ int size = sizeof(KnownModels) / sizeof(KnownModels[0]);
+
+ for (unsigned int i = 0 ; i < size; i++)
+ {
+ if (memcmp(model, KnownModels[i], 10) == 0)
+ {
+ result = i;
+ break;
+ }
+ }
+
+ return result;
+}
+
+// TOP1 //
+// input1 = data[169]
+// input2 = data[170]
+float getPumpFlow(uint8_t input1, uint8_t input2)
+{
+ int PumpFlow2 = (int)input2;
+ float PumpFlow1 = (((float)input1 - 1) / 256);
+ float PumpFlow = PumpFlow2 + PumpFlow1;
+
+ return PumpFlow;
+}
+
+// TOP5, TOP6 //
+float getFractional(uint8_t input, uint8_t shift)
+{
+ float result;
+ int fractional = (int)((input >> shift) & 0b111) - 1;
+ result = fractional * 0.25;
+
+ return result;
+}
+
+// TOP44 //
+// errorType = data[113]
+// errorNumber = data[114]
+std::string getErrorInfo(uint8_t errorType, uint8_t errorNumber)
+{
+ int error_type = (int)(errorType);
+ int error_number = ((int)(errorNumber)) - 17;
+ char error_string[10];
+
+ switch (error_type)
+ {
+ case 177: // B1=F type error
+ sprintf(error_string, "F%02X", error_number);
+ break;
+ case 161: // A1=H type error
+ sprintf(error_string, "H%02X", error_number);
+ break;
+ default:
+ sprintf(error_string, "No error");
+ break;
+ }
+
+ return error_string;
+}
+
+bool getBoolState(uint8_t input)
+{
+ return input != 0;
+}
+
+std::string getTextState(const char **array, int index)
+{
+ int size = atoi(array[0]);
+
+ if ((index < 0) || (index >= size))
+ {
+ return "UNKNOWN";
+ }
+
+ return array[index + 1];
+}
diff --git a/prototypes/panasonic_heatpump/decode.h b/prototypes/panasonic_heatpump/decode.h
new file mode 100644
index 0000000..750d5eb
--- /dev/null
+++ b/prototypes/panasonic_heatpump/decode.h
@@ -0,0 +1,173 @@
+#pragma once
+#include
+#include
+#include
+#include
+#include
+
+#define NUMBER_OF_MODELS 51
+#define NUMBER_OF_TOPICS 127
+#define NUMBER_OF_TOPICS_EXTRA 6
+#define NUMBER_OF_OPT_TOPICS 7
+#define MAX_TOPIC_LEN 42
+
+int getBit1(uint8_t input);
+int getBit1and2(uint8_t input);
+int getBit3and4(uint8_t input);
+int getBit5and6(uint8_t input);
+int getBit7and8(uint8_t input);
+int getBit3and4and5(uint8_t input);
+int getLeft5bits(uint8_t input);
+int getRight3bits(uint8_t input);
+int getIntMinus1(uint8_t input);
+int getIntMinus128(uint8_t input);
+float getIntMinus1Div5(uint8_t input);
+float getIntMinus1Div50(uint8_t input);
+int getIntMinus1Times10(uint8_t input);
+int getIntMinus1Times50(uint8_t input);
+int getFirstByte(uint8_t input);
+int getSecondByte(uint8_t input);
+int getWord(uint8_t hi, uint8_t low);
+int getUintt16(uint8_t input1, uint8_t input2);
+
+int getPower(uint8_t input);
+int getOpMode(uint8_t input);
+int getModel(std::vector &data, uint8_t index);
+int getBivalent(uint8_t input);
+float getPumpFlow(uint8_t input1, uint8_t input2);
+float getFractional(uint8_t input, uint8_t shift);
+std::string getErrorInfo(uint8_t errorType, uint8_t errorNumber);
+
+bool getBoolState(uint8_t input);
+std::string getTextState(const char **array, int index);
+
+static const char *DisabledEnabled[] = {"2", "Disabled", "Enabled"};
+static const char *BlockedFree[] = {"2", "Blocked", "Free"};
+static const char *OffOn[] = {"2", "Off", "On"};
+static const char *InactiveActive[] = {"2", "Inactive", "Active"};
+static const char *PumpFlowRateMode[] = {"2", "DeltaT", "Max flow"};
+static const char *HolidayState[] = {"3", "Off", "Scheduled", "Active"};
+static const char *OpModeDesc[] = {"9", "Heat", "Cool", "Auto(heat)", "DHW", "Heat+DHW", "Cool+DHW", "Auto(heat)+DHW", "Auto(cool)", "Auto(cool)+DHW"};
+static const char *Powerfulmode[] = {"4", "Off", "30min", "60min", "90min"};
+static const char *Quietmode[] = {"4", "Off", "Level 1", "Level 2", "Level 3"};
+static const char *Valve[] = {"2", "Room", "DHW"};
+static const char *MixingValve[] = {"4", "Off", "Increase","Nothing","Decrease"};
+static const char *ZonesState[] = {"3", "Zone1 active", "Zone2 active", "Zone1 and zone2 active"};
+static const char *HeatCoolModeDesc[] = {"2", "Comp. Curve", "Direct"};
+static const char *SolarModeDesc[] = {"3", "Disabled", "Buffer", "DHW"};
+static const char *ZonesSensorType[] = {"4", "Water Temperature", "External Thermostat", "Internal Thermostat", "Thermistor"};
+static const char *LiquidType[] = {"2", "Water", "Glycol"};
+static const char *ExtPadHeaterType[] = {"3", "Disabled", "Type-A","Type-B"};
+static const char *Bivalent[] = {"6", "Off", "Alternativ", "A-Off", "Parallel", "P-Off", "Parallel Advanced"};
+
+static const char *ModelNames[] =
+{
+ "51", //string representation of number of known models (last model number + 1)
+ "WH-MDC05H3E5", //0
+ "WH-MDC07H3E5", //1
+ "IDU:WH-SXC09H3E5, ODU:WH-UX09HE5", //2
+ "IDU:WH-SDC09H3E8, ODU:WH-UD09HE8", //3
+ "IDU:WH-SXC09H3E8, ODU:WH-UX09HE8", //4
+ "IDU:WH-SXC12H9E8, ODU:WH-UX12HE8", //5
+ "IDU:WH-SXC16H9E8, ODU:WH-UX16HE8", //6
+ "IDU:WH-SDC05H3E5, ODU:WH-UD05HE5", //7
+ "IDU:WH-SDC0709J3E5, ODU:WH-UD09JE5", //8
+ "WH-MDC05J3E5", //9
+ "WH-MDC09H3E5", //10
+ "WH-MXC09H3E5", //11
+ "IDU:WH-ADC0309J3E5, ODU:WH-UD09JE5", //12
+ "IDU:WH-ADC0916H9E8, ODU:WH-UX12HE8", //13
+ "IDU:WH-SQC09H3E8, ODU:WH-UQ09HE8", //14
+ "IDU:WH-SDC09H3E5, ODU:WH-UD09HE5", //15
+ "IDU:WH-ADC0309H3E5, ODU:WH-UD09HE5", //16
+ "IDU:WH-ADC0309J3E5, ODU:WH-UD05JE5", //17
+ "IDU:WH-SDC0709J3E5, ODU:WH-UD07JE5", //18
+ "IDU:WH-SDC07H3E5-1, ODU:WH-UD07HE5-1", //19
+ "WH-MDC07J3E5", //20
+ "WH-MDC09J3E5", //21
+ "IDU:WH-SDC0305J3E5, ODU:WH-UD05JE5", //22
+ "WH-MXC09J3E8", //23
+ "WH-MXC12J9E8", //24
+ "IDU:WH-ADC1216H6E5, ODU:WH-UD12HE5", //25
+ "IDU:WH-ADC0309J3E5C, ODU:WH-UD07JE5", //26
+ "WH-MDC07J3E5", //27
+ "WH-MDC05J3E5", //28
+ "IDU:WH-UQ12HE8, ODU:WH-SQC12H9E8", //29
+ "IDU:WH-SXC12H6E5, ODU:WH-UX12HE5", //30
+ "WH-MDC09J3E5", //31
+ "WH-MXC09J3E5", //32
+ "IDU:WH-ADC1216H6E5C ODU:WH-UD12HE5", //33
+ "IDU:WH-ADC0509L3E5 ODU:WH-WDG07LE5", //34
+ "IDU:WH-SXC09H3E8 ODU:WH-UX09HE8", //35
+ "IDU:WH-ADC0309K3E5AN ODU:WH-UDZ07KE5", //36
+ "IDU:WH-SDC0309K3E5 ODU:WH-UDZ05KE5", //37
+ "IDU:WH-SDC0509L3E5 ODU:WH-WDG09LE5", //38
+ "IDU:WH-SDC12H9E8 ODU:WH-UD12HE8", //39
+ "IDU:WH-SDC0309K3E5, ODU:WH-UDZ07KE5", //40
+ "IDU:WH-ADC0916H9E8, ODU:WH-UX16HE8", //41
+ "IDU:WH-ADC0912H9E8, ODU:WH-UX12HE8", //42
+ "WH-MXC16J9E8", //43
+ "WH-MXC12J6E5", //44
+ "IDU:WH-SQC09H3E8, ODU:WH-UQ09HE8", //45
+ "IDU:WH-ADC0309K3E5 ODU:WH-UDZ09KE5", //46
+ "IDU:WH-ADC0916H9E8, ODU:WH-UX12HE8", //47
+ "IDU:WH-SDC0509L3E5 ODU:WH-WDG07LE5", //48
+ "IDU:WH-SXC09H3E5, ODU:WH-UX09HE5", //49
+ "IDU:WH-SXC12H9E8, ODU:WH-UX12HE8", //50
+};
+
+// stores the bytes #129 to #138 of known models in the same order as the ModelNames above
+static const uint8_t KnownModels[NUMBER_OF_MODELS][10] =
+{
+ 0xE2, 0xCF, 0x0B, 0x13, 0x33, 0x32, 0xD1, 0x0C, 0x16, 0x33, //0
+ 0xE2, 0xCF, 0x0B, 0x14, 0x33, 0x42, 0xD1, 0x0B, 0x17, 0x33, //1
+ 0xE2, 0xCF, 0x0D, 0x77, 0x09, 0x12, 0xD0, 0x0B, 0x05, 0x11, //2
+ 0xE2, 0xCF, 0x0C, 0x88, 0x05, 0x12, 0xD0, 0x0B, 0x97, 0x05, //3
+ 0xE2, 0xCF, 0x0D, 0x85, 0x05, 0x12, 0xD0, 0x0C, 0x94, 0x05, //4
+ 0xE2, 0xCF, 0x0D, 0x86, 0x05, 0x12, 0xD0, 0x0C, 0x95, 0x05, //5
+ 0xE2, 0xCF, 0x0D, 0x87, 0x05, 0x12, 0xD0, 0x0C, 0x96, 0x05, //6
+ 0xE2, 0xCE, 0x0D, 0x71, 0x81, 0x72, 0xCE, 0x0C, 0x92, 0x81, //7
+ 0x62, 0xD2, 0x0B, 0x43, 0x54, 0x42, 0xD2, 0x0B, 0x72, 0x66, //8
+ 0xC2, 0xD3, 0x0B, 0x33, 0x65, 0xB2, 0xD3, 0x0B, 0x94, 0x65, //9
+ 0xE2, 0xCF, 0x0B, 0x15, 0x33, 0x42, 0xD1, 0x0B, 0x18, 0x33, //10
+ 0xE2, 0xCF, 0x0B, 0x41, 0x34, 0x82, 0xD1, 0x0B, 0x31, 0x35, //11
+ 0x62, 0xD2, 0x0B, 0x45, 0x54, 0x42, 0xD2, 0x0B, 0x47, 0x55, //12
+ 0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0D, 0x95, 0x05, //13
+ 0xE2, 0xCF, 0x0B, 0x82, 0x05, 0x12, 0xD0, 0x0C, 0x91, 0x05, //14
+ 0xE2, 0xCF, 0x0C, 0x55, 0x14, 0x12, 0xD0, 0x0B, 0x15, 0x08, //15
+ 0xE2, 0xCF, 0x0C, 0x43, 0x00, 0x12, 0xD0, 0x0B, 0x15, 0x08, //16
+ 0x62, 0xD2, 0x0B, 0x45, 0x54, 0x32, 0xD2, 0x0C, 0x45, 0x55, //17
+ 0x62, 0xD2, 0x0B, 0x43, 0x54, 0x42, 0xD2, 0x0C, 0x46, 0x55, //18
+ 0xE2, 0xCF, 0x0C, 0x54, 0x14, 0x12, 0xD0, 0x0B, 0x14, 0x08, //19
+ 0xC2, 0xD3, 0x0B, 0x34, 0x65, 0xB2, 0xD3, 0x0B, 0x95, 0x65, //20
+ 0xC2, 0xD3, 0x0B, 0x35, 0x65, 0xB2, 0xD3, 0x0B, 0x96, 0x65, //21
+ 0x62, 0xD2, 0x0B, 0x41, 0x54, 0x32, 0xD2, 0x0C, 0x45, 0x55, //22
+ 0x32, 0xD4, 0x0B, 0x87, 0x84, 0x73, 0x90, 0x0C, 0x84, 0x84, //23
+ 0x32, 0xD4, 0x0B, 0x88, 0x84, 0x73, 0x90, 0x0C, 0x85, 0x84, //24
+ 0xE2, 0xCF, 0x0B, 0x75, 0x09, 0x12, 0xD0, 0x0C, 0x06, 0x11, //25
+ 0x42, 0xD4, 0x0B, 0x83, 0x71, 0x42, 0xD2, 0x0C, 0x46, 0x55, //26
+ 0xC2, 0xD3, 0x0C, 0x34, 0x65, 0xB2, 0xD3, 0x0B, 0x95, 0x65, //27
+ 0xC2, 0xD3, 0x0C, 0x33, 0x65, 0xB2, 0xD3, 0x0B, 0x94, 0x65, //28
+ 0xE2, 0xCF, 0x0B, 0x83, 0x05, 0x12, 0xD0, 0x0D, 0x92, 0x05, //29
+ 0xE2, 0xCF, 0x0C, 0x78, 0x09, 0x12, 0xD0, 0x0B, 0x06, 0x11, //30
+ 0xC2, 0xD3, 0x0C, 0x35, 0x65, 0xB2, 0xD3, 0x0B, 0x96, 0x65, //31
+ 0x32, 0xD4, 0x0B, 0x99, 0x77, 0x62, 0x90, 0x0B, 0x01, 0x78, //32
+ 0x42, 0xD4, 0x0B, 0x15, 0x76, 0x12, 0xD0, 0x0B, 0x10, 0x11, //33
+ 0xE2, 0xD5, 0x0C, 0x29, 0x99, 0x83, 0x92, 0x0C, 0x28, 0x98, //34
+ 0xE2, 0xCF, 0x0D, 0x85, 0x05, 0x12, 0xD0, 0x0E, 0x94, 0x05, //35
+ 0xE2, 0xD5, 0x0D, 0x36, 0x99, 0x02, 0xD6, 0x0F, 0x67, 0x95, //36
+ 0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0E, 0x66, 0x95, //37
+ 0xE2, 0xD5, 0x0B, 0x34, 0x99, 0x83, 0x92, 0x0C, 0x29, 0x98, //38
+ 0xE2, 0xCF, 0x0C, 0x89, 0x05, 0x12, 0xD0, 0x0C, 0x98, 0x05, //39
+ 0xE2, 0xD5, 0x0B, 0x08, 0x95, 0x02, 0xD6, 0x0E, 0x67, 0x95, //40
+ 0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0C, 0x96, 0x05, //41
+ 0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0E, 0x95, 0x05, //42
+ 0x32, 0xD4, 0x0B, 0x89, 0x84, 0x73, 0x90, 0x0C, 0x86, 0x84, //43
+ 0x32, 0xD4, 0x0B, 0x00, 0x78, 0x62, 0x90, 0x0B, 0x02, 0x78, //44
+ 0xE2, 0xCF, 0x0B, 0x82, 0x05, 0x12, 0xD0, 0x0D, 0x91, 0x05, //45
+ 0xE2, 0xD5, 0x0D, 0x99, 0x94, 0x02, 0xD6, 0x0D, 0x68, 0x95, //46
+ 0xE2, 0xCF, 0x0C, 0x74, 0x09, 0x12, 0xD0, 0x0C, 0x95, 0x05, //47
+ 0xE2, 0xD5, 0x0B, 0x34, 0x99, 0x83, 0x92, 0x0C, 0x28, 0x98, //48
+ 0xE2, 0xCF, 0x0D, 0x77, 0x09, 0x12, 0xD0, 0x0C, 0x05, 0x11, //49
+ 0xE2, 0xCF, 0x0D, 0x86, 0x05, 0x12, 0xD0, 0x0E, 0x95, 0x05, //50
+};
diff --git a/prototypes/panasonic_heatpump/heishamon_decode.xlsx b/prototypes/panasonic_heatpump/heishamon_decode.xlsx
new file mode 100644
index 0000000..aea5421
Binary files /dev/null and b/prototypes/panasonic_heatpump/heishamon_decode.xlsx differ
diff --git a/prototypes/panasonic_heatpump/panasonic-heatpump-prototype.yaml b/prototypes/panasonic_heatpump/panasonic-heatpump-prototype.yaml
new file mode 100644
index 0000000..e9465d7
--- /dev/null
+++ b/prototypes/panasonic_heatpump/panasonic-heatpump-prototype.yaml
@@ -0,0 +1,162 @@
+substitutions:
+ mdns_name: panasonic-heatpump
+ device_name: Panasonic Heatpump
+ device_description: Reads/Controls your Panasonic Aquarea Heatpump over UART
+
+ pin_rx_hp: GPIO4 # heatpump reads data (RX) on this pin (green)
+ pin_tx_hp: GPIO3 # heatpump sends data (TX) on this pin (yellow)
+ pin_tx_cz: GPIO1 # WiFi module sends data (TX) on this pin (blue)
+ pin_rx_cz: GPIO0 # WiFi module reads data (RX) on this pin (white)
+
+ # CN-CNT Pinout (from top to bottom)
+ # 1 - +5V (250mA)
+ # 2 - 0-5V TX (from heatpump)
+ # 3 - 0-5V RX (to heatpump)
+ # 4 - +12V (250mA)
+ # 5 - GND
+
+esp32:
+ board: esp32-c3-devkitm-1
+ variant: ESP32C3
+ framework:
+ type: arduino
+
+esphome:
+ name: $mdns_name
+ friendly_name: $device_name
+ comment: $device_description
+ includes:
+ - prototypes/panasonic_heatpump/decode.h
+ - prototypes/panasonic_heatpump/decode.cpp
+
+ota:
+ platform: esphome
+ password: !secret ota_password
+ id: ota_pass
+
+api:
+ encryption:
+ key: !secret ha_api_key
+
+wifi:
+ ssid: !secret wifi_ssid
+ password: !secret wifi_password
+ ap:
+ ssid: "${device_name} Fallback"
+ password: !secret fallback_password
+
+web_server:
+ port: 80
+ auth:
+ username: !secret webserver_username
+ password: !secret webserver_password
+
+captive_portal:
+
+improv_serial:
+
+logger:
+ level: DEBUG
+
+uart:
+ - id: uart_hp
+ # switch rx and tx to read what the heatpump is sending
+ tx_pin: $pin_rx_hp
+ rx_pin: $pin_tx_hp
+ baud_rate: 9600
+ data_bits: 8
+ parity: EVEN
+ stop_bits: 1
+ debug:
+ direction: RX
+ dummy_receiver: true # needed if no uart component is available
+ after:
+ bytes: 203
+ sequence:
+ - lambda: |-
+ ESP_LOGD("custom", "Heatpump:");
+ UARTDebug::log_hex(direction, bytes, ',');
+ if (bytes.size() == 203)
+ {
+ id(top0).publish_state(getBoolState(getBit7and8(bytes[4])));
+ id(top1).publish_state(getPumpFlow(bytes[169], bytes[170]));
+ id(top2).publish_state(getBoolState(getBit1and2(bytes[4])));
+ id(top3).publish_state(getBoolState(getBit1and2(bytes[7])));
+ id(top4).publish_state(getTextState(OpModeDesc, getOpMode(bytes[6])));
+ // ...
+ // (for more topics see heishamon_decode.xlsx or code-gen-result.md)
+ }
+ - uart.write: # Write rx to tx.
+ id: uart_cz
+ data: !lambda return bytes;
+ - id: uart_cz
+ # switch rx and tx to read what the WiFi module is sending
+ tx_pin: $pin_rx_cz
+ rx_pin: $pin_tx_cz
+ baud_rate: 9600
+ data_bits: 8
+ parity: EVEN
+ stop_bits: 1
+ debug:
+ direction: RX
+ dummy_receiver: true # needed if no uart component is available
+ after:
+ bytes: 111
+ sequence:
+ - lambda: |-
+ ESP_LOGD("custom", "CZ-TAW1:");
+ UARTDebug::log_hex(direction, bytes, ',');
+ - uart.write: # Write rx to tx.
+ id: uart_hp
+ data: !lambda return bytes;
+
+sensor:
+ - platform: wifi_signal
+ name: WiFi Signal
+
+ - platform: template
+ id: top1
+ name: "Pump Flow"
+ unit_of_measurement: l/min
+ lambda: "return {};"
+ # ...
+ # (for more topics see heishamon_decode.xlsx or code-gen-result.md)
+
+text_sensor:
+ - platform: version
+ hide_timestamp: true
+ name: ESPHome Version
+ - platform: wifi_info
+ ip_address:
+ name: IP Addresse
+ icon: mdi:ip
+
+ - platform: template
+ id: top4
+ name: "Operating Mode State"
+ lambda: "return {};"
+ # ...
+ # (for more topics see heishamon_decode.xlsx or code-gen-result.md)
+
+binary_sensor:
+ - platform: status
+ name: Status
+
+ - platform: template
+ id: top0
+ name: "Heatpump State"
+ lambda: "return {};"
+ - platform: template
+ id: top2
+ name: "Force DHW State"
+ lambda: "return {};"
+ - platform: template
+ id: top3
+ name: "Quiet Mode Schedule"
+ lambda: "return {};"
+ # ...
+ # (for more topics see heishamon_decode.xlsx or code-gen-result.md)
+
+button:
+ - platform: restart
+ name: Restart
diff --git a/prototypes/panasonic_heatpump/wiring.jpeg b/prototypes/panasonic_heatpump/wiring.jpeg
new file mode 100644
index 0000000..471cf08
Binary files /dev/null and b/prototypes/panasonic_heatpump/wiring.jpeg differ