Compare commits
4 Commits
1a7f29b363
...
c319928c65
| Author | SHA1 | Date | |
|---|---|---|---|
| c319928c65 | |||
| c4734a11ca | |||
| e22979c1c7 | |||
| a430110f94 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -18,13 +18,13 @@
|
|||||||
</ParameterRefs>
|
</ParameterRefs>
|
||||||
<ComObjectTable>
|
<ComObjectTable>
|
||||||
<ComObject Id="%AID%_O-%TT%%CC%%PPP+00%" Name="KOf-%TT%%CC%%PPP+00% "
|
<ComObject Id="%AID%_O-%TT%%CC%%PPP+00%" Name="KOf-%TT%%CC%%PPP+00% "
|
||||||
Text="Eingang %CC%%Pn%" Number="%CC%%Pn%"
|
Text="Eingang %CC%%Pn%" Number="%Pn%"
|
||||||
FunctionText="Bereich %CC%, Funktion Eingang %Pn%" ObjectSize="4 Bytes"
|
FunctionText="Bereich %CC%, Funktion Eingang %Pn%" ObjectSize="4 Bytes"
|
||||||
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
ReadOnInitFlag="Disabled" />
|
ReadOnInitFlag="Disabled" />
|
||||||
<ComObject Id="%AID%_O-%TT%%CC%%PPP+01%" Name="KOf-%TT%%CC%%PPP+01% "
|
<ComObject Id="%AID%_O-%TT%%CC%%PPP+01%" Name="KOf-%TT%%CC%%PPP+01% "
|
||||||
Text="Ausgang %CC%%Pn+1%" Number="%CC%%Pn+1%"
|
Text="Ausgang %CC%%Pn+1%" Number="%Pn+1%"
|
||||||
FunctionText="Bereich %CC%, Funktion Ausgang %Pn+1%" ObjectSize="4 Bytes"
|
FunctionText="Bereich %CC%, Funktion Ausgang %Pn+1%" ObjectSize="4 Bytes"
|
||||||
ReadFlag="Disabled" WriteFlag="Disabled" CommunicationFlag="Enabled"
|
ReadFlag="Disabled" WriteFlag="Disabled" CommunicationFlag="Enabled"
|
||||||
TransmitFlag="Enabled" UpdateFlag="Disabled"
|
TransmitFlag="Enabled" UpdateFlag="Disabled"
|
||||||
|
|||||||
@ -26,16 +26,23 @@
|
|||||||
</ParameterType>
|
</ParameterType>
|
||||||
<ParameterType Id="%AID%_PT-FunctionCount" Name="FunctionCount">
|
<ParameterType Id="%AID%_PT-FunctionCount" Name="FunctionCount">
|
||||||
<TypeRestriction Base="Value" SizeInBit="4">
|
<TypeRestriction Base="Value" SizeInBit="4">
|
||||||
<Enumeration Text="1" Value="0" Id="%ENID%" />
|
<Enumeration Text="0" Value="0" Id="%ENID%" />
|
||||||
<Enumeration Text="2" Value="1" Id="%ENID%" />
|
<Enumeration Text="1" Value="1" Id="%ENID%" />
|
||||||
<Enumeration Text="3" Value="2" Id="%ENID%" />
|
<Enumeration Text="2" Value="2" Id="%ENID%" />
|
||||||
<Enumeration Text="4" Value="3" Id="%ENID%" />
|
<Enumeration Text="3" Value="3" Id="%ENID%" />
|
||||||
<Enumeration Text="5" Value="4" Id="%ENID%" />
|
<Enumeration Text="4" Value="4" Id="%ENID%" />
|
||||||
<Enumeration Text="6" Value="5" Id="%ENID%" />
|
<Enumeration Text="5" Value="5" Id="%ENID%" />
|
||||||
<Enumeration Text="7" Value="6" Id="%ENID%" />
|
<Enumeration Text="6" Value="6" Id="%ENID%" />
|
||||||
<Enumeration Text="8" Value="7" Id="%ENID%" />
|
<Enumeration Text="7" Value="7" Id="%ENID%" />
|
||||||
<Enumeration Text="9" Value="8" Id="%ENID%" />
|
<Enumeration Text="8" Value="8" Id="%ENID%" />
|
||||||
<Enumeration Text="10" Value="9" Id="%ENID%" />
|
<Enumeration Text="9" Value="9" Id="%ENID%" />
|
||||||
|
<Enumeration Text="10" Value="10" Id="%ENID%" />
|
||||||
|
</TypeRestriction>
|
||||||
|
</ParameterType>
|
||||||
|
<ParameterType Id="%AID%_PT-Checkbox" Name="Checkbox">
|
||||||
|
<TypeRestriction Base="Value" SizeInBit="1" UIHint="CheckBox">
|
||||||
|
<Enumeration Text="Deaktiviert" Value="0" Id="%ENID%" />
|
||||||
|
<Enumeration Text="Aktiviert" Value="1" Id="%ENID%" />
|
||||||
</TypeRestriction>
|
</TypeRestriction>
|
||||||
</ParameterType>
|
</ParameterType>
|
||||||
<ParameterType Id="%AID%_PT-FunctionType" Name="FunctionType">
|
<ParameterType Id="%AID%_PT-FunctionType" Name="FunctionType">
|
||||||
|
|||||||
@ -7,9 +7,9 @@
|
|||||||
<ApplicationPrograms>
|
<ApplicationPrograms>
|
||||||
<ApplicationProgram Id="%AID%" ApplicationNumber="621">
|
<ApplicationProgram Id="%AID%" ApplicationNumber="621">
|
||||||
<op:part href="Function.parts.xml" name="FN" instances="10">
|
<op:part href="Function.parts.xml" name="FN" instances="10">
|
||||||
<op:param name="%ParamOffset%" value="59" increment="20" />
|
<op:param name="%ParamOffset%" value="62" increment="20" />
|
||||||
<op:param name="%Pl%" value="0" asLetter="true" increment="1" />
|
<op:param name="%Pl%" value="0" asLetter="true" increment="1" />
|
||||||
<op:param name="%Pn%" value="1" increment="2" digits="3" />
|
<op:param name="%Pn%" value="30" increment="2" digits="3" />
|
||||||
<op:param name="%PPP%" value="100" increment="100" digits="3" />
|
<op:param name="%PPP%" value="100" increment="100" digits="3" />
|
||||||
<op:param name="%TRef%" value="26" increment="1" digits="2" />
|
<op:param name="%TRef%" value="26" increment="1" digits="2" />
|
||||||
</op:part>
|
</op:part>
|
||||||
@ -22,6 +22,63 @@
|
|||||||
ParameterType="%AID%_PT-Text40Byte"
|
ParameterType="%AID%_PT-Text40Byte"
|
||||||
Text="Beschreibung des Bereiches"
|
Text="Beschreibung des Bereiches"
|
||||||
Value="" />
|
Value="" />
|
||||||
|
|
||||||
|
<!-- Checkbox-Parameter für Standard-KOs (3 Bytes Union, BitOffset 0-16) -->
|
||||||
|
<Union SizeInBit="24">
|
||||||
|
<Memory CodeSegment="%AID%_RS-04-00000" Offset="59" BitOffset="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%010" Name="p%C%ChkTemperatur"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="0"
|
||||||
|
Text="Temperatur" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%011" Name="p%C%ChkLuftfeuchtigkeit"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="1"
|
||||||
|
Text="Luftfeuchtigkeit" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%012" Name="p%C%ChkPraesenz"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="2"
|
||||||
|
Text="Präsenz" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%013" Name="p%C%ChkFensterkontakt"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="3"
|
||||||
|
Text="Fensterkontakt" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%014" Name="p%C%ChkSolltemperatur"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="4"
|
||||||
|
Text="Solltemperatur" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%015" Name="p%C%ChkHeizungsventil"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="5"
|
||||||
|
Text="Heizungsventil" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%016" Name="p%C%ChkSteckdose1"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="6"
|
||||||
|
Text="Steckdose 1" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%017" Name="p%C%ChkSteckdose2"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="0" BitOffset="7"
|
||||||
|
Text="Steckdose 2" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%018" Name="p%C%ChkLicht1"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="0"
|
||||||
|
Text="Licht 1" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%019" Name="p%C%ChkLicht2"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="1"
|
||||||
|
Text="Licht 2" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%020" Name="p%C%ChkDimmen1"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="2"
|
||||||
|
Text="Dimmen 1" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%021" Name="p%C%ChkDimmen2"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="3"
|
||||||
|
Text="Dimmen 2" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%022" Name="p%C%ChkJalousie1"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="4"
|
||||||
|
Text="Jalousie 1" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%023" Name="p%C%ChkJalousie2"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="5"
|
||||||
|
Text="Jalousie 2" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%024" Name="p%C%ChkCO2"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="6"
|
||||||
|
Text="CO2" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%025" Name="p%C%ChkHelligkeit"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="1" BitOffset="7"
|
||||||
|
Text="Helligkeit" Value="0" />
|
||||||
|
<Parameter Id="%AID%_UP-%TT%%CC%026" Name="p%C%ChkSzene"
|
||||||
|
ParameterType="%AID%_PT-Checkbox" Offset="2" BitOffset="0"
|
||||||
|
Text="Szene" Value="0" />
|
||||||
|
</Union>
|
||||||
|
|
||||||
<Parameter Id="%AID%_P-%TT%%CC%005" Name="p%C%FunctionCount" Offset="0"
|
<Parameter Id="%AID%_P-%TT%%CC%005" Name="p%C%FunctionCount" Offset="0"
|
||||||
BitOffset="8" ParameterType="%AID%_PT-FunctionCount"
|
BitOffset="8" ParameterType="%AID%_PT-FunctionCount"
|
||||||
Text="Anzahl der Funktionen" Value="0" />
|
Text="Anzahl der Funktionen" Value="0" />
|
||||||
@ -32,6 +89,42 @@
|
|||||||
<ParameterRef Id="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201"
|
<ParameterRef Id="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201"
|
||||||
RefId="%AID%_P-%TT%%CC%002" />
|
RefId="%AID%_P-%TT%%CC%002" />
|
||||||
|
|
||||||
|
<!-- Checkbox ParameterRefs -->
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%010_R-%TT%%CC%01001"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%010" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%011_R-%TT%%CC%01101"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%011" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%012_R-%TT%%CC%01201"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%012" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%013_R-%TT%%CC%01301"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%013" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%014_R-%TT%%CC%01401"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%014" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%015_R-%TT%%CC%01501"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%015" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%016_R-%TT%%CC%01601"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%016" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%017_R-%TT%%CC%01701"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%017" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%018_R-%TT%%CC%01801"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%018" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%019_R-%TT%%CC%01901"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%019" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%020_R-%TT%%CC%02001"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%020" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%021_R-%TT%%CC%02101"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%021" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%022_R-%TT%%CC%02201"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%022" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%023_R-%TT%%CC%02301"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%023" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%024_R-%TT%%CC%02401"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%024" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%025_R-%TT%%CC%02501"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%025" />
|
||||||
|
<ParameterRef Id="%AID%_UP-%TT%%CC%026_R-%TT%%CC%02601"
|
||||||
|
RefId="%AID%_UP-%TT%%CC%026" />
|
||||||
|
|
||||||
<ParameterRef Id="%AID%_UP-%TT%%CC%005_R-%TT%%CC%00501"
|
<ParameterRef Id="%AID%_UP-%TT%%CC%005_R-%TT%%CC%00501"
|
||||||
RefId="%AID%_P-%TT%%CC%005" />
|
RefId="%AID%_P-%TT%%CC%005" />
|
||||||
|
|
||||||
@ -39,9 +132,276 @@
|
|||||||
instanceTo="10" />
|
instanceTo="10" />
|
||||||
</ParameterRefs>
|
</ParameterRefs>
|
||||||
<ComObjectTable>
|
<ComObjectTable>
|
||||||
|
<!-- Standard-KOs (Index 0-28) -->
|
||||||
|
<!-- 0: Temperatur -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S000" Name="KoS%CC%000"
|
||||||
|
Text="Temperatur" Number="0"
|
||||||
|
FunctionText="Bereich %CC%, Temperatur" ObjectSize="2 Bytes"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 1: Luftfeuchtigkeit -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S001" Name="KoS%CC%001"
|
||||||
|
Text="Luftfeuchtigkeit" Number="1"
|
||||||
|
FunctionText="Bereich %CC%, Luftfeuchtigkeit" ObjectSize="2 Bytes"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 2: Präsenz -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S002" Name="KoS%CC%002"
|
||||||
|
Text="Präsenz" Number="2"
|
||||||
|
FunctionText="Bereich %CC%, Präsenz" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 3: Fensterkontakt -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S003" Name="KoS%CC%003"
|
||||||
|
Text="Fensterkontakt" Number="3"
|
||||||
|
FunctionText="Bereich %CC%, Fensterkontakt" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 4: Solltemperatur -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S004" Name="KoS%CC%004"
|
||||||
|
Text="Solltemperatur" Number="4"
|
||||||
|
FunctionText="Bereich %CC%, Solltemperatur" ObjectSize="2 Bytes"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 5: Heizungsventil -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S005" Name="KoS%CC%005"
|
||||||
|
Text="Heizungsventil" Number="5"
|
||||||
|
FunctionText="Bereich %CC%, Heizungsventil" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 6: Steckdose 1 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S006" Name="KoS%CC%006"
|
||||||
|
Text="Steckdose 1 Schalten" Number="6"
|
||||||
|
FunctionText="Bereich %CC%, Steckdose 1 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 7: Steckdose 1 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S007" Name="KoS%CC%007"
|
||||||
|
Text="Steckdose 1 Status" Number="7"
|
||||||
|
FunctionText="Bereich %CC%, Steckdose 1 Status" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 8: Steckdose 2 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S008" Name="KoS%CC%008"
|
||||||
|
Text="Steckdose 2 Schalten" Number="8"
|
||||||
|
FunctionText="Bereich %CC%, Steckdose 2 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 9: Steckdose 2 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S009" Name="KoS%CC%009"
|
||||||
|
Text="Steckdose 2 Status" Number="9"
|
||||||
|
FunctionText="Bereich %CC%, Steckdose 2 Status" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 10: Licht 1 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S010" Name="KoS%CC%010"
|
||||||
|
Text="Licht 1 Schalten" Number="10"
|
||||||
|
FunctionText="Bereich %CC%, Licht 1 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 11: Licht 1 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S011" Name="KoS%CC%011"
|
||||||
|
Text="Licht 1 Status" Number="11"
|
||||||
|
FunctionText="Bereich %CC%, Licht 1 Status" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 12: Licht 2 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S012" Name="KoS%CC%012"
|
||||||
|
Text="Licht 2 Schalten" Number="12"
|
||||||
|
FunctionText="Bereich %CC%, Licht 2 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 13: Licht 2 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S013" Name="KoS%CC%013"
|
||||||
|
Text="Licht 2 Status" Number="13"
|
||||||
|
FunctionText="Bereich %CC%, Licht 2 Status" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 14: Dimmen 1 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S014" Name="KoS%CC%014"
|
||||||
|
Text="Dimmen 1 Schalten" Number="14"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 1 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 15: Dimmen 1 Wert -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S015" Name="KoS%CC%015"
|
||||||
|
Text="Dimmen 1 Wert" Number="15"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 1 Wert" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 16: Dimmen 1 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S016" Name="KoS%CC%016"
|
||||||
|
Text="Dimmen 1 Status" Number="16"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 1 Status" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 17: Dimmen 2 Schalten -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S017" Name="KoS%CC%017"
|
||||||
|
Text="Dimmen 2 Schalten" Number="17"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 2 Schalten" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 18: Dimmen 2 Wert -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S018" Name="KoS%CC%018"
|
||||||
|
Text="Dimmen 2 Wert" Number="18"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 2 Wert" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 19: Dimmen 2 Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S019" Name="KoS%CC%019"
|
||||||
|
Text="Dimmen 2 Status" Number="19"
|
||||||
|
FunctionText="Bereich %CC%, Dimmen 2 Status" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 20: Jalousie 1 Auf/Ab -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S020" Name="KoS%CC%020"
|
||||||
|
Text="Jalousie 1 Auf/Ab" Number="20"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 1 Auf/Ab" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 21: Jalousie 1 Position -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S021" Name="KoS%CC%021"
|
||||||
|
Text="Jalousie 1 Position" Number="21"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 1 Position" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 22: Jalousie 1 Pos. Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S022" Name="KoS%CC%022"
|
||||||
|
Text="Jalousie 1 Pos. Status" Number="22"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 1 Pos. Status" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 23: Jalousie 2 Auf/Ab -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S023" Name="KoS%CC%023"
|
||||||
|
Text="Jalousie 2 Auf/Ab" Number="23"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 2 Auf/Ab" ObjectSize="1 Bit"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 24: Jalousie 2 Position -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S024" Name="KoS%CC%024"
|
||||||
|
Text="Jalousie 2 Position" Number="24"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 2 Position" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 25: Jalousie 2 Pos. Status -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S025" Name="KoS%CC%025"
|
||||||
|
Text="Jalousie 2 Pos. Status" Number="25"
|
||||||
|
FunctionText="Bereich %CC%, Jalousie 2 Pos. Status" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 26: CO2 -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S026" Name="KoS%CC%026"
|
||||||
|
Text="CO2" Number="26"
|
||||||
|
FunctionText="Bereich %CC%, CO2" ObjectSize="2 Bytes"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 27: Helligkeit -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S027" Name="KoS%CC%027"
|
||||||
|
Text="Helligkeit" Number="27"
|
||||||
|
FunctionText="Bereich %CC%, Helligkeit" ObjectSize="2 Bytes"
|
||||||
|
ReadFlag="Disabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Disabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
<!-- 28: Szene -->
|
||||||
|
<ComObject Id="%AID%_O-%TT%%CC%S028" Name="KoS%CC%028"
|
||||||
|
Text="Szene" Number="28"
|
||||||
|
FunctionText="Bereich %CC%, Szene" ObjectSize="1 Byte"
|
||||||
|
ReadFlag="Enabled" WriteFlag="Enabled" CommunicationFlag="Enabled"
|
||||||
|
TransmitFlag="Enabled" UpdateFlag="Enabled"
|
||||||
|
ReadOnInitFlag="Disabled" />
|
||||||
|
|
||||||
|
<!-- Benutzerdefinierte Funktions-KOs (ab Index 30) -->
|
||||||
<op:usePart name="FN" xpath="//ComObjectTable/*" />
|
<op:usePart name="FN" xpath="//ComObjectTable/*" />
|
||||||
</ComObjectTable>
|
</ComObjectTable>
|
||||||
<ComObjectRefs>
|
<ComObjectRefs>
|
||||||
|
<!-- Standard-KO ComObjectRefs mit DPT -->
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S000_R-%TT%%CC%S00001"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S000" DatapointType="DPST-9-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S001_R-%TT%%CC%S00101"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S001" DatapointType="DPST-9-7" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S002_R-%TT%%CC%S00201"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S002" DatapointType="DPST-1-18" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S003_R-%TT%%CC%S00301"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S003" DatapointType="DPST-1-19" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S004_R-%TT%%CC%S00401"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S004" DatapointType="DPST-9-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S005_R-%TT%%CC%S00501"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S005" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S006_R-%TT%%CC%S00601"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S006" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S007_R-%TT%%CC%S00701"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S007" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S008_R-%TT%%CC%S00801"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S008" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S009_R-%TT%%CC%S00901"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S009" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S010_R-%TT%%CC%S01001"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S010" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S011_R-%TT%%CC%S01101"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S011" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S012_R-%TT%%CC%S01201"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S012" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S013_R-%TT%%CC%S01301"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S013" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S014_R-%TT%%CC%S01401"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S014" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S015_R-%TT%%CC%S01501"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S015" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S016_R-%TT%%CC%S01601"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S016" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S017_R-%TT%%CC%S01701"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S017" DatapointType="DPST-1-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S018_R-%TT%%CC%S01801"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S018" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S019_R-%TT%%CC%S01901"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S019" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S020_R-%TT%%CC%S02001"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S020" DatapointType="DPST-1-8" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S021_R-%TT%%CC%S02101"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S021" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S022_R-%TT%%CC%S02201"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S022" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S023_R-%TT%%CC%S02301"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S023" DatapointType="DPST-1-8" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S024_R-%TT%%CC%S02401"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S024" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S025_R-%TT%%CC%S02501"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S025" DatapointType="DPST-5-1" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S026_R-%TT%%CC%S02601"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S026" DatapointType="DPST-9-8" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S027_R-%TT%%CC%S02701"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S027" DatapointType="DPST-9-4" />
|
||||||
|
<ComObjectRef Id="%AID%_O-%TT%%CC%S028_R-%TT%%CC%S02801"
|
||||||
|
RefId="%AID%_O-%TT%%CC%S028" DatapointType="DPST-17-1" />
|
||||||
|
|
||||||
|
<!-- Benutzerdefinierte Funktions-KO Refs -->
|
||||||
<op:usePart name="FN" xpath="//ComObjectRefs/*" />
|
<op:usePart name="FN" xpath="//ComObjectRefs/*" />
|
||||||
</ComObjectRefs>
|
</ComObjectRefs>
|
||||||
</Static>
|
</Static>
|
||||||
@ -63,6 +423,161 @@
|
|||||||
<ParameterRefRef RefId="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201"
|
<ParameterRefRef RefId="%AID%_P-%TT%%CC%002_R-%TT%%CC%00201"
|
||||||
IndentLevel="1" />
|
IndentLevel="1" />
|
||||||
|
|
||||||
|
<!-- Standard-Objekte -->
|
||||||
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Standard-Objekte"
|
||||||
|
UIHint="Headline" />
|
||||||
|
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%010_R-%TT%%CC%01001"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%011_R-%TT%%CC%01101"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%012_R-%TT%%CC%01201"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%013_R-%TT%%CC%01301"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%014_R-%TT%%CC%01401"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%015_R-%TT%%CC%01501"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%016_R-%TT%%CC%01601"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%017_R-%TT%%CC%01701"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%018_R-%TT%%CC%01801"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%019_R-%TT%%CC%01901"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%020_R-%TT%%CC%02001"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%021_R-%TT%%CC%02101"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%022_R-%TT%%CC%02201"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%023_R-%TT%%CC%02301"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%024_R-%TT%%CC%02401"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%025_R-%TT%%CC%02501"
|
||||||
|
IndentLevel="1" />
|
||||||
|
<ParameterRefRef RefId="%AID%_UP-%TT%%CC%026_R-%TT%%CC%02601"
|
||||||
|
IndentLevel="1" />
|
||||||
|
|
||||||
|
<!-- Bedingte KO-Anzeige per Checkbox: Temperatur -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%010_R-%TT%%CC%01001">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S000_R-%TT%%CC%S00001" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Luftfeuchtigkeit -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%011_R-%TT%%CC%01101">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S001_R-%TT%%CC%S00101" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Präsenz -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%012_R-%TT%%CC%01201">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S002_R-%TT%%CC%S00201" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Fensterkontakt -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%013_R-%TT%%CC%01301">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S003_R-%TT%%CC%S00301" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Solltemperatur -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%014_R-%TT%%CC%01401">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S004_R-%TT%%CC%S00401" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Heizungsventil -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%015_R-%TT%%CC%01501">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S005_R-%TT%%CC%S00501" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Steckdose 1 (2 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%016_R-%TT%%CC%01601">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S006_R-%TT%%CC%S00601" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S007_R-%TT%%CC%S00701" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Steckdose 2 (2 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%017_R-%TT%%CC%01701">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S008_R-%TT%%CC%S00801" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S009_R-%TT%%CC%S00901" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Licht 1 (2 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%018_R-%TT%%CC%01801">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S010_R-%TT%%CC%S01001" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S011_R-%TT%%CC%S01101" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Licht 2 (2 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%019_R-%TT%%CC%01901">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S012_R-%TT%%CC%S01201" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S013_R-%TT%%CC%S01301" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Dimmen 1 (3 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%020_R-%TT%%CC%02001">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S014_R-%TT%%CC%S01401" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S015_R-%TT%%CC%S01501" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S016_R-%TT%%CC%S01601" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Dimmen 2 (3 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%021_R-%TT%%CC%02101">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S017_R-%TT%%CC%S01701" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S018_R-%TT%%CC%S01801" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S019_R-%TT%%CC%S01901" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Jalousie 1 (3 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%022_R-%TT%%CC%02201">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S020_R-%TT%%CC%S02001" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S021_R-%TT%%CC%S02101" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S022_R-%TT%%CC%S02201" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Jalousie 2 (3 KOs) -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%023_R-%TT%%CC%02301">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S023_R-%TT%%CC%S02301" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S024_R-%TT%%CC%S02401" />
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S025_R-%TT%%CC%S02501" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- CO2 -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%024_R-%TT%%CC%02401">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S026_R-%TT%%CC%S02601" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Helligkeit -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%025_R-%TT%%CC%02501">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S027_R-%TT%%CC%S02701" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
<!-- Szene -->
|
||||||
|
<choose ParamRefId="%AID%_UP-%TT%%CC%026_R-%TT%%CC%02601">
|
||||||
|
<when test="1">
|
||||||
|
<ComObjectRefRef RefId="%AID%_O-%TT%%CC%S028_R-%TT%%CC%S02801" />
|
||||||
|
</when>
|
||||||
|
</choose>
|
||||||
|
|
||||||
|
<!-- Funktionen -->
|
||||||
<ParameterSeparator Id="%AID%_PS-nnn" Text="Funktionen"
|
<ParameterSeparator Id="%AID%_PS-nnn" Text="Funktionen"
|
||||||
UIHint="Headline" />
|
UIHint="Headline" />
|
||||||
<ParameterRefRef
|
<ParameterRefRef
|
||||||
@ -73,55 +588,55 @@
|
|||||||
xpath="//Dynamic/ChannelIndependentBlock/*" instance="1" />
|
xpath="//Dynamic/ChannelIndependentBlock/*" instance="1" />
|
||||||
<choose ParamRefId="%AID%_UP-%TT%%CC%005_R-%TT%%CC%00501">
|
<choose ParamRefId="%AID%_UP-%TT%%CC%005_R-%TT%%CC%00501">
|
||||||
<!-- FN 2 -->
|
<!-- FN 2 -->
|
||||||
<when test=">0">
|
<when test=">1">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="2" />
|
instance="2" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 3 -->
|
<!-- FN 3 -->
|
||||||
<when test=">1">
|
<when test=">2">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="3" />
|
instance="3" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 4 -->
|
<!-- FN 4 -->
|
||||||
<when test=">2">
|
<when test=">3">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="4" />
|
instance="4" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 5 -->
|
<!-- FN 5 -->
|
||||||
<when test=">3">
|
<when test=">4">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="5" />
|
instance="5" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 6 -->
|
<!-- FN 6 -->
|
||||||
<when test=">4">
|
<when test=">5">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="6" />
|
instance="6" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 7 -->
|
<!-- FN 7 -->
|
||||||
<when test=">5">
|
<when test=">6">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="7" />
|
instance="7" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 8 -->
|
<!-- FN 8 -->
|
||||||
<when test=">6">
|
<when test=">7">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="8" />
|
instance="8" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 9 -->
|
<!-- FN 9 -->
|
||||||
<when test=">7">
|
<when test=">8">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="9" />
|
instance="9" />
|
||||||
</when>
|
</when>
|
||||||
<!-- FN 10 -->
|
<!-- FN 10 -->
|
||||||
<when test=">8">
|
<when test=">9">
|
||||||
<op:usePart name="FN"
|
<op:usePart name="FN"
|
||||||
xpath="//Dynamic/ChannelIndependentBlock/*"
|
xpath="//Dynamic/ChannelIndependentBlock/*"
|
||||||
instance="10" />
|
instance="10" />
|
||||||
|
|||||||
@ -29,8 +29,8 @@
|
|||||||
<op:define prefix="SC"
|
<op:define prefix="SC"
|
||||||
share="Section.share.xml"
|
share="Section.share.xml"
|
||||||
template="Section.templ.xml"
|
template="Section.templ.xml"
|
||||||
NumChannels="1"
|
NumChannels="25"
|
||||||
KoOffset="20"
|
KoOffset="10"
|
||||||
ModuleType="10" >
|
ModuleType="10" >
|
||||||
<!--<op:verify File="../lib/OFM-LogicModule/library.json" ModuleVersion="%LOG_VerifyVersion%" /> -->
|
<!--<op:verify File="../lib/OFM-LogicModule/library.json" ModuleVersion="%LOG_VerifyVersion%" /> -->
|
||||||
</op:define>
|
</op:define>
|
||||||
|
|||||||
@ -321,6 +321,7 @@ bool KnxWorker::getGroupObjectInfo(size_t index, KnxGroupObjectInfo& info) {
|
|||||||
info.commFlag = go.commFlag();
|
info.commFlag = go.commFlag();
|
||||||
info.readFlag = go.readEnable();
|
info.readFlag = go.readEnable();
|
||||||
info.writeFlag = go.writeEnable();
|
info.writeFlag = go.writeEnable();
|
||||||
|
info.transmitFlag = go.transmitEnable();
|
||||||
|
|
||||||
// Resolve the primary group address via association/address tables
|
// Resolve the primary group address via association/address tables
|
||||||
info.groupAddress = resolveGroupAddress(static_cast<uint16_t>(index));
|
info.groupAddress = resolveGroupAddress(static_cast<uint16_t>(index));
|
||||||
@ -333,6 +334,47 @@ bool KnxWorker::getGroupObjectInfo(size_t index, KnxGroupObjectInfo& info) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool KnxWorker::sendSwitch(uint16_t groupAddr, bool value) {
|
||||||
|
#if !UART_DEBUG_MODE
|
||||||
|
if (!knxBau.configured()) {
|
||||||
|
ESP_LOGW(TAG, "sendSwitch: KNX not configured");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the GroupObject index for this group address
|
||||||
|
size_t goCount = getGroupObjectCount();
|
||||||
|
for (size_t i = 1; i <= goCount; i++) {
|
||||||
|
uint16_t addr = resolveGroupAddress(static_cast<uint16_t>(i));
|
||||||
|
if (addr == groupAddr) {
|
||||||
|
GroupObject& go = knx.getGroupObject(i);
|
||||||
|
|
||||||
|
// Check if this GO can transmit
|
||||||
|
if (!go.transmitEnable()) {
|
||||||
|
ESP_LOGW(TAG, "sendSwitch: GO %d cannot transmit", (int)i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set value and trigger send
|
||||||
|
KNXValue knxVal = value;
|
||||||
|
if (go.value(knxVal, DPT_Switch)) {
|
||||||
|
ESP_LOGI(TAG, "sendSwitch: GA=%d GO=%d value=%d", groupAddr, (int)i, value);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
ESP_LOGW(TAG, "sendSwitch: Failed to set value for GO %d", (int)i);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ESP_LOGW(TAG, "sendSwitch: No GO found for GA=%d", groupAddr);
|
||||||
|
return false;
|
||||||
|
#else
|
||||||
|
(void)groupAddr;
|
||||||
|
(void)value;
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void KnxWorker::formatGroupAddress(uint16_t addr, char* buf, size_t bufSize) {
|
void KnxWorker::formatGroupAddress(uint16_t addr, char* buf, size_t bufSize) {
|
||||||
// Format: main/middle/sub (5/3/8 bit)
|
// Format: main/middle/sub (5/3/8 bit)
|
||||||
uint8_t main = (addr >> 11) & 0x1F;
|
uint8_t main = (addr >> 11) & 0x1F;
|
||||||
|
|||||||
@ -11,7 +11,8 @@ struct KnxGroupObjectInfo {
|
|||||||
uint8_t dptSub; // DPT Subtyp
|
uint8_t dptSub; // DPT Subtyp
|
||||||
bool commFlag; // Kommunikations-Flag
|
bool commFlag; // Kommunikations-Flag
|
||||||
bool readFlag; // Lese-Flag
|
bool readFlag; // Lese-Flag
|
||||||
bool writeFlag; // Schreib-Flag
|
bool writeFlag; // Schreib-Flag (empfangen vom Bus)
|
||||||
|
bool transmitFlag; // Sende-Flag (senden auf den Bus)
|
||||||
};
|
};
|
||||||
|
|
||||||
class KnxWorker {
|
class KnxWorker {
|
||||||
@ -28,6 +29,9 @@ public:
|
|||||||
size_t getGroupObjectCount();
|
size_t getGroupObjectCount();
|
||||||
bool getGroupObjectInfo(size_t index, KnxGroupObjectInfo& info);
|
bool getGroupObjectInfo(size_t index, KnxGroupObjectInfo& info);
|
||||||
|
|
||||||
|
// KNX Telegramm senden
|
||||||
|
bool sendSwitch(uint16_t groupAddr, bool value);
|
||||||
|
|
||||||
// Gruppenadresse als String formatieren (z.B. "1/2/3")
|
// Gruppenadresse als String formatieren (z.B. "1/2/3")
|
||||||
static void formatGroupAddress(uint16_t addr, char* buf, size_t bufSize);
|
static void formatGroupAddress(uint16_t addr, char* buf, size_t bufSize);
|
||||||
|
|
||||||
|
|||||||
@ -119,20 +119,30 @@ void WidgetConfig::serialize(uint8_t* buf) const {
|
|||||||
buf[pos++] = cardStyle;
|
buf[pos++] = cardStyle;
|
||||||
for (size_t i = 0; i < MAX_SUBBUTTONS; ++i) {
|
for (size_t i = 0; i < MAX_SUBBUTTONS; ++i) {
|
||||||
const SubButtonConfig& sb = subButtons[i];
|
const SubButtonConfig& sb = subButtons[i];
|
||||||
buf[pos++] = sb.iconCodepoint & 0xFF;
|
buf[pos++] = sb.iconCodepointOff & 0xFF;
|
||||||
buf[pos++] = (sb.iconCodepoint >> 8) & 0xFF;
|
buf[pos++] = (sb.iconCodepointOff >> 8) & 0xFF;
|
||||||
buf[pos++] = (sb.iconCodepoint >> 16) & 0xFF;
|
buf[pos++] = (sb.iconCodepointOff >> 16) & 0xFF;
|
||||||
buf[pos++] = (sb.iconCodepoint >> 24) & 0xFF;
|
buf[pos++] = (sb.iconCodepointOff >> 24) & 0xFF;
|
||||||
|
buf[pos++] = sb.iconCodepointOn & 0xFF;
|
||||||
|
buf[pos++] = (sb.iconCodepointOn >> 8) & 0xFF;
|
||||||
|
buf[pos++] = (sb.iconCodepointOn >> 16) & 0xFF;
|
||||||
|
buf[pos++] = (sb.iconCodepointOn >> 24) & 0xFF;
|
||||||
buf[pos++] = sb.knxAddrRead & 0xFF;
|
buf[pos++] = sb.knxAddrRead & 0xFF;
|
||||||
buf[pos++] = (sb.knxAddrRead >> 8) & 0xFF;
|
buf[pos++] = (sb.knxAddrRead >> 8) & 0xFF;
|
||||||
buf[pos++] = sb.knxAddrWrite & 0xFF;
|
buf[pos++] = sb.knxAddrWrite & 0xFF;
|
||||||
buf[pos++] = (sb.knxAddrWrite >> 8) & 0xFF;
|
buf[pos++] = (sb.knxAddrWrite >> 8) & 0xFF;
|
||||||
buf[pos++] = sb.colorOn.r;
|
buf[pos++] = sb.bgColorOn.r;
|
||||||
buf[pos++] = sb.colorOn.g;
|
buf[pos++] = sb.bgColorOn.g;
|
||||||
buf[pos++] = sb.colorOn.b;
|
buf[pos++] = sb.bgColorOn.b;
|
||||||
buf[pos++] = sb.colorOff.r;
|
buf[pos++] = sb.bgColorOff.r;
|
||||||
buf[pos++] = sb.colorOff.g;
|
buf[pos++] = sb.bgColorOff.g;
|
||||||
buf[pos++] = sb.colorOff.b;
|
buf[pos++] = sb.bgColorOff.b;
|
||||||
|
buf[pos++] = sb.iconColorOn.r;
|
||||||
|
buf[pos++] = sb.iconColorOn.g;
|
||||||
|
buf[pos++] = sb.iconColorOn.b;
|
||||||
|
buf[pos++] = sb.iconColorOff.r;
|
||||||
|
buf[pos++] = sb.iconColorOff.g;
|
||||||
|
buf[pos++] = sb.iconColorOff.b;
|
||||||
buf[pos++] = static_cast<uint8_t>(sb.position);
|
buf[pos++] = static_cast<uint8_t>(sb.position);
|
||||||
buf[pos++] = static_cast<uint8_t>(sb.action);
|
buf[pos++] = static_cast<uint8_t>(sb.action);
|
||||||
buf[pos++] = sb.targetScreen;
|
buf[pos++] = sb.targetScreen;
|
||||||
@ -303,18 +313,27 @@ void WidgetConfig::deserialize(const uint8_t* buf) {
|
|||||||
|
|
||||||
for (size_t i = 0; i < MAX_SUBBUTTONS; ++i) {
|
for (size_t i = 0; i < MAX_SUBBUTTONS; ++i) {
|
||||||
SubButtonConfig& sb = subButtons[i];
|
SubButtonConfig& sb = subButtons[i];
|
||||||
if (pos + 20 <= SERIALIZED_SIZE) {
|
if (pos + 30 <= SERIALIZED_SIZE) {
|
||||||
sb.iconCodepoint = buf[pos] | (buf[pos + 1] << 8) |
|
sb.iconCodepointOff = buf[pos] | (buf[pos + 1] << 8) |
|
||||||
(buf[pos + 2] << 16) | (buf[pos + 3] << 24);
|
(buf[pos + 2] << 16) | (buf[pos + 3] << 24);
|
||||||
|
pos += 4;
|
||||||
|
sb.iconCodepointOn = buf[pos] | (buf[pos + 1] << 8) |
|
||||||
|
(buf[pos + 2] << 16) | (buf[pos + 3] << 24);
|
||||||
pos += 4;
|
pos += 4;
|
||||||
sb.knxAddrRead = buf[pos] | (buf[pos + 1] << 8); pos += 2;
|
sb.knxAddrRead = buf[pos] | (buf[pos + 1] << 8); pos += 2;
|
||||||
sb.knxAddrWrite = buf[pos] | (buf[pos + 1] << 8); pos += 2;
|
sb.knxAddrWrite = buf[pos] | (buf[pos + 1] << 8); pos += 2;
|
||||||
sb.colorOn.r = buf[pos++];
|
sb.bgColorOn.r = buf[pos++];
|
||||||
sb.colorOn.g = buf[pos++];
|
sb.bgColorOn.g = buf[pos++];
|
||||||
sb.colorOn.b = buf[pos++];
|
sb.bgColorOn.b = buf[pos++];
|
||||||
sb.colorOff.r = buf[pos++];
|
sb.bgColorOff.r = buf[pos++];
|
||||||
sb.colorOff.g = buf[pos++];
|
sb.bgColorOff.g = buf[pos++];
|
||||||
sb.colorOff.b = buf[pos++];
|
sb.bgColorOff.b = buf[pos++];
|
||||||
|
sb.iconColorOn.r = buf[pos++];
|
||||||
|
sb.iconColorOn.g = buf[pos++];
|
||||||
|
sb.iconColorOn.b = buf[pos++];
|
||||||
|
sb.iconColorOff.r = buf[pos++];
|
||||||
|
sb.iconColorOff.g = buf[pos++];
|
||||||
|
sb.iconColorOff.b = buf[pos++];
|
||||||
sb.position = static_cast<SubButtonPosition>(buf[pos++]);
|
sb.position = static_cast<SubButtonPosition>(buf[pos++]);
|
||||||
sb.action = static_cast<SubButtonAction>(buf[pos++]);
|
sb.action = static_cast<SubButtonAction>(buf[pos++]);
|
||||||
sb.targetScreen = buf[pos++];
|
sb.targetScreen = buf[pos++];
|
||||||
@ -559,6 +578,8 @@ void GuiConfig::clear() {
|
|||||||
knxDateAddress = 0;
|
knxDateAddress = 0;
|
||||||
knxDateTimeAddress = 0;
|
knxDateTimeAddress = 0;
|
||||||
knxNightModeAddress = 0;
|
knxNightModeAddress = 0;
|
||||||
|
screenAnimType = ScreenAnimType::FADE;
|
||||||
|
screenAnimDuration = 300; // Default 300ms
|
||||||
for (size_t i = 0; i < MAX_SCREENS; i++) {
|
for (size_t i = 0; i < MAX_SCREENS; i++) {
|
||||||
screens[i].clear(static_cast<uint8_t>(i), nullptr);
|
screens[i].clear(static_cast<uint8_t>(i), nullptr);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -169,19 +169,22 @@ enum class SubButtonAction : uint8_t {
|
|||||||
NAVIGATE = 1, // Navigate to screen
|
NAVIGATE = 1, // Navigate to screen
|
||||||
};
|
};
|
||||||
|
|
||||||
// Sub-button configuration for RoomCard (20 bytes)
|
// Sub-button configuration for RoomCard (30 bytes)
|
||||||
struct SubButtonConfig {
|
struct SubButtonConfig {
|
||||||
uint32_t iconCodepoint; // 4 bytes - Icon codepoint
|
uint32_t iconCodepointOff; // 4 bytes - Icon codepoint when OFF
|
||||||
|
uint32_t iconCodepointOn; // 4 bytes - Icon codepoint when ON (0 = use iconCodepointOff)
|
||||||
uint16_t knxAddrRead; // 2 bytes - KNX address to read status
|
uint16_t knxAddrRead; // 2 bytes - KNX address to read status
|
||||||
uint16_t knxAddrWrite; // 2 bytes - KNX address to write on click
|
uint16_t knxAddrWrite; // 2 bytes - KNX address to write on click
|
||||||
Color colorOn; // 3 bytes - Color when ON
|
Color bgColorOn; // 3 bytes - Background color when ON
|
||||||
Color colorOff; // 3 bytes - Color when OFF
|
Color bgColorOff; // 3 bytes - Background color when OFF
|
||||||
|
Color iconColorOn; // 3 bytes - Icon color when ON
|
||||||
|
Color iconColorOff; // 3 bytes - Icon color when OFF
|
||||||
SubButtonPosition position; // 1 byte - Position around bubble
|
SubButtonPosition position; // 1 byte - Position around bubble
|
||||||
SubButtonAction action; // 1 byte - Action type
|
SubButtonAction action; // 1 byte - Action type
|
||||||
uint8_t targetScreen; // 1 byte - Target screen for navigate
|
uint8_t targetScreen; // 1 byte - Target screen for navigate
|
||||||
bool enabled; // 1 byte - Is this sub-button active?
|
bool enabled; // 1 byte - Is this sub-button active?
|
||||||
uint8_t _padding[2]; // 2 bytes - Alignment padding
|
uint8_t _padding[2]; // 2 bytes - Alignment padding
|
||||||
// Total: 20 bytes per SubButton
|
// Total: 30 bytes per SubButton
|
||||||
};
|
};
|
||||||
|
|
||||||
// Text line configuration for RoomCard (24 bytes)
|
// Text line configuration for RoomCard (24 bytes)
|
||||||
@ -296,8 +299,8 @@ struct WidgetConfig {
|
|||||||
uint8_t arcValueFontSize; // Center value font size index
|
uint8_t arcValueFontSize; // Center value font size index
|
||||||
|
|
||||||
// Serialization size (fixed for NVS storage)
|
// Serialization size (fixed for NVS storage)
|
||||||
// 331 + 14 (arcMin + arcMax + arcUnit + arcShowValue + arcScaleOffset + arcScaleColor + arcValueColor + arcValueFontSize) = 345
|
// 369 + 36 (6 subbuttons * 6 bytes for icon colors) = 405
|
||||||
static constexpr size_t SERIALIZED_SIZE = 345;
|
static constexpr size_t SERIALIZED_SIZE = 405;
|
||||||
|
|
||||||
void serialize(uint8_t* buf) const;
|
void serialize(uint8_t* buf) const;
|
||||||
void deserialize(const uint8_t* buf);
|
void deserialize(const uint8_t* buf);
|
||||||
@ -340,6 +343,20 @@ struct ScreenConfig {
|
|||||||
const WidgetConfig* findWidget(uint8_t id) const;
|
const WidgetConfig* findWidget(uint8_t id) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Screen transition animation types
|
||||||
|
enum class ScreenAnimType : uint8_t {
|
||||||
|
NONE = 0,
|
||||||
|
FADE = 1,
|
||||||
|
SLIDE_LEFT = 2,
|
||||||
|
SLIDE_RIGHT = 3,
|
||||||
|
SLIDE_UP = 4,
|
||||||
|
SLIDE_DOWN = 5,
|
||||||
|
OVER_LEFT = 6,
|
||||||
|
OVER_RIGHT = 7,
|
||||||
|
OVER_UP = 8,
|
||||||
|
OVER_DOWN = 9,
|
||||||
|
};
|
||||||
|
|
||||||
struct GuiConfig {
|
struct GuiConfig {
|
||||||
uint8_t screenCount;
|
uint8_t screenCount;
|
||||||
ScreenConfig screens[MAX_SCREENS];
|
ScreenConfig screens[MAX_SCREENS];
|
||||||
@ -352,6 +369,10 @@ struct GuiConfig {
|
|||||||
uint16_t knxDateTimeAddress;
|
uint16_t knxDateTimeAddress;
|
||||||
uint16_t knxNightModeAddress;
|
uint16_t knxNightModeAddress;
|
||||||
|
|
||||||
|
// Screen transition animation
|
||||||
|
ScreenAnimType screenAnimType;
|
||||||
|
uint16_t screenAnimDuration; // Duration in ms (0 = default 300ms)
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
ScreenConfig* findScreen(uint8_t id);
|
ScreenConfig* findScreen(uint8_t id);
|
||||||
const ScreenConfig* findScreen(uint8_t id) const;
|
const ScreenConfig* findScreen(uint8_t id) const;
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include "widgets/RoomCardTileWidget.hpp"
|
#include "widgets/RoomCardTileWidget.hpp"
|
||||||
#include "HistoryStore.hpp"
|
#include "HistoryStore.hpp"
|
||||||
#include "SdCard.hpp"
|
#include "SdCard.hpp"
|
||||||
|
#include "Gui.hpp"
|
||||||
#include "esp_lv_adapter.h"
|
#include "esp_lv_adapter.h"
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "esp_timer.h"
|
#include "esp_timer.h"
|
||||||
@ -358,6 +359,23 @@ void WidgetManager::applyScreen(uint8_t screenId) {
|
|||||||
esp_lv_adapter_unlock();
|
esp_lv_adapter_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to convert ScreenAnimType to LVGL animation type (LVGL 9.x API)
|
||||||
|
static lv_screen_load_anim_t screenAnimToLvgl(ScreenAnimType type) {
|
||||||
|
switch (type) {
|
||||||
|
case ScreenAnimType::NONE: return LV_SCREEN_LOAD_ANIM_NONE;
|
||||||
|
case ScreenAnimType::FADE: return LV_SCREEN_LOAD_ANIM_FADE_IN;
|
||||||
|
case ScreenAnimType::SLIDE_LEFT: return LV_SCREEN_LOAD_ANIM_MOVE_LEFT;
|
||||||
|
case ScreenAnimType::SLIDE_RIGHT: return LV_SCREEN_LOAD_ANIM_MOVE_RIGHT;
|
||||||
|
case ScreenAnimType::SLIDE_UP: return LV_SCREEN_LOAD_ANIM_MOVE_TOP;
|
||||||
|
case ScreenAnimType::SLIDE_DOWN: return LV_SCREEN_LOAD_ANIM_MOVE_BOTTOM;
|
||||||
|
case ScreenAnimType::OVER_LEFT: return LV_SCREEN_LOAD_ANIM_OVER_LEFT;
|
||||||
|
case ScreenAnimType::OVER_RIGHT: return LV_SCREEN_LOAD_ANIM_OVER_RIGHT;
|
||||||
|
case ScreenAnimType::OVER_UP: return LV_SCREEN_LOAD_ANIM_OVER_TOP;
|
||||||
|
case ScreenAnimType::OVER_DOWN: return LV_SCREEN_LOAD_ANIM_OVER_BOTTOM;
|
||||||
|
default: return LV_SCREEN_LOAD_ANIM_FADE_IN;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void WidgetManager::applyScreenLocked(uint8_t screenId) {
|
void WidgetManager::applyScreenLocked(uint8_t screenId) {
|
||||||
ESP_LOGI(TAG, "applyScreen(%d) - start", screenId);
|
ESP_LOGI(TAG, "applyScreen(%d) - start", screenId);
|
||||||
|
|
||||||
@ -374,35 +392,40 @@ void WidgetManager::applyScreenLocked(uint8_t screenId) {
|
|||||||
closeModalLocked();
|
closeModalLocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
lv_display_t* disp = lv_display_get_default();
|
// SAFE DESTRUCTION of C++ widgets:
|
||||||
if (disp) {
|
|
||||||
lv_display_enable_invalidation(disp, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// SAFE DESTRUCTION:
|
|
||||||
// 1. Mark all C++ widgets as "LVGL object already gone"
|
// 1. Mark all C++ widgets as "LVGL object already gone"
|
||||||
for (auto& widget : widgets_) {
|
for (auto& widget : widgets_) {
|
||||||
if (widget) widget->clearLvglObject();
|
if (widget) widget->clearLvglObject();
|
||||||
}
|
}
|
||||||
|
// 2. Clean layer_top (sub-buttons etc)
|
||||||
// 2. Delete all LVGL objects on layers we use
|
|
||||||
lv_obj_clean(lv_scr_act());
|
|
||||||
lv_obj_clean(lv_layer_top());
|
lv_obj_clean(lv_layer_top());
|
||||||
|
// 3. Destroy C++ objects (their destructors won't call lv_obj_delete)
|
||||||
// 3. Now destroy C++ objects (their destructors won't call lv_obj_delete)
|
|
||||||
destroyAllWidgets();
|
destroyAllWidgets();
|
||||||
|
|
||||||
|
// Create a NEW screen object for the transition
|
||||||
|
lv_obj_t* newScreen = lv_obj_create(NULL);
|
||||||
|
lv_obj_remove_style_all(newScreen);
|
||||||
|
lv_obj_set_size(newScreen, LV_PCT(100), LV_PCT(100));
|
||||||
|
lv_obj_clear_flag(newScreen, LV_OBJ_FLAG_SCROLLABLE);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "Creating new widgets for screen '%s' (%d widgets)...",
|
ESP_LOGI(TAG, "Creating new widgets for screen '%s' (%d widgets)...",
|
||||||
screen->name, screen->widgetCount);
|
screen->name, screen->widgetCount);
|
||||||
lv_obj_t* root = lv_scr_act();
|
createAllWidgets(*screen, newScreen);
|
||||||
createAllWidgets(*screen, root);
|
|
||||||
ESP_LOGI(TAG, "Widgets created");
|
ESP_LOGI(TAG, "Widgets created");
|
||||||
applyCachedValuesToWidgets();
|
applyCachedValuesToWidgets();
|
||||||
|
|
||||||
if (disp) {
|
// Get animation settings
|
||||||
lv_display_enable_invalidation(disp, true);
|
ESP_LOGI(TAG, "Animation config: type=%d, duration=%u",
|
||||||
}
|
(int)config_->screenAnimType, config_->screenAnimDuration);
|
||||||
lv_obj_invalidate(lv_scr_act());
|
lv_screen_load_anim_t animType = screenAnimToLvgl(config_->screenAnimType);
|
||||||
|
uint32_t animDuration = config_->screenAnimDuration > 0 ? config_->screenAnimDuration : 300;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Loading screen with animation: lvgl_type=%d, duration=%lums",
|
||||||
|
(int)animType, (unsigned long)animDuration);
|
||||||
|
|
||||||
|
// Load the new screen with animation (old screen auto-deleted after animation)
|
||||||
|
// Parameters: new_scr, anim_type, time_ms, delay_ms, auto_del_old_scr
|
||||||
|
lv_screen_load_anim(newScreen, animType, animDuration, 0, true);
|
||||||
|
|
||||||
ESP_LOGI(TAG, "applyScreen(%d) - complete", screenId);
|
ESP_LOGI(TAG, "applyScreen(%d) - complete", screenId);
|
||||||
}
|
}
|
||||||
@ -604,13 +627,31 @@ void WidgetManager::handleButtonAction(const WidgetConfig& cfg, lv_obj_t* target
|
|||||||
case ButtonAction::KNX:
|
case ButtonAction::KNX:
|
||||||
default: {
|
default: {
|
||||||
if (cfg.knxAddressWrite > 0) {
|
if (cfg.knxAddressWrite > 0) {
|
||||||
bool state = false;
|
bool currentState = false;
|
||||||
if (target) {
|
if (target) {
|
||||||
state = (lv_obj_get_state(target) & LV_STATE_CHECKED) != 0;
|
currentState = (lv_obj_get_state(target) & LV_STATE_CHECKED) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For toggle buttons: send the opposite of current state
|
||||||
|
// For non-toggle buttons: send ON (true)
|
||||||
|
bool sendValue = cfg.isToggle ? !currentState : true;
|
||||||
|
|
||||||
|
ESP_LOGI(TAG, "Button %d clicked, KNX write to %d, value=%d (toggle=%d, currentState=%d)",
|
||||||
|
cfg.id, cfg.knxAddressWrite, sendValue, cfg.isToggle, currentState);
|
||||||
|
|
||||||
|
// Send KNX telegram
|
||||||
|
if (Gui::knxWorker.sendSwitch(cfg.knxAddressWrite, sendValue)) {
|
||||||
|
// Update local UI state immediately for responsive feedback
|
||||||
|
if (cfg.isToggle && target) {
|
||||||
|
if (sendValue) {
|
||||||
|
lv_obj_add_state(target, LV_STATE_CHECKED);
|
||||||
|
} else {
|
||||||
|
lv_obj_clear_state(target, LV_STATE_CHECKED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Also update the cache
|
||||||
|
cacheKnxSwitch(cfg.knxAddressWrite, sendValue);
|
||||||
}
|
}
|
||||||
ESP_LOGI(TAG, "Button %d clicked, KNX write to %d, state=%d",
|
|
||||||
cfg.id, cfg.knxAddressWrite, state);
|
|
||||||
// TODO: Send KNX telegram
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -680,9 +721,12 @@ void WidgetManager::navigateBack() {
|
|||||||
|
|
||||||
void WidgetManager::sendKnxSwitch(uint16_t groupAddr, bool value) {
|
void WidgetManager::sendKnxSwitch(uint16_t groupAddr, bool value) {
|
||||||
ESP_LOGI(TAG, "sendKnxSwitch: GA=%d, value=%d", groupAddr, value);
|
ESP_LOGI(TAG, "sendKnxSwitch: GA=%d, value=%d", groupAddr, value);
|
||||||
// TODO: Send actual KNX telegram via KnxWorker
|
|
||||||
// For now, just log and update cache so UI reflects the change
|
// Send actual KNX telegram via KnxWorker
|
||||||
cacheKnxSwitch(groupAddr, value);
|
if (Gui::knxWorker.sendSwitch(groupAddr, value)) {
|
||||||
|
// Update cache so UI reflects the change
|
||||||
|
cacheKnxSwitch(groupAddr, value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WidgetManager::enterStandby() {
|
void WidgetManager::enterStandby() {
|
||||||
@ -1481,6 +1525,11 @@ void WidgetManager::getConfigJson(char* buf, size_t bufSize) const {
|
|||||||
cJSON_AddNumberToObject(knx, "dateTime", config_->knxDateTimeAddress);
|
cJSON_AddNumberToObject(knx, "dateTime", config_->knxDateTimeAddress);
|
||||||
cJSON_AddNumberToObject(knx, "night", config_->knxNightModeAddress);
|
cJSON_AddNumberToObject(knx, "night", config_->knxNightModeAddress);
|
||||||
|
|
||||||
|
// Screen transition animation
|
||||||
|
cJSON* anim = cJSON_AddObjectToObject(root, "screenAnim");
|
||||||
|
cJSON_AddNumberToObject(anim, "type", static_cast<int>(config_->screenAnimType));
|
||||||
|
cJSON_AddNumberToObject(anim, "duration", config_->screenAnimDuration);
|
||||||
|
|
||||||
cJSON* screens = cJSON_AddArrayToObject(root, "screens");
|
cJSON* screens = cJSON_AddArrayToObject(root, "screens");
|
||||||
|
|
||||||
for (uint8_t s = 0; s < config_->screenCount; s++) {
|
for (uint8_t s = 0; s < config_->screenCount; s++) {
|
||||||
@ -1693,19 +1742,26 @@ void WidgetManager::getConfigJson(char* buf, size_t bufSize) const {
|
|||||||
|
|
||||||
cJSON* sbJson = cJSON_CreateObject();
|
cJSON* sbJson = cJSON_CreateObject();
|
||||||
cJSON_AddNumberToObject(sbJson, "pos", static_cast<int>(sb.position));
|
cJSON_AddNumberToObject(sbJson, "pos", static_cast<int>(sb.position));
|
||||||
cJSON_AddNumberToObject(sbJson, "icon", sb.iconCodepoint);
|
cJSON_AddNumberToObject(sbJson, "iconOff", sb.iconCodepointOff);
|
||||||
|
cJSON_AddNumberToObject(sbJson, "iconOn", sb.iconCodepointOn);
|
||||||
cJSON_AddNumberToObject(sbJson, "knxRead", sb.knxAddrRead);
|
cJSON_AddNumberToObject(sbJson, "knxRead", sb.knxAddrRead);
|
||||||
cJSON_AddNumberToObject(sbJson, "knxWrite", sb.knxAddrWrite);
|
cJSON_AddNumberToObject(sbJson, "knxWrite", sb.knxAddrWrite);
|
||||||
cJSON_AddNumberToObject(sbJson, "action", static_cast<int>(sb.action));
|
cJSON_AddNumberToObject(sbJson, "action", static_cast<int>(sb.action));
|
||||||
cJSON_AddNumberToObject(sbJson, "target", sb.targetScreen);
|
cJSON_AddNumberToObject(sbJson, "target", sb.targetScreen);
|
||||||
|
|
||||||
char colorOnStr[8], colorOffStr[8];
|
char bgColorOnStr[8], bgColorOffStr[8], iconColorOnStr[8], iconColorOffStr[8];
|
||||||
snprintf(colorOnStr, sizeof(colorOnStr), "#%02X%02X%02X",
|
snprintf(bgColorOnStr, sizeof(bgColorOnStr), "#%02X%02X%02X",
|
||||||
sb.colorOn.r, sb.colorOn.g, sb.colorOn.b);
|
sb.bgColorOn.r, sb.bgColorOn.g, sb.bgColorOn.b);
|
||||||
snprintf(colorOffStr, sizeof(colorOffStr), "#%02X%02X%02X",
|
snprintf(bgColorOffStr, sizeof(bgColorOffStr), "#%02X%02X%02X",
|
||||||
sb.colorOff.r, sb.colorOff.g, sb.colorOff.b);
|
sb.bgColorOff.r, sb.bgColorOff.g, sb.bgColorOff.b);
|
||||||
cJSON_AddStringToObject(sbJson, "colorOn", colorOnStr);
|
snprintf(iconColorOnStr, sizeof(iconColorOnStr), "#%02X%02X%02X",
|
||||||
cJSON_AddStringToObject(sbJson, "colorOff", colorOffStr);
|
sb.iconColorOn.r, sb.iconColorOn.g, sb.iconColorOn.b);
|
||||||
|
snprintf(iconColorOffStr, sizeof(iconColorOffStr), "#%02X%02X%02X",
|
||||||
|
sb.iconColorOff.r, sb.iconColorOff.g, sb.iconColorOff.b);
|
||||||
|
cJSON_AddStringToObject(sbJson, "bgColorOn", bgColorOnStr);
|
||||||
|
cJSON_AddStringToObject(sbJson, "bgColorOff", bgColorOffStr);
|
||||||
|
cJSON_AddStringToObject(sbJson, "iconColorOn", iconColorOnStr);
|
||||||
|
cJSON_AddStringToObject(sbJson, "iconColorOff", iconColorOffStr);
|
||||||
|
|
||||||
cJSON_AddItemToArray(subButtons, sbJson);
|
cJSON_AddItemToArray(subButtons, sbJson);
|
||||||
}
|
}
|
||||||
@ -2035,9 +2091,10 @@ bool WidgetManager::updateConfigFromJson(const char* json) {
|
|||||||
cond.style.flags |= ConditionStyle::FLAG_USE_TEXT_COLOR;
|
cond.style.flags |= ConditionStyle::FLAG_USE_TEXT_COLOR;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Background color
|
// Background color (only if not empty and starts with #)
|
||||||
cJSON* bgColor = cJSON_GetObjectItem(condItem, "bgColor");
|
cJSON* bgColor = cJSON_GetObjectItem(condItem, "bgColor");
|
||||||
if (cJSON_IsString(bgColor)) {
|
if (cJSON_IsString(bgColor) && bgColor->valuestring &&
|
||||||
|
bgColor->valuestring[0] == '#' && strlen(bgColor->valuestring) >= 4) {
|
||||||
cond.style.bgColor = Color::fromHex(parseHexColor(bgColor->valuestring));
|
cond.style.bgColor = Color::fromHex(parseHexColor(bgColor->valuestring));
|
||||||
cond.style.flags |= ConditionStyle::FLAG_USE_BG_COLOR;
|
cond.style.flags |= ConditionStyle::FLAG_USE_BG_COLOR;
|
||||||
}
|
}
|
||||||
@ -2139,9 +2196,20 @@ bool WidgetManager::updateConfigFromJson(const char* json) {
|
|||||||
sb.position = static_cast<SubButtonPosition>(pos->valueint);
|
sb.position = static_cast<SubButtonPosition>(pos->valueint);
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* icon = cJSON_GetObjectItem(sbItem, "icon");
|
cJSON* iconOff = cJSON_GetObjectItem(sbItem, "iconOff");
|
||||||
if (cJSON_IsNumber(icon)) {
|
if (cJSON_IsNumber(iconOff)) {
|
||||||
sb.iconCodepoint = static_cast<uint32_t>(icon->valuedouble);
|
sb.iconCodepointOff = static_cast<uint32_t>(iconOff->valuedouble);
|
||||||
|
} else {
|
||||||
|
// Backward compatibility: try old "icon" field
|
||||||
|
cJSON* icon = cJSON_GetObjectItem(sbItem, "icon");
|
||||||
|
if (cJSON_IsNumber(icon)) {
|
||||||
|
sb.iconCodepointOff = static_cast<uint32_t>(icon->valuedouble);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* iconOn = cJSON_GetObjectItem(sbItem, "iconOn");
|
||||||
|
if (cJSON_IsNumber(iconOn)) {
|
||||||
|
sb.iconCodepointOn = static_cast<uint32_t>(iconOn->valuedouble);
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* knxRead = cJSON_GetObjectItem(sbItem, "knxRead");
|
cJSON* knxRead = cJSON_GetObjectItem(sbItem, "knxRead");
|
||||||
@ -2164,14 +2232,42 @@ bool WidgetManager::updateConfigFromJson(const char* json) {
|
|||||||
sb.targetScreen = target->valueint;
|
sb.targetScreen = target->valueint;
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* colorOn = cJSON_GetObjectItem(sbItem, "colorOn");
|
// Background colors
|
||||||
if (cJSON_IsString(colorOn)) {
|
cJSON* bgColorOn = cJSON_GetObjectItem(sbItem, "bgColorOn");
|
||||||
sb.colorOn = Color::fromHex(parseHexColor(colorOn->valuestring));
|
if (cJSON_IsString(bgColorOn)) {
|
||||||
|
sb.bgColorOn = Color::fromHex(parseHexColor(bgColorOn->valuestring));
|
||||||
|
} else {
|
||||||
|
// Backward compatibility: try old "colorOn" field
|
||||||
|
cJSON* colorOn = cJSON_GetObjectItem(sbItem, "colorOn");
|
||||||
|
if (cJSON_IsString(colorOn)) {
|
||||||
|
sb.bgColorOn = Color::fromHex(parseHexColor(colorOn->valuestring));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cJSON* colorOff = cJSON_GetObjectItem(sbItem, "colorOff");
|
cJSON* bgColorOff = cJSON_GetObjectItem(sbItem, "bgColorOff");
|
||||||
if (cJSON_IsString(colorOff)) {
|
if (cJSON_IsString(bgColorOff)) {
|
||||||
sb.colorOff = Color::fromHex(parseHexColor(colorOff->valuestring));
|
sb.bgColorOff = Color::fromHex(parseHexColor(bgColorOff->valuestring));
|
||||||
|
} else {
|
||||||
|
// Backward compatibility: try old "colorOff" field
|
||||||
|
cJSON* colorOff = cJSON_GetObjectItem(sbItem, "colorOff");
|
||||||
|
if (cJSON_IsString(colorOff)) {
|
||||||
|
sb.bgColorOff = Color::fromHex(parseHexColor(colorOff->valuestring));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Icon colors (default to white if not specified)
|
||||||
|
cJSON* iconColorOn = cJSON_GetObjectItem(sbItem, "iconColorOn");
|
||||||
|
if (cJSON_IsString(iconColorOn)) {
|
||||||
|
sb.iconColorOn = Color::fromHex(parseHexColor(iconColorOn->valuestring));
|
||||||
|
} else {
|
||||||
|
sb.iconColorOn = {255, 255, 255}; // Default white
|
||||||
|
}
|
||||||
|
|
||||||
|
cJSON* iconColorOff = cJSON_GetObjectItem(sbItem, "iconColorOff");
|
||||||
|
if (cJSON_IsString(iconColorOff)) {
|
||||||
|
sb.iconColorOff = Color::fromHex(parseHexColor(iconColorOff->valuestring));
|
||||||
|
} else {
|
||||||
|
sb.iconColorOff = {255, 255, 255}; // Default white
|
||||||
}
|
}
|
||||||
|
|
||||||
sbIdx++;
|
sbIdx++;
|
||||||
@ -2375,6 +2471,19 @@ bool WidgetManager::updateConfigFromJson(const char* json) {
|
|||||||
if (cJSON_IsNumber(nightAddr)) newConfig->knxNightModeAddress = nightAddr->valueint;
|
if (cJSON_IsNumber(nightAddr)) newConfig->knxNightModeAddress = nightAddr->valueint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Screen transition animation
|
||||||
|
cJSON* anim = cJSON_GetObjectItem(root, "screenAnim");
|
||||||
|
if (cJSON_IsObject(anim)) {
|
||||||
|
cJSON* animType = cJSON_GetObjectItem(anim, "type");
|
||||||
|
if (cJSON_IsNumber(animType)) {
|
||||||
|
newConfig->screenAnimType = static_cast<ScreenAnimType>(animType->valueint);
|
||||||
|
}
|
||||||
|
cJSON* animDuration = cJSON_GetObjectItem(anim, "duration");
|
||||||
|
if (cJSON_IsNumber(animDuration)) {
|
||||||
|
newConfig->screenAnimDuration = static_cast<uint16_t>(animDuration->valueint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (newConfig->screenCount == 0) {
|
if (newConfig->screenCount == 0) {
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@ -24,7 +24,7 @@ esp_err_t WebServer::getKnxAddressesHandler(httpd_req_t* req) {
|
|||||||
cJSON_AddStringToObject(obj, "addrStr", addrStr);
|
cJSON_AddStringToObject(obj, "addrStr", addrStr);
|
||||||
cJSON_AddBoolToObject(obj, "comm", info.commFlag);
|
cJSON_AddBoolToObject(obj, "comm", info.commFlag);
|
||||||
cJSON_AddBoolToObject(obj, "read", info.readFlag);
|
cJSON_AddBoolToObject(obj, "read", info.readFlag);
|
||||||
cJSON_AddBoolToObject(obj, "write", info.writeFlag);
|
cJSON_AddBoolToObject(obj, "write", info.transmitFlag); // transmit = kann auf Bus schreiben
|
||||||
cJSON_AddItemToArray(arr, obj);
|
cJSON_AddItemToArray(arr, obj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -235,7 +235,9 @@ void ButtonWidget::applyStyle() {
|
|||||||
lv_obj_set_style_text_color(iconLabel_, lv_color_make(
|
lv_obj_set_style_text_color(iconLabel_, lv_color_make(
|
||||||
config_.textColor.r, config_.textColor.g, config_.textColor.b), 0);
|
config_.textColor.r, config_.textColor.g, config_.textColor.b), 0);
|
||||||
|
|
||||||
uint8_t sizeIdx = config_.iconSize < 6 ? config_.iconSize : config_.fontSize;
|
// Icon fonts support sizes 0-13 (14px to 260px)
|
||||||
|
uint8_t sizeIdx = config_.iconSize;
|
||||||
|
if (sizeIdx > 13) sizeIdx = 13;
|
||||||
lv_obj_set_style_text_font(iconLabel_, Fonts::iconFont(sizeIdx), 0);
|
lv_obj_set_style_text_font(iconLabel_, Fonts::iconFont(sizeIdx), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -336,10 +338,16 @@ bool ButtonWidget::evaluateConditions(float primaryValue, float secondaryValue,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (bestMatch->style.flags & ConditionStyle::FLAG_USE_BG_COLOR) {
|
if (bestMatch->style.flags & ConditionStyle::FLAG_USE_BG_COLOR) {
|
||||||
lv_obj_set_style_bg_color(obj_, lv_color_make(
|
lv_color_t bgColor = lv_color_make(
|
||||||
bestMatch->style.bgColor.r,
|
bestMatch->style.bgColor.r,
|
||||||
bestMatch->style.bgColor.g,
|
bestMatch->style.bgColor.g,
|
||||||
bestMatch->style.bgColor.b), 0);
|
bestMatch->style.bgColor.b);
|
||||||
|
// Set for default state
|
||||||
|
lv_obj_set_style_bg_color(obj_, bgColor, LV_PART_MAIN | LV_STATE_DEFAULT);
|
||||||
|
// Also set for checked state (toggle buttons)
|
||||||
|
lv_obj_set_style_bg_color(obj_, bgColor, LV_PART_MAIN | LV_STATE_CHECKED);
|
||||||
|
// And for pressed state
|
||||||
|
lv_obj_set_style_bg_color(obj_, bgColor, LV_PART_MAIN | LV_STATE_PRESSED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bestMatch->style.flags & ConditionStyle::FLAG_USE_BG_OPACITY) {
|
if (bestMatch->style.flags & ConditionStyle::FLAG_USE_BG_OPACITY) {
|
||||||
@ -411,8 +419,45 @@ void ButtonWidget::applyFakeShadowStyle() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ButtonWidget::updateIcon(uint32_t codepoint) {
|
void ButtonWidget::updateIcon(uint32_t codepoint) {
|
||||||
if (!iconLabel_ || codepoint == 0) return;
|
if (codepoint == 0) return;
|
||||||
|
|
||||||
|
// If no icon label exists yet, we need to create it dynamically
|
||||||
|
if (!iconLabel_ && obj_ && Fonts::hasIconFont()) {
|
||||||
|
// For buttons without a content container, we need to create the icon label
|
||||||
|
if (!contentContainer_) {
|
||||||
|
// Create a simple icon label directly in the button
|
||||||
|
iconLabel_ = lv_label_create(obj_);
|
||||||
|
if (iconLabel_) {
|
||||||
|
lv_obj_clear_flag(iconLabel_, LV_OBJ_FLAG_CLICKABLE);
|
||||||
|
// Position it based on icon position setting
|
||||||
|
if (config_.iconPosition == static_cast<uint8_t>(IconPosition::LEFT)) {
|
||||||
|
lv_obj_align(iconLabel_, LV_ALIGN_LEFT_MID, config_.iconPositionX, 0);
|
||||||
|
} else if (config_.iconPosition == static_cast<uint8_t>(IconPosition::RIGHT)) {
|
||||||
|
lv_obj_align(iconLabel_, LV_ALIGN_RIGHT_MID, -config_.iconPositionX, 0);
|
||||||
|
} else {
|
||||||
|
lv_obj_align(iconLabel_, LV_ALIGN_CENTER, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!iconLabel_) return;
|
||||||
|
|
||||||
|
// Set the icon text
|
||||||
char iconText[5];
|
char iconText[5];
|
||||||
encodeUtf8(codepoint, iconText);
|
encodeUtf8(codepoint, iconText);
|
||||||
lv_label_set_text(iconLabel_, iconText);
|
lv_label_set_text(iconLabel_, iconText);
|
||||||
|
|
||||||
|
// Apply the correct font size
|
||||||
|
// If iconSize is 0 (no icon was originally configured), use fontSize instead
|
||||||
|
// Default to size 2 (22px) if both are 0
|
||||||
|
// Icon fonts support sizes 0-13 (14px to 260px)
|
||||||
|
uint8_t sizeIdx = config_.iconSize > 0 ? config_.iconSize : config_.fontSize;
|
||||||
|
if (sizeIdx == 0) sizeIdx = 2; // Default to medium size (22px)
|
||||||
|
if (sizeIdx > 13) sizeIdx = 13; // Cap at max icon font size
|
||||||
|
lv_obj_set_style_text_font(iconLabel_, Fonts::iconFont(sizeIdx), 0);
|
||||||
|
|
||||||
|
// Apply text color from config
|
||||||
|
lv_obj_set_style_text_color(iconLabel_, lv_color_make(
|
||||||
|
config_.textColor.r, config_.textColor.g, config_.textColor.b), 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,12 +115,13 @@ void RoomCardWidgetBase::createSubButtonsCommon() {
|
|||||||
int16_t absY = config_.y + relY;
|
int16_t absY = config_.y + relY;
|
||||||
lv_obj_set_pos(btn, absX, absY);
|
lv_obj_set_pos(btn, absX, absY);
|
||||||
|
|
||||||
// Create icon
|
// Create icon (use iconCodepointOff initially, will be updated based on state)
|
||||||
if (cfg.iconCodepoint > 0 && Fonts::hasIconFont()) {
|
uint32_t initialIcon = cfg.iconCodepointOff;
|
||||||
|
if (initialIcon > 0 && Fonts::hasIconFont()) {
|
||||||
lv_obj_t* icon = lv_label_create(btn);
|
lv_obj_t* icon = lv_label_create(btn);
|
||||||
lv_obj_clear_flag(icon, LV_OBJ_FLAG_CLICKABLE);
|
lv_obj_clear_flag(icon, LV_OBJ_FLAG_CLICKABLE);
|
||||||
char iconText[5];
|
char iconText[5];
|
||||||
encodeUtf8(cfg.iconCodepoint, iconText);
|
encodeUtf8(initialIcon, iconText);
|
||||||
lv_label_set_text(icon, iconText);
|
lv_label_set_text(icon, iconText);
|
||||||
lv_obj_center(icon);
|
lv_obj_center(icon);
|
||||||
subButtonIcons_[i] = icon;
|
subButtonIcons_[i] = icon;
|
||||||
@ -149,7 +150,10 @@ void RoomCardWidgetBase::applySubButtonStyle() {
|
|||||||
for (uint8_t i = 0; i < config_.subButtonCount && i < MAX_SUBBUTTONS; ++i) {
|
for (uint8_t i = 0; i < config_.subButtonCount && i < MAX_SUBBUTTONS; ++i) {
|
||||||
if (subButtonIcons_[i] && subBtnIconFont) {
|
if (subButtonIcons_[i] && subBtnIconFont) {
|
||||||
lv_obj_set_style_text_font(subButtonIcons_[i], subBtnIconFont, 0);
|
lv_obj_set_style_text_font(subButtonIcons_[i], subBtnIconFont, 0);
|
||||||
lv_obj_set_style_text_color(subButtonIcons_[i], lv_color_white(), 0);
|
// Set initial icon color based on state (OFF by default)
|
||||||
|
const Color& iconColor = subButtonStates_[i] ?
|
||||||
|
config_.subButtons[i].iconColorOn : config_.subButtons[i].iconColorOff;
|
||||||
|
lv_obj_set_style_text_color(subButtonIcons_[i], lv_color_hex(iconColor.toLvColor()), 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -158,9 +162,25 @@ void RoomCardWidgetBase::updateSubButtonColor(uint8_t index) {
|
|||||||
if (index >= MAX_SUBBUTTONS || !subButtonObjs_[index]) return;
|
if (index >= MAX_SUBBUTTONS || !subButtonObjs_[index]) return;
|
||||||
|
|
||||||
const SubButtonConfig& cfg = config_.subButtons[index];
|
const SubButtonConfig& cfg = config_.subButtons[index];
|
||||||
const Color& color = subButtonStates_[index] ? cfg.colorOn : cfg.colorOff;
|
bool isOn = subButtonStates_[index];
|
||||||
|
|
||||||
lv_obj_set_style_bg_color(subButtonObjs_[index], lv_color_hex(color.toLvColor()), 0);
|
// Update background color
|
||||||
|
const Color& bgColor = isOn ? cfg.bgColorOn : cfg.bgColorOff;
|
||||||
|
lv_obj_set_style_bg_color(subButtonObjs_[index], lv_color_hex(bgColor.toLvColor()), 0);
|
||||||
|
|
||||||
|
// Update icon and icon color based on state
|
||||||
|
if (subButtonIcons_[index]) {
|
||||||
|
uint32_t iconCodepoint = isOn && cfg.iconCodepointOn > 0 ? cfg.iconCodepointOn : cfg.iconCodepointOff;
|
||||||
|
if (iconCodepoint > 0) {
|
||||||
|
char iconText[5];
|
||||||
|
encodeUtf8(iconCodepoint, iconText);
|
||||||
|
lv_label_set_text(subButtonIcons_[index], iconText);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set icon color
|
||||||
|
const Color& iconColor = isOn ? cfg.iconColorOn : cfg.iconColorOff;
|
||||||
|
lv_obj_set_style_text_color(subButtonIcons_[index], lv_color_hex(iconColor.toLvColor()), 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RoomCardWidgetBase::updateTemperature(float value) {
|
void RoomCardWidgetBase::updateTemperature(float value) {
|
||||||
|
|||||||
15
sdkconfig
15
sdkconfig
@ -2845,8 +2845,8 @@ CONFIG_LV_COLOR_DEPTH=16
|
|||||||
#
|
#
|
||||||
# Memory Settings
|
# Memory Settings
|
||||||
#
|
#
|
||||||
CONFIG_LV_USE_BUILTIN_MALLOC=y
|
# CONFIG_LV_USE_BUILTIN_MALLOC is not set
|
||||||
# CONFIG_LV_USE_CLIB_MALLOC is not set
|
CONFIG_LV_USE_CLIB_MALLOC=y
|
||||||
# CONFIG_LV_USE_MICROPYTHON_MALLOC is not set
|
# CONFIG_LV_USE_MICROPYTHON_MALLOC is not set
|
||||||
# CONFIG_LV_USE_RTTHREAD_MALLOC is not set
|
# CONFIG_LV_USE_RTTHREAD_MALLOC is not set
|
||||||
# CONFIG_LV_USE_CUSTOM_MALLOC is not set
|
# CONFIG_LV_USE_CUSTOM_MALLOC is not set
|
||||||
@ -2856,15 +2856,12 @@ CONFIG_LV_USE_BUILTIN_STRING=y
|
|||||||
CONFIG_LV_USE_BUILTIN_SPRINTF=y
|
CONFIG_LV_USE_BUILTIN_SPRINTF=y
|
||||||
# CONFIG_LV_USE_CLIB_SPRINTF is not set
|
# CONFIG_LV_USE_CLIB_SPRINTF is not set
|
||||||
# CONFIG_LV_USE_CUSTOM_SPRINTF is not set
|
# CONFIG_LV_USE_CUSTOM_SPRINTF is not set
|
||||||
CONFIG_LV_MEM_SIZE_KILOBYTES=128
|
|
||||||
CONFIG_LV_MEM_POOL_EXPAND_SIZE_KILOBYTES=0
|
|
||||||
CONFIG_LV_MEM_ADR=0x0
|
|
||||||
# end of Memory Settings
|
# end of Memory Settings
|
||||||
|
|
||||||
#
|
#
|
||||||
# HAL Settings
|
# HAL Settings
|
||||||
#
|
#
|
||||||
CONFIG_LV_DEF_REFR_PERIOD=33
|
CONFIG_LV_DEF_REFR_PERIOD=16
|
||||||
CONFIG_LV_DPI_DEF=130
|
CONFIG_LV_DPI_DEF=130
|
||||||
# end of HAL Settings
|
# end of HAL Settings
|
||||||
|
|
||||||
@ -2936,12 +2933,12 @@ CONFIG_LV_USE_DRAW_SW_ASM=0
|
|||||||
#
|
#
|
||||||
CONFIG_LV_USE_LOG=y
|
CONFIG_LV_USE_LOG=y
|
||||||
# CONFIG_LV_LOG_LEVEL_TRACE is not set
|
# CONFIG_LV_LOG_LEVEL_TRACE is not set
|
||||||
CONFIG_LV_LOG_LEVEL_INFO=y
|
# CONFIG_LV_LOG_LEVEL_INFO is not set
|
||||||
# CONFIG_LV_LOG_LEVEL_WARN is not set
|
# CONFIG_LV_LOG_LEVEL_WARN is not set
|
||||||
# CONFIG_LV_LOG_LEVEL_ERROR is not set
|
CONFIG_LV_LOG_LEVEL_ERROR=y
|
||||||
# CONFIG_LV_LOG_LEVEL_USER is not set
|
# CONFIG_LV_LOG_LEVEL_USER is not set
|
||||||
# CONFIG_LV_LOG_LEVEL_NONE is not set
|
# CONFIG_LV_LOG_LEVEL_NONE is not set
|
||||||
CONFIG_LV_LOG_LEVEL=1
|
CONFIG_LV_LOG_LEVEL=3
|
||||||
CONFIG_LV_LOG_PRINTF=y
|
CONFIG_LV_LOG_PRINTF=y
|
||||||
CONFIG_LV_LOG_USE_TIMESTAMP=y
|
CONFIG_LV_LOG_USE_TIMESTAMP=y
|
||||||
CONFIG_LV_LOG_USE_FILE_LINE=y
|
CONFIG_LV_LOG_USE_FILE_LINE=y
|
||||||
|
|||||||
@ -30,6 +30,28 @@
|
|||||||
<input class="flex-1 bg-panel-2 border border-border rounded-lg px-2 py-1.5 text-text text-[12px] focus:outline-none focus:border-accent" type="number" min="0" v-model.number="store.config.standby.minutes">
|
<input class="flex-1 bg-panel-2 border border-border rounded-lg px-2 py-1.5 text-text text-[12px] focus:outline-none focus:border-accent" type="number" min="0" v-model.number="store.config.standby.minutes">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex flex-col gap-2.5">
|
||||||
|
<div class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">Screen-Animation</div>
|
||||||
|
<div class="flex items-center justify-between gap-2.5">
|
||||||
|
<label class="text-[12px] text-muted">Typ</label>
|
||||||
|
<select class="flex-1 bg-panel-2 border border-border rounded-lg px-2 py-1.5 text-text text-[12px] focus:outline-none focus:border-accent" v-model.number="store.config.screenAnim.type">
|
||||||
|
<option :value="0">Keine</option>
|
||||||
|
<option :value="1">Einblenden</option>
|
||||||
|
<option :value="2">Schieben Links</option>
|
||||||
|
<option :value="3">Schieben Rechts</option>
|
||||||
|
<option :value="4">Schieben Hoch</option>
|
||||||
|
<option :value="5">Schieben Runter</option>
|
||||||
|
<option :value="6">Ueberlagern Links</option>
|
||||||
|
<option :value="7">Ueberlagern Rechts</option>
|
||||||
|
<option :value="8">Ueberlagern Hoch</option>
|
||||||
|
<option :value="9">Ueberlagern Runter</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center justify-between gap-2.5">
|
||||||
|
<label class="text-[12px] text-muted">Dauer (ms)</label>
|
||||||
|
<input class="flex-1 bg-panel-2 border border-border rounded-lg px-2 py-1.5 text-text text-[12px] focus:outline-none focus:border-accent" type="number" min="0" max="2000" v-model.number="store.config.screenAnim.duration">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="flex flex-col gap-2.5">
|
<div class="flex flex-col gap-2.5">
|
||||||
<div class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">KNX Zeit</div>
|
<div class="text-[12px] uppercase tracking-[0.08em] text-[#3a5f88]">KNX Zeit</div>
|
||||||
<div class="flex items-center justify-between gap-2.5">
|
<div class="flex items-center justify-between gap-2.5">
|
||||||
|
|||||||
@ -71,6 +71,7 @@ const key = computed(() => w.value ? typeKeyFor(w.value.type) : 'label');
|
|||||||
const showIconPicker = ref(false);
|
const showIconPicker = ref(false);
|
||||||
const conditionIconPickerIdx = ref(-1);
|
const conditionIconPickerIdx = ref(-1);
|
||||||
const subButtonIconPickerIdx = ref(-1);
|
const subButtonIconPickerIdx = ref(-1);
|
||||||
|
const subButtonIconType = ref('off'); // 'off' or 'on'
|
||||||
const textLineIconPickerIdx = ref(-1);
|
const textLineIconPickerIdx = ref(-1);
|
||||||
|
|
||||||
// Map widget types to settings components
|
// Map widget types to settings components
|
||||||
@ -110,9 +111,10 @@ function openConditionIconPicker(idx) {
|
|||||||
showIconPicker.value = true;
|
showIconPicker.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openSubButtonIconPicker(idx) {
|
function openSubButtonIconPicker(idx, type = 'off') {
|
||||||
conditionIconPickerIdx.value = -1;
|
conditionIconPickerIdx.value = -1;
|
||||||
subButtonIconPickerIdx.value = idx;
|
subButtonIconPickerIdx.value = idx;
|
||||||
|
subButtonIconType.value = type;
|
||||||
textLineIconPickerIdx.value = -1;
|
textLineIconPickerIdx.value = -1;
|
||||||
showIconPicker.value = true;
|
showIconPicker.value = true;
|
||||||
}
|
}
|
||||||
@ -131,7 +133,8 @@ const activeIconCodepoint = computed({
|
|||||||
return w.value.conditions[conditionIconPickerIdx.value].icon || 0;
|
return w.value.conditions[conditionIconPickerIdx.value].icon || 0;
|
||||||
}
|
}
|
||||||
if (subButtonIconPickerIdx.value >= 0 && w.value?.subButtons?.[subButtonIconPickerIdx.value]) {
|
if (subButtonIconPickerIdx.value >= 0 && w.value?.subButtons?.[subButtonIconPickerIdx.value]) {
|
||||||
return w.value.subButtons[subButtonIconPickerIdx.value].icon || 0;
|
const sb = w.value.subButtons[subButtonIconPickerIdx.value];
|
||||||
|
return subButtonIconType.value === 'on' ? (sb.iconOn || 0) : (sb.iconOff || 0);
|
||||||
}
|
}
|
||||||
if (textLineIconPickerIdx.value >= 0 && w.value?.textLines?.[textLineIconPickerIdx.value]) {
|
if (textLineIconPickerIdx.value >= 0 && w.value?.textLines?.[textLineIconPickerIdx.value]) {
|
||||||
return w.value.textLines[textLineIconPickerIdx.value].icon || 0;
|
return w.value.textLines[textLineIconPickerIdx.value].icon || 0;
|
||||||
@ -142,7 +145,12 @@ const activeIconCodepoint = computed({
|
|||||||
if (conditionIconPickerIdx.value >= 0 && w.value?.conditions?.[conditionIconPickerIdx.value]) {
|
if (conditionIconPickerIdx.value >= 0 && w.value?.conditions?.[conditionIconPickerIdx.value]) {
|
||||||
w.value.conditions[conditionIconPickerIdx.value].icon = value;
|
w.value.conditions[conditionIconPickerIdx.value].icon = value;
|
||||||
} else if (subButtonIconPickerIdx.value >= 0 && w.value?.subButtons?.[subButtonIconPickerIdx.value]) {
|
} else if (subButtonIconPickerIdx.value >= 0 && w.value?.subButtons?.[subButtonIconPickerIdx.value]) {
|
||||||
w.value.subButtons[subButtonIconPickerIdx.value].icon = value;
|
const sb = w.value.subButtons[subButtonIconPickerIdx.value];
|
||||||
|
if (subButtonIconType.value === 'on') {
|
||||||
|
sb.iconOn = value;
|
||||||
|
} else {
|
||||||
|
sb.iconOff = value;
|
||||||
|
}
|
||||||
} else if (textLineIconPickerIdx.value >= 0 && w.value?.textLines?.[textLineIconPickerIdx.value]) {
|
} else if (textLineIconPickerIdx.value >= 0 && w.value?.textLines?.[textLineIconPickerIdx.value]) {
|
||||||
w.value.textLines[textLineIconPickerIdx.value].icon = value;
|
w.value.textLines[textLineIconPickerIdx.value].icon = value;
|
||||||
} else if (w.value) {
|
} else if (w.value) {
|
||||||
@ -155,6 +163,7 @@ function handleIconPickerClose() {
|
|||||||
showIconPicker.value = false;
|
showIconPicker.value = false;
|
||||||
conditionIconPickerIdx.value = -1;
|
conditionIconPickerIdx.value = -1;
|
||||||
subButtonIconPickerIdx.value = -1;
|
subButtonIconPickerIdx.value = -1;
|
||||||
|
subButtonIconType.value = 'off';
|
||||||
textLineIconPickerIdx.value = -1;
|
textLineIconPickerIdx.value = -1;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -24,8 +24,8 @@
|
|||||||
class="absolute rounded-full flex items-center justify-center shadow-md"
|
class="absolute rounded-full flex items-center justify-center shadow-md"
|
||||||
:style="getSubButtonStyle(sb, idx)"
|
:style="getSubButtonStyle(sb, idx)"
|
||||||
>
|
>
|
||||||
<span v-if="sb.icon" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
|
<span v-if="getSubButtonIcon(sb)" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
|
||||||
{{ String.fromCodePoint(sb.icon) }}
|
{{ String.fromCodePoint(getSubButtonIcon(sb)) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -56,8 +56,8 @@
|
|||||||
class="absolute rounded-full flex items-center justify-center shadow-md"
|
class="absolute rounded-full flex items-center justify-center shadow-md"
|
||||||
:style="getSubButtonStyleTile(sb, idx)"
|
:style="getSubButtonStyleTile(sb, idx)"
|
||||||
>
|
>
|
||||||
<span v-if="sb.icon" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
|
<span v-if="getSubButtonIcon(sb)" class="material-symbols-outlined" :style="getSubButtonIconStyle(sb)">
|
||||||
{{ String.fromCodePoint(sb.icon) }}
|
{{ String.fromCodePoint(getSubButtonIcon(sb)) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -162,13 +162,15 @@ const getSubButtonStyleTile = (sb, idx) => {
|
|||||||
const btnSize = (props.widget.subButtonSize || 40) * s;
|
const btnSize = (props.widget.subButtonSize || 40) * s;
|
||||||
const gap = 10 * s;
|
const gap = 10 * s;
|
||||||
const padding = 12 * s;
|
const padding = 12 * s;
|
||||||
|
// Use bgColorOff with fallback to old colorOff for compatibility
|
||||||
|
const bgColor = sb.bgColorOff || sb.colorOff || '#666666';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: btnSize + 'px',
|
width: btnSize + 'px',
|
||||||
height: btnSize + 'px',
|
height: btnSize + 'px',
|
||||||
right: padding + 'px',
|
right: padding + 'px',
|
||||||
top: (padding + idx * (btnSize + gap)) + 'px',
|
top: (padding + idx * (btnSize + gap)) + 'px',
|
||||||
backgroundColor: sb.colorOff || '#666666',
|
backgroundColor: bgColor,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -241,7 +243,8 @@ function getSubButtonStyle(sb, idx) {
|
|||||||
const angle = (pos * (Math.PI / 4)) - (Math.PI / 2);
|
const angle = (pos * (Math.PI / 4)) - (Math.PI / 2);
|
||||||
const x = centerX + orbitRadius * Math.cos(angle) - subBtnSize / 2;
|
const x = centerX + orbitRadius * Math.cos(angle) - subBtnSize / 2;
|
||||||
const y = centerY + orbitRadius * Math.sin(angle) - subBtnSize / 2;
|
const y = centerY + orbitRadius * Math.sin(angle) - subBtnSize / 2;
|
||||||
const bgColor = sb.colorOff || '#666666';
|
// Use bgColorOff with fallback to old colorOff for compatibility
|
||||||
|
const bgColor = sb.bgColorOff || sb.colorOff || '#666666';
|
||||||
|
|
||||||
return {
|
return {
|
||||||
width: `${subBtnSize}px`,
|
width: `${subBtnSize}px`,
|
||||||
@ -257,12 +260,19 @@ function getSubButtonIconStyle(sb) {
|
|||||||
const s = props.scale;
|
const s = props.scale;
|
||||||
const subBtnSize = (props.widget.subButtonSize || 40) * s;
|
const subBtnSize = (props.widget.subButtonSize || 40) * s;
|
||||||
const iconSize = subBtnSize * 0.5;
|
const iconSize = subBtnSize * 0.5;
|
||||||
|
// Use iconColorOff with fallback for compatibility
|
||||||
|
const iconColor = sb.iconColorOff || '#ffffff';
|
||||||
return {
|
return {
|
||||||
fontSize: `${iconSize}px`,
|
fontSize: `${iconSize}px`,
|
||||||
color: '#ffffff'
|
color: iconColor
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSubButtonIcon(sb) {
|
||||||
|
// Use iconOff with fallback to old icon field for compatibility
|
||||||
|
return sb.iconOff || sb.icon || 0;
|
||||||
|
}
|
||||||
|
|
||||||
const computedStyle = computed(() => {
|
const computedStyle = computed(() => {
|
||||||
const w = props.widget;
|
const w = props.widget;
|
||||||
const s = props.scale;
|
const s = props.scale;
|
||||||
|
|||||||
@ -147,10 +147,14 @@
|
|||||||
</button>
|
</button>
|
||||||
<button v-if="cond.icon" class="w-6 h-6 rounded-md border border-red-200 bg-[#f7dede] text-[#b3261e] grid place-items-center text-[11px] cursor-pointer hover:bg-[#f2cfcf]" @click="cond.icon = 0">x</button>
|
<button v-if="cond.icon" class="w-6 h-6 rounded-md border border-red-200 bg-[#f7dede] text-[#b3261e] grid place-items-center text-[11px] cursor-pointer hover:bg-[#f2cfcf]" @click="cond.icon = 0">x</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 text-[11px] text-muted">
|
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
||||||
<label class="w-[50px]">Farbe</label>
|
<label class="w-[50px]">Textfarbe</label>
|
||||||
<input class="h-[22px] w-[32px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="cond.textColor">
|
<input class="h-[22px] w-[32px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="cond.textColor">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="flex items-center gap-2 text-[11px] text-muted">
|
||||||
|
<label class="w-[50px]">Hintergr.</label>
|
||||||
|
<input class="h-[22px] w-[32px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="cond.bgColor">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -190,7 +194,8 @@ const conditionCount = computed({
|
|||||||
op: 'eq',
|
op: 'eq',
|
||||||
priority: props.widget.conditions.length,
|
priority: props.widget.conditions.length,
|
||||||
icon: 0,
|
icon: 0,
|
||||||
textColor: '#FFFFFF'
|
textColor: '#FFFFFF',
|
||||||
|
bgColor: ''
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (props.widget.conditions.length > target) {
|
if (props.widget.conditions.length > target) {
|
||||||
|
|||||||
@ -166,11 +166,20 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
||||||
<label class="w-[50px]">Icon</label>
|
<label class="w-[50px]">Icon Aus</label>
|
||||||
<button class="flex-1 bg-white border border-border rounded-md px-2.5 py-1 text-[11px] flex items-center justify-center gap-1 cursor-pointer hover:bg-[#e4ebf2]" @click="$emit('open-subbutton-icon-picker', idx)">
|
<button class="flex-1 bg-white border border-border rounded-md px-2.5 py-1 text-[11px] flex items-center justify-center gap-1 cursor-pointer hover:bg-[#e4ebf2]" @click="$emit('open-subbutton-icon-picker', idx, 'off')">
|
||||||
<span v-if="sb.icon" class="material-symbols-outlined text-[16px]">{{ String.fromCodePoint(sb.icon) }}</span>
|
<span v-if="sb.iconOff" class="material-symbols-outlined text-[16px]">{{ String.fromCodePoint(sb.iconOff) }}</span>
|
||||||
<span v-else>Kein Icon</span>
|
<span v-else>Kein Icon</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button v-if="sb.iconOff" class="w-6 h-6 rounded-md border border-red-200 bg-[#f7dede] text-[#b3261e] grid place-items-center text-[11px] cursor-pointer hover:bg-[#f2cfcf]" @click="sb.iconOff = 0">x</button>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
||||||
|
<label class="w-[50px]">Icon An</label>
|
||||||
|
<button class="flex-1 bg-white border border-border rounded-md px-2.5 py-1 text-[11px] flex items-center justify-center gap-1 cursor-pointer hover:bg-[#e4ebf2]" @click="$emit('open-subbutton-icon-picker', idx, 'on')">
|
||||||
|
<span v-if="sb.iconOn" class="material-symbols-outlined text-[16px]">{{ String.fromCodePoint(sb.iconOn) }}</span>
|
||||||
|
<span v-else>Wie Aus</span>
|
||||||
|
</button>
|
||||||
|
<button v-if="sb.iconOn" class="w-6 h-6 rounded-md border border-red-200 bg-[#f7dede] text-[#b3261e] grid place-items-center text-[11px] cursor-pointer hover:bg-[#f2cfcf]" @click="sb.iconOn = 0">x</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
||||||
<label class="w-[50px]">Aktion</label>
|
<label class="w-[50px]">Aktion</label>
|
||||||
@ -184,7 +193,7 @@
|
|||||||
<select class="flex-1 bg-white border border-border rounded-md px-2 py-1 text-[11px]" v-model.number="sb.knxRead">
|
<select class="flex-1 bg-white border border-border rounded-md px-2 py-1 text-[11px]" v-model.number="sb.knxRead">
|
||||||
<option :value="0">-- Keine --</option>
|
<option :value="0">-- Keine --</option>
|
||||||
<option v-for="addr in store.knxAddresses" :key="`${addr.addr}-${addr.index}`" :value="addr.addr">
|
<option v-for="addr in store.knxAddresses" :key="`${addr.addr}-${addr.index}`" :value="addr.addr">
|
||||||
GA {{ addr.addrStr }}
|
GA {{ addr.addrStr }} (GO{{ addr.index }})
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -193,7 +202,7 @@
|
|||||||
<select class="flex-1 bg-white border border-border rounded-md px-2 py-1 text-[11px]" v-model.number="sb.knxWrite">
|
<select class="flex-1 bg-white border border-border rounded-md px-2 py-1 text-[11px]" v-model.number="sb.knxWrite">
|
||||||
<option :value="0">-- Keine --</option>
|
<option :value="0">-- Keine --</option>
|
||||||
<option v-for="addr in writeableAddresses" :key="`${addr.addr}-${addr.index}`" :value="addr.addr">
|
<option v-for="addr in writeableAddresses" :key="`${addr.addr}-${addr.index}`" :value="addr.addr">
|
||||||
GA {{ addr.addrStr }}
|
GA {{ addr.addrStr }} (GO{{ addr.index }})
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
@ -203,12 +212,19 @@
|
|||||||
<option v-for="s in store.config.screens" :key="s.id" :value="s.id">{{ s.name }}</option>
|
<option v-for="s in store.config.screens" :key="s.id" :value="s.id">{{ s.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center gap-2 text-[11px] text-muted">
|
<div class="flex items-center gap-2 mb-2 text-[11px] text-muted">
|
||||||
<label class="w-[50px]">Farben</label>
|
<label class="w-[50px]">Hintergr.</label>
|
||||||
<span class="text-[10px]">An:</span>
|
<span class="text-[10px]">An:</span>
|
||||||
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.colorOn">
|
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.bgColorOn">
|
||||||
<span class="text-[10px]">Aus:</span>
|
<span class="text-[10px]">Aus:</span>
|
||||||
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.colorOff">
|
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.bgColorOff">
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center gap-2 text-[11px] text-muted">
|
||||||
|
<label class="w-[50px]">Icon</label>
|
||||||
|
<span class="text-[10px]">An:</span>
|
||||||
|
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.iconColorOn">
|
||||||
|
<span class="text-[10px]">Aus:</span>
|
||||||
|
<input class="h-[22px] w-[28px] cursor-pointer border-0 bg-transparent p-0" type="color" v-model="sb.iconColorOff">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -316,13 +332,16 @@ const subButtonCount = computed({
|
|||||||
while (props.widget.subButtons.length < target) {
|
while (props.widget.subButtons.length < target) {
|
||||||
props.widget.subButtons.push({
|
props.widget.subButtons.push({
|
||||||
pos: props.widget.subButtons.length,
|
pos: props.widget.subButtons.length,
|
||||||
icon: 0,
|
iconOff: 0,
|
||||||
|
iconOn: 0,
|
||||||
knxRead: 0,
|
knxRead: 0,
|
||||||
knxWrite: 0,
|
knxWrite: 0,
|
||||||
action: 0,
|
action: 0,
|
||||||
target: 0,
|
target: 0,
|
||||||
colorOn: '#FFCC00',
|
bgColorOn: '#FFCC00',
|
||||||
colorOff: '#666666'
|
bgColorOff: '#666666',
|
||||||
|
iconColorOn: '#FFFFFF',
|
||||||
|
iconColorOff: '#FFFFFF'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (props.widget.subButtons.length > target) {
|
if (props.widget.subButtons.length > target) {
|
||||||
|
|||||||
@ -8,6 +8,7 @@ export const useEditorStore = defineStore('editor', () => {
|
|||||||
startScreen: 0,
|
startScreen: 0,
|
||||||
standby: { enabled: false, screen: -1, minutes: 5 },
|
standby: { enabled: false, screen: -1, minutes: 5 },
|
||||||
knx: { time: 0, date: 0, dateTime: 0, night: 0 },
|
knx: { time: 0, date: 0, dateTime: 0, night: 0 },
|
||||||
|
screenAnim: { type: 1, duration: 300 }, // 1 = Fade, 300ms
|
||||||
screens: []
|
screens: []
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -209,6 +210,12 @@ export const useEditorStore = defineStore('editor', () => {
|
|||||||
if (config.knx.dateTime === undefined) config.knx.dateTime = 0;
|
if (config.knx.dateTime === undefined) config.knx.dateTime = 0;
|
||||||
if (config.knx.night === undefined) config.knx.night = 0;
|
if (config.knx.night === undefined) config.knx.night = 0;
|
||||||
}
|
}
|
||||||
|
if (!config.screenAnim) {
|
||||||
|
config.screenAnim = { type: 1, duration: 300 };
|
||||||
|
} else {
|
||||||
|
if (config.screenAnim.type === undefined) config.screenAnim.type = 1;
|
||||||
|
if (config.screenAnim.duration === undefined) config.screenAnim.duration = 300;
|
||||||
|
}
|
||||||
mapLegacyKnxAddresses();
|
mapLegacyKnxAddresses();
|
||||||
|
|
||||||
// Recalculate IDs
|
// Recalculate IDs
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user