Skip to content

Commit a8bb896

Browse files
committed
Fix import regressions: component id, restore_mode, ledc inverted, template lambda, time on_time, ap secrets split
1 parent db20a12 commit a8bb896

6 files changed

Lines changed: 45 additions & 11 deletions

File tree

‎src/components/SettingsPanel.tsx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,13 @@ export default function SettingsPanel() {
9898
<label className="toggle-label">
9999
<input
100100
type="checkbox"
101-
checked={s.useSecretsFallbackAp}
102-
onChange={(e) => update({ useSecretsFallbackAp: e.target.checked })}
101+
checked={s.useSecretsFallbackApSsid && s.useSecretsFallbackApPassword}
102+
onChange={(e) => update({ useSecretsFallbackApSsid: e.target.checked, useSecretsFallbackApPassword: e.target.checked })}
103103
/>
104104
<span className="toggle-text">Use secrets.yaml</span>
105105
</label>
106106
</div>
107-
{!s.useSecretsFallbackAp && (
107+
{!s.useSecretsFallbackApSsid && (
108108
<>
109109
<div className="form-group">
110110
<label>AP Name</label>

‎src/context/ProjectContext.tsx‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ const defaultSettings: ProjectSettings = {
3434
fallbackApEnabled: true,
3535
fallbackApSsid: '',
3636
fallbackApPassword: '',
37-
useSecretsFallbackAp: false,
37+
useSecretsFallbackApSsid: false,
38+
useSecretsFallbackApPassword: false,
3839
statusLedPin: '',
3940
timeEnabled: false,
4041
timeTimezone: '',

‎src/data/components.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,7 @@ export const componentDefinitions: ComponentDefinition[] = [
624624
configFields: [
625625
{ key: 'name', label: 'ID', type: 'text', required: true, placeholder: 'pwm_output' },
626626
{ key: 'frequency', label: 'Frequency', type: 'text', default: '1000Hz' },
627+
{ key: 'inverted', label: 'Inverted', type: 'boolean', default: false },
627628
],
628629
},
629630
{

‎src/types/index.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,9 @@ export interface ProjectSettings {
190190
fallbackApEnabled: boolean;
191191
fallbackApSsid: string;
192192
fallbackApPassword: string;
193-
useSecretsFallbackAp: boolean;
193+
useSecretsFallbackApSsid: boolean;
194+
useSecretsFallbackApPassword: boolean;
195+
_rawTimeExtras?: Record<string, unknown>;
194196
_rawOnBoot?: unknown;
195197
statusLedPin: string;
196198
timeEnabled: boolean;

‎src/utils/yamlGenerator.ts‎

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,8 @@ export function generateYaml(project: Project): string {
8080

8181
if (settings.fallbackApEnabled) {
8282
wifi.ap = {
83-
ssid: settings.useSecretsFallbackAp ? '__SECRET__fallback_ap_ssid' : (settings.fallbackApSsid || `${settings.friendlyName} Fallback`),
84-
password: settings.useSecretsFallbackAp ? '__SECRET__fallback_ap_password' : (settings.fallbackApPassword || 'fallback123'),
83+
ssid: settings.useSecretsFallbackApSsid ? '__SECRET__fallback_ap_ssid' : (settings.fallbackApSsid || `${settings.friendlyName} Fallback`),
84+
password: settings.useSecretsFallbackApPassword ? '__SECRET__fallback_ap_password' : (settings.fallbackApPassword || 'fallback123'),
8585
};
8686
}
8787
doc.wifi = wifi;
@@ -288,10 +288,12 @@ export function generateYaml(project: Project): string {
288288
// ── time (SNTP) ──
289289
if (settings.timeEnabled) {
290290
const time: Record<string, unknown> = { platform: 'sntp' };
291+
if (settings._rawTimeExtras?.id) time.id = settings._rawTimeExtras.id;
291292
if (settings.timeTimezone) time.timezone = settings.timeTimezone;
292293
if (settings.timeServers) {
293294
time.servers = settings.timeServers.split(',').map((s) => s.trim()).filter(Boolean);
294295
}
296+
if (settings._rawTimeExtras?.on_time) time.on_time = settings._rawTimeExtras.on_time;
295297
doc.time = [time];
296298
}
297299

@@ -777,6 +779,7 @@ function generateComponentEntry(
777779
base.name = str(inst.config.name, inst.name);
778780
// Use original output id from import if present, otherwise auto-generate
779781
base.output = inst.config._outputId ? String(inst.config._outputId) : `${inst.id}_output`;
782+
if (inst.config.restore_mode) base.restore_mode = inst.config.restore_mode;
780783
break;
781784
}
782785
case 'light.neopixelbus': {
@@ -800,6 +803,7 @@ function generateComponentEntry(
800803
base.platform = 'ledc';
801804
if (inst.pins.pin != null) base.pin = `GPIO${inst.pins.pin}`;
802805
base.id = inst.config.name ? String(inst.config.name) : inst.id;
806+
if (inst.config.inverted) base.inverted = true;
803807
if (inst.config.frequency) base.frequency = inst.config.frequency;
804808
break;
805809
}
@@ -1414,6 +1418,7 @@ function generateComponentEntry(
14141418
base.platform = 'template';
14151419
base.name = str(inst.config.name, inst.name);
14161420
if (inst.config.device_class) base.device_class = inst.config.device_class;
1421+
if (inst.config._lambda) base.lambda = inst.config._lambda;
14171422
break;
14181423
}
14191424
case 'binary_sensor.analog_threshold': {
@@ -1505,6 +1510,14 @@ function generateComponentEntry(
15051510
}
15061511
}
15071512

1513+
// Generic: emit _yamlId (component id distinct from name), _filters captured from import
1514+
if (inst.config._yamlId !== undefined && base.id === undefined) {
1515+
base.id = inst.config._yamlId;
1516+
}
1517+
if (inst.config._filters !== undefined && base.filters === undefined) {
1518+
base.filters = inst.config._filters;
1519+
}
1520+
15081521
return base;
15091522
}
15101523

@@ -1694,7 +1707,7 @@ function str(val: unknown, fallback: string): string {
16941707
/** Generate a secrets.yaml file based on which secret flags are enabled */
16951708
export function generateSecretsYaml(project: Project): string | null {
16961709
const s = project.settings;
1697-
const anySecrets = s.useSecretsWifi || s.useSecretsApi || s.useSecretsOta || s.useSecretsMqtt || s.useSecretsFallbackAp;
1710+
const anySecrets = s.useSecretsWifi || s.useSecretsApi || s.useSecretsOta || s.useSecretsMqtt || s.useSecretsFallbackApSsid || s.useSecretsFallbackApPassword;
16981711
if (!anySecrets) return null;
16991712

17001713
const lines: string[] = [
@@ -1720,8 +1733,8 @@ export function generateSecretsYaml(project: Project): string | null {
17201733
lines.push(`mqtt_password: "${s.mqttPassword || 'YOUR_MQTT_PASSWORD'}"`);
17211734
}
17221735

1723-
if (s.useSecretsFallbackAp && s.fallbackApEnabled) {
1724-
lines.push(`fallback_ap_ssid: "${s.fallbackApSsid || 'YOUR_AP_NAME'}"`);
1736+
if ((s.useSecretsFallbackApSsid || s.useSecretsFallbackApPassword) && s.fallbackApEnabled) {
1737+
if (s.useSecretsFallbackApSsid) lines.push(`fallback_ap_ssid: "${s.fallbackApSsid || 'YOUR_AP_NAME'}"`);
17251738
lines.push(`fallback_ap_password: "${s.fallbackApPassword || 'YOUR_AP_PASSWORD'}"`);
17261739
}
17271740

‎src/utils/yamlImporter.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -203,13 +203,20 @@ export function importYaml(text: string): ImportResult {
203203
fallbackApEnabled: !!apDoc.ssid,
204204
fallbackApSsid: isSecret(apDoc.ssid) ? '' : strVal(apDoc.ssid),
205205
fallbackApPassword: isSecret(apDoc.password) ? '' : strVal(apDoc.password),
206-
useSecretsFallbackAp: isSecret(apDoc.ssid) || isSecret(apDoc.password),
206+
useSecretsFallbackApSsid: isSecret(apDoc.ssid),
207+
useSecretsFallbackApPassword: isSecret(apDoc.password),
207208
statusLedPin,
208209
timeEnabled: doc.time !== undefined,
209210
timeTimezone: strVal(timeDoc.timezone),
210211
timeServers: Array.isArray(timeDoc.servers)
211212
? (timeDoc.servers as unknown[]).map(String).join(', ')
212213
: '',
214+
_rawTimeExtras: (() => {
215+
const extras: Record<string, unknown> = {};
216+
if (timeDoc.id) extras.id = timeDoc.id;
217+
if (timeDoc.on_time) extras.on_time = timeDoc.on_time;
218+
return Object.keys(extras).length > 0 ? extras : undefined;
219+
})(),
213220
};
214221

215222
// ── Components ───────────────────────────────────────────────
@@ -296,6 +303,16 @@ export function importYaml(text: string): ImportResult {
296303
}
297304
}
298305

306+
// Generic extra captures: id (separate from name), restore_mode, lambda, filters
307+
if (entry.id !== undefined && String(entry.id) !== String(config.name ?? '')) {
308+
config._yamlId = entry.id;
309+
}
310+
if (entry.restore_mode !== undefined && config.restore_mode === undefined) {
311+
config.restore_mode = entry.restore_mode;
312+
}
313+
if (entry.lambda !== undefined) config._lambda = entry.lambda;
314+
if (entry.filters !== undefined) config._filters = entry.filters;
315+
299316
// Capture inline action blocks (on_press, on_state, on_value, etc.) so the
300317
// generator can re-attach them and the original behaviour is preserved.
301318
const inlineActions: Record<string, unknown> = {};

0 commit comments

Comments
 (0)