export const DISPLAY_W = 1280; export const DISPLAY_H = 800; export const MAX_SCREENS = 8; export const WIDGET_TYPES = { LABEL: 0, BUTTON: 1, LED: 2, ICON: 3, TABVIEW: 4, TABPAGE: 5, POWERFLOW: 6, POWERNODE: 7, POWERLINK: 8, CHART: 9, CLOCK: 10, ROOMCARD: 11, RECTANGLE: 12, ARC: 13, BUTTONMATRIX: 14 }; export const ICON_POSITIONS = { LEFT: 0, RIGHT: 1, TOP: 2, BOTTOM: 3 }; export const BUTTON_ACTIONS = { KNX: 0, JUMP: 1, BACK: 2, NONE: 3 }; export const TEXT_ALIGNS = { LEFT: 0, CENTER: 1, RIGHT: 2 }; export const TYPE_KEYS = { 0: 'label', 1: 'button', 2: 'led', 3: 'icon', 4: 'tabview', 5: 'tabpage', 6: 'powerflow', 7: 'powernode', 8: 'powerlink', 9: 'chart', 10: 'clock', 11: 'roomcard', 12: 'rectangle', 13: 'arc', 14: 'buttonmatrix' }; export const TYPE_LABELS = { label: 'Label', button: 'Button', led: 'LED', icon: 'Icon', tabview: 'Tabs', tabpage: 'Seite', powerflow: 'Power Flow', powernode: 'Power Node', powerlink: 'Power Link', chart: 'Chart', clock: 'Uhr (Analog)', roomcard: 'Room Card', rectangle: 'Rechteck', arc: 'Arc', buttonmatrix: 'Button Matrix' }; export const textSources = { 0: 'Statisch', 1: 'KNX Temperatur', 2: 'KNX Schalter', 3: 'KNX Prozent', 4: 'KNX Text', 5: 'KNX Leistung (DPT 14.056)', 6: 'KNX Energie (DPT 13.013)', 7: 'KNX Dezimalfaktor (DPT 5.005)', 8: 'KNX Uhrzeit (DPT 10.001)', 9: 'KNX Datum (DPT 11.001)', 10: 'KNX Datum & Uhrzeit (DPT 19.001)', 11: 'System Uhrzeit', 12: 'System Datum', 13: 'System Datum & Uhrzeit', 14: 'KNX Luftfeuchtigkeit (DPT 9.007)', 15: 'KNX Helligkeit (DPT 9.004)' }; export const textSourceGroups = [ { label: 'Statisch', values: [0] }, { label: 'System', values: [11, 12, 13] }, { label: 'DPT 1.x', values: [2] }, { label: 'DPT 5.x', values: [3, 7] }, { label: 'DPT 9.x', values: [1, 14, 15] }, { label: 'DPT 10.x', values: [8] }, { label: 'DPT 11.x', values: [9] }, { label: 'DPT 13.x', values: [6] }, { label: 'DPT 14.x', values: [5] }, { label: 'DPT 16.x', values: [4] }, { label: 'DPT 19.x', values: [10] } ]; export const sourceOptions = { label: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], button: [0], led: [0, 2], icon: [0, 2], powernode: [0, 1, 2, 3, 4, 5, 6, 7, 14, 15], powerlink: [0, 1, 3, 5, 6, 7, 14, 15], chart: [1, 3, 5, 6, 7, 14, 15], clock: [11], roomcard: [0, 1, 3, 5, 6, 7, 14, 15], rectangle: [0], arc: [0, 1, 2, 3, 5, 6, 7, 14, 15], buttonmatrix: [0] }; export const chartPeriods = [ { value: 0, label: '1h' }, { value: 1, label: '3h' }, { value: 2, label: '5h' }, { value: 3, label: '12h' }, { value: 4, label: '24h' }, { value: 5, label: '1 Monat' } ]; export const SUBBUTTON_POSITIONS = { TOP: 0, TOP_RIGHT: 1, RIGHT: 2, BOTTOM_RIGHT: 3, BOTTOM: 4, BOTTOM_LEFT: 5, LEFT: 6, TOP_LEFT: 7 }; export const SUBBUTTON_POSITION_LABELS = { 0: 'Oben', 1: 'Oben rechts', 2: 'Rechts', 3: 'Unten rechts', 4: 'Unten', 5: 'Unten links', 6: 'Links', 7: 'Oben links' }; export const SUBBUTTON_ACTIONS = { TOGGLE_KNX: 0, NAVIGATE: 1 }; export const ICON_DEFAULTS = { iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 8 }; export const fontSizes = [14, 18, 22, 28, 36, 48]; // Icon fonts have additional larger sizes for decorative use // Large icons use PSRAM for draw buffers (ESP32-P4 with 32MB PSRAM) export const iconFontSizes = [14, 18, 22, 28, 36, 48, 64, 80, 96, 120, 150, 180, 220, 260]; export const defaultFormats = { 1: '%.1f °C', 2: '%s', 3: '%d %%', 4: '%s', 5: '%.1f W', 6: '%.0f kWh', 7: '%d', 8: '%02d:%02d:%02d', 9: '%02d.%02d.%04d', 10: '%02d.%02d.%04d %02d:%02d:%02d', 11: '%02d:%02d:%02d', 12: '%02d.%02d.%04d', 13: '%02d.%02d.%04d %02d:%02d:%02d' }; export const WIDGET_DEFAULTS = { label: { w: 160, h: 40, text: 'Neues Label', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.LEFT, textColor: '#FFFFFF', bgColor: '#0E1217', bgOpacity: 0, radius: 6, shadow: { enabled: false, x: 2, y: 2, blur: 8, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.KNX, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 8, themeFixed: false }, button: { w: 130, h: 52, text: 'Button', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, isContainer: false, textColor: '#FFFFFF', bgColor: '#2E7DD1', bgOpacity: 255, radius: 10, shadow: { enabled: true, x: 2, y: 3, blur: 10, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.KNX, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 8, themeFixed: false, conditions: [] }, led: { w: 60, h: 60, text: '', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#F6C177', bgOpacity: 255, radius: 30, shadow: { enabled: true, x: 0, y: 0, blur: 18, spread: 0, color: '#F6C177' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.KNX, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 8, themeFixed: false }, icon: { w: 48, h: 48, text: '', textSrc: 0, fontSize: 3, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#0E1217', bgOpacity: 0, radius: 0, shadow: { enabled: false, x: 0, y: 0, blur: 0, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.KNX, targetScreen: 0, iconCodepoint: 0xe88a, iconPosition: 0, iconSize: 3, iconGap: 8, themeFixed: false }, tabview: { w: 400, h: 300, text: '', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#2a3543', bgOpacity: 255, radius: 8, shadow: { enabled: false }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, // 0=Top, 1=Bottom, 2=Left, 3=Right iconSize: 5, // Used for Tab Height (x10) -> 50px iconGap: 0, themeFixed: false }, tabpage: { w: 0, // Ignored h: 0, // Ignored text: 'Tab', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#1A1A2E', bgOpacity: 0, // Transparent by default radius: 0, shadow: { enabled: false }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, themeFixed: false }, powerflow: { w: 720, h: 460, text: 'Power Flow Card', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.LEFT, textColor: '#1f2a33', bgColor: '#ffffff', bgOpacity: 255, radius: 18, shadow: { enabled: true, x: 0, y: 8, blur: 22, spread: 0, color: '#1b28351f' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, themeFixed: false }, powernode: { w: 120, h: 120, text: 'Knoten\n0 W', textSrc: 0, fontSize: 2, textAlign: TEXT_ALIGNS.CENTER, textColor: '#223447', bgColor: '#4fb06d', bgOpacity: 255, radius: 60, shadow: { enabled: false, x: 0, y: 0, blur: 12, spread: 0, color: '#4fb06d' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 8, // Secondary value (left) textSrc2: 0, text2: '', knxAddr2: 0, // Tertiary value (right) textSrc3: 0, text3: '', knxAddr3: 0, // Conditions themeFixed: false, conditions: [] }, powerlink: { w: 3, h: 0, text: '', textSrc: 0, fontSize: 0, textAlign: TEXT_ALIGNS.CENTER, textColor: '#2b3b4b', bgColor: '#6fa7d8', bgOpacity: 220, radius: 0, shadow: { enabled: false, x: 0, y: 0, blur: 0, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 0, iconGap: 6, themeFixed: false }, chart: { w: 360, h: 220, text: 'Chart', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.LEFT, textColor: '#E7EDF3', bgColor: '#16202c', bgOpacity: 255, radius: 12, shadow: { enabled: false, x: 0, y: 0, blur: 0, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, themeFixed: false, chart: { period: 0, showXLine: true, showYLine: true, showXLabels: true, showYLabels: true, showBg: true, showGrid: true, lineWidth: 2, pointCount: 120, showPoints: false, pointSize: 4, series: [ { knxAddr: 0, textSrc: 1, color: '#EF6351' } ] } }, clock: { w: 200, h: 200, text: '', textSrc: 11, // System Time fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#16202c', bgOpacity: 255, radius: 100, // Circular default shadow: { enabled: false, x: 0, y: 0, blur: 0, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, themeFixed: false }, roomcard: { w: 200, h: 200, text: 'Wohnzimmer\n%.1f °C', textSrc: 1, // Temperature fontSize: 2, textAlign: TEXT_ALIGNS.CENTER, textColor: '#223447', bgColor: '#FFFFFF', bgOpacity: 255, radius: 16, // For Tile style (Bubble ignores this) shadow: { enabled: true, x: 0, y: 4, blur: 12, spread: 0, color: '#00000022' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.JUMP, targetScreen: 0, iconCodepoint: 0xe88a, // Home icon iconPosition: 0, iconSize: 3, iconGap: 8, subButtonSize: 40, // Sub-button size in pixels subButtonDistance: 80, // Distance from center in pixels subButtonOpacity: 255, // Sub-button opacity (0-255) cardStyle: 0, // 0=Bubble (round), 1=Tile (rectangular) subButtons: [], textLines: [], // Variable text lines with icon, text, textSrc, knxAddr, fontSize themeFixed: false }, rectangle: { w: 220, h: 140, text: '', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#2E7DD1', bgOpacity: 180, radius: 14, borderWidth: 2, borderColor: '#FFFFFF', borderOpacity: 180, shadow: { enabled: false, x: 2, y: 2, blur: 10, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, iconPositionX: 0, iconPositionY: 0, themeFixed: false }, arc: { w: 180, h: 180, text: '75', textSrc: 0, fontSize: 2, textAlign: TEXT_ALIGNS.CENTER, textColor: '#5DD39E', bgColor: '#274060', bgOpacity: 180, radius: 12, borderWidth: 0, borderColor: '#FFFFFF', borderOpacity: 0, arcMin: 0, arcMax: 100, arcUnit: 1, arcShowValue: true, arcScaleOffset: 0, arcScaleColor: '#5DD39E', arcValueColor: '#5DD39E', arcValueFontSize: 2, shadow: { enabled: false, x: 0, y: 0, blur: 8, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: 0, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, iconPositionX: 0, iconPositionY: 0, themeFixed: false }, buttonmatrix: { w: 240, h: 150, text: '1;2;3\n4;5;6\n7;8;9', textSrc: 0, fontSize: 1, textAlign: TEXT_ALIGNS.CENTER, textColor: '#FFFFFF', bgColor: '#2A3A4A', bgOpacity: 200, radius: 10, borderWidth: 1, borderColor: '#FFFFFF', borderOpacity: 48, shadow: { enabled: false, x: 0, y: 0, blur: 8, spread: 0, color: '#000000' }, isToggle: false, knxAddrWrite: 0, knxAddr: 0, action: BUTTON_ACTIONS.KNX, targetScreen: 0, iconCodepoint: 0, iconPosition: 0, iconSize: 1, iconGap: 0, iconPositionX: 0, iconPositionY: 0, themeFixed: false } };