diff --git a/ampel-cfg.h.py b/ampel-cfg.h.py
deleted file mode 100755
index dcc603cffb6f6b2e00d7fa31fe3582a1213ceafa..0000000000000000000000000000000000000000
--- a/ampel-cfg.h.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python3
-
-configshape_in = """
-String		current_lang
-String		wlanssid
-Password		wlanpwd
-String		www_username
-Password		www_password
-String		fs_ssid
-Password		fs_pwd
-Bool		www_basicauth_enabled
-Bool		dht_read
-Bool		htu21d_read
-Bool		ppd_read
-Bool		sds_read
-Bool		pms_read
-Bool		hpm_read
-Bool		npm_read
-Bool		sps30_read
-Bool		bmp_read
-Bool		bmx280_read
-Bool		sht3x_read
-Bool		scd30_read
-Bool		ds18b20_read
-Bool		dnms_read
-String		dnms_correction
-String		temp_correction
-String		height_above_sealevel
-Bool		gps_read
-Bool		send2dusti
-Bool		ssl_dusti
-Bool		send2madavi
-Bool		ssl_madavi
-Bool		send2sensemap
-Bool		send2fsapp
-Bool		send2aircms
-Bool		send2csv
-Bool		auto_update
-Bool		use_beta
-Bool		has_display
-Bool		has_sh1106
-Bool		has_flipped_display
-Bool		has_lcd1602
-Bool		has_lcd1602_27
-Bool		has_lcd2004
-Bool		has_lcd2004_27
-Bool		display_wifi_info
-Bool		display_device_info
-String		static_ip
-String		static_subnet
-String		static_gateway
-String		static_dns
-UInt		debug
-Time		sending_intervall_ms
-Time		time_for_wifi_config
-String		senseboxid
-Bool		send2custom
-String		host_custom
-String		url_custom
-UInt		port_custom
-String		user_custom
-Password		pwd_custom
-Bool		ssl_custom
-Bool		send2influx
-String		host_influx
-String		url_influx
-UInt		port_influx
-String		user_influx
-Password		pwd_influx
-String		measurement_name_influx
-Bool		ssl_influx
-"""
-
-with open("airrohr-cfg.h", "w") as h:
-    print("""
-
-// This file is generated, please do not edit.
-// Change airrohr-cfg.h.py instead.
-
-enum ConfigEntryType : unsigned short {
-	Config_Type_Bool,
-	Config_Type_UInt,
-	Config_Type_Time,
-	Config_Type_String,
-	Config_Type_Password
-};
-
-struct ConfigShapeEntry {
-	enum ConfigEntryType cfg_type;
-	unsigned short cfg_len;
-	const char* _cfg_key;
-	union {
-		void* as_void;
-		bool* as_bool;
-		unsigned int* as_uint;
-		char* as_str;
-	} cfg_val;
-	const __FlashStringHelper* cfg_key() const { return FPSTR(_cfg_key); }
-};
-
-enum ConfigShapeId {""", file=h)
-
-    for cfgentry in configshape_in.strip().split('\n'):
-        print("\tConfig_", cfgentry.split()[1], ",", sep='', file=h)
-    print("};", file=h)
-
-    for cfgentry in configshape_in.strip().split('\n'):
-        _, cfgkey = cfgentry.split()
-        print("static constexpr char CFG_KEY_", cfgkey.upper(),
-              "[] PROGMEM = \"", cfgkey, "\";", sep='', file=h)
-
-    print("static constexpr ConfigShapeEntry configShape[] PROGMEM = {",
-          file=h)
-    for cfgentry in configshape_in.strip().split('\n'):
-        cfgtype, cfgkey = cfgentry.split()
-        print("\t{ Config_Type_", cfgtype,
-              ", sizeof(cfg::" + cfgkey + ")-1" if cfgtype in ('String', 'Password') else ", 0",
-              ", CFG_KEY_", cfgkey.upper(),
-              ", ", "" if cfgtype in ('String', 'Password') else "&",
-              "cfg::", cfgkey, " },", sep='', file=h)
-    print("};", file=h)
diff --git a/ampel-firmware/save_config.h b/ampel-firmware/save_config.h
new file mode 100644
index 0000000000000000000000000000000000000000..771b761d83e561aa5e462d34aaed4a1ef3eda5d4
--- /dev/null
+++ b/ampel-firmware/save_config.h
@@ -0,0 +1,96 @@
+
+
+// This file is generated, please do not edit.
+// Change generate_ampel_config_h.py instead.
+
+enum ConfigEntryType : unsigned short {
+  Config_Type_Bool,
+  Config_Type_UInt,
+  Config_Type_Time,
+  Config_Type_String,
+  Config_Type_Password
+};
+
+struct ConfigShapeEntry {
+  enum ConfigEntryType cfg_type;
+  unsigned short cfg_len;
+  const char* _cfg_key;
+  union {
+    void* as_void;
+    bool* as_bool;
+    unsigned int* as_uint;
+    char* as_str;
+  } cfg_val;
+  const __FlashStringHelper* cfg_key() const { return FPSTR(_cfg_key); }
+};
+
+enum ConfigShapeId {
+  Config_wifi_ssid,
+  Config_wifi_password,
+  Config_wifi_timeout,
+  Config_measurement_timestep,
+  Config_csv_interval,
+  Config_temperature_offset,
+  Config_altitude_above_sea_level,
+  Config_atmospheric_co2_concentration,
+  Config_auto_calibrate_sensor,
+  Config_max_brightness,
+  Config_min_brightness,
+  Config_led_count,
+  Config_http_user,
+  Config_http_password,
+  Config_mqtt_sending_interval,
+  Config_mqtt_server,
+  Config_mqtt_port,
+  Config_mqtt_user,
+  Config_mqtt_password,
+  Config_ntp_server,
+  Config_utc_offset_in_seconds,
+  Config_bauds,
+};
+static constexpr char CFG_KEY_WIFI_SSID[] PROGMEM = "wifi_ssid";
+static constexpr char CFG_KEY_WIFI_PASSWORD[] PROGMEM = "wifi_password";
+static constexpr char CFG_KEY_WIFI_TIMEOUT[] PROGMEM = "wifi_timeout";
+static constexpr char CFG_KEY_MEASUREMENT_TIMESTEP[] PROGMEM = "measurement_timestep";
+static constexpr char CFG_KEY_CSV_INTERVAL[] PROGMEM = "csv_interval";
+static constexpr char CFG_KEY_TEMPERATURE_OFFSET[] PROGMEM = "temperature_offset";
+static constexpr char CFG_KEY_ALTITUDE_ABOVE_SEA_LEVEL[] PROGMEM = "altitude_above_sea_level";
+static constexpr char CFG_KEY_ATMOSPHERIC_CO2_CONCENTRATION[] PROGMEM = "atmospheric_co2_concentration";
+static constexpr char CFG_KEY_AUTO_CALIBRATE_SENSOR[] PROGMEM = "auto_calibrate_sensor";
+static constexpr char CFG_KEY_MAX_BRIGHTNESS[] PROGMEM = "max_brightness";
+static constexpr char CFG_KEY_MIN_BRIGHTNESS[] PROGMEM = "min_brightness";
+static constexpr char CFG_KEY_LED_COUNT[] PROGMEM = "led_count";
+static constexpr char CFG_KEY_HTTP_USER[] PROGMEM = "http_user";
+static constexpr char CFG_KEY_HTTP_PASSWORD[] PROGMEM = "http_password";
+static constexpr char CFG_KEY_MQTT_SENDING_INTERVAL[] PROGMEM = "mqtt_sending_interval";
+static constexpr char CFG_KEY_MQTT_SERVER[] PROGMEM = "mqtt_server";
+static constexpr char CFG_KEY_MQTT_PORT[] PROGMEM = "mqtt_port";
+static constexpr char CFG_KEY_MQTT_USER[] PROGMEM = "mqtt_user";
+static constexpr char CFG_KEY_MQTT_PASSWORD[] PROGMEM = "mqtt_password";
+static constexpr char CFG_KEY_NTP_SERVER[] PROGMEM = "ntp_server";
+static constexpr char CFG_KEY_UTC_OFFSET_IN_SECONDS[] PROGMEM = "utc_offset_in_seconds";
+static constexpr char CFG_KEY_BAUDS[] PROGMEM = "bauds";
+static constexpr ConfigShapeEntry configShape[] PROGMEM = {
+  { Config_Type_String, sizeof(cfg::wifi_ssid)-1, CFG_KEY_WIFI_SSID, cfg::wifi_ssid },
+  { Config_Type_Password, sizeof(cfg::wifi_password)-1, CFG_KEY_WIFI_PASSWORD, cfg::wifi_password },
+  { Config_Type_UInt, 0, CFG_KEY_WIFI_TIMEOUT, &cfg::wifi_timeout },
+  { Config_Type_UInt, 0, CFG_KEY_MEASUREMENT_TIMESTEP, &cfg::measurement_timestep },
+  { Config_Type_UInt, 0, CFG_KEY_CSV_INTERVAL, &cfg::csv_interval },
+  { Config_Type_UInt, 0, CFG_KEY_TEMPERATURE_OFFSET, &cfg::temperature_offset },
+  { Config_Type_UInt, 0, CFG_KEY_ALTITUDE_ABOVE_SEA_LEVEL, &cfg::altitude_above_sea_level },
+  { Config_Type_UInt, 0, CFG_KEY_ATMOSPHERIC_CO2_CONCENTRATION, &cfg::atmospheric_co2_concentration },
+  { Config_Type_Bool, 0, CFG_KEY_AUTO_CALIBRATE_SENSOR, &cfg::auto_calibrate_sensor },
+  { Config_Type_UInt, 0, CFG_KEY_MAX_BRIGHTNESS, &cfg::max_brightness },
+  { Config_Type_UInt, 0, CFG_KEY_MIN_BRIGHTNESS, &cfg::min_brightness },
+  { Config_Type_UInt, 0, CFG_KEY_LED_COUNT, &cfg::led_count },
+  { Config_Type_String, sizeof(cfg::http_user)-1, CFG_KEY_HTTP_USER, cfg::http_user },
+  { Config_Type_Password, sizeof(cfg::http_password)-1, CFG_KEY_HTTP_PASSWORD, cfg::http_password },
+  { Config_Type_UInt, 0, CFG_KEY_MQTT_SENDING_INTERVAL, &cfg::mqtt_sending_interval },
+  { Config_Type_String, sizeof(cfg::mqtt_server)-1, CFG_KEY_MQTT_SERVER, cfg::mqtt_server },
+  { Config_Type_UInt, 0, CFG_KEY_MQTT_PORT, &cfg::mqtt_port },
+  { Config_Type_String, sizeof(cfg::mqtt_user)-1, CFG_KEY_MQTT_USER, cfg::mqtt_user },
+  { Config_Type_String, sizeof(cfg::mqtt_password)-1, CFG_KEY_MQTT_PASSWORD, cfg::mqtt_password },
+  { Config_Type_String, sizeof(cfg::ntp_server)-1, CFG_KEY_NTP_SERVER, cfg::ntp_server },
+  { Config_Type_UInt, 0, CFG_KEY_UTC_OFFSET_IN_SECONDS, &cfg::utc_offset_in_seconds },
+  { Config_Type_UInt, 0, CFG_KEY_BAUDS, &cfg::bauds },
+};
diff --git a/generate_ampel_config_h.py b/generate_ampel_config_h.py
new file mode 100755
index 0000000000000000000000000000000000000000..b4069457bfc101cd3420fccf803cd6035c5d72e7
--- /dev/null
+++ b/generate_ampel_config_h.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+
+# Copied from https://github.com/opendata-stuttgart/sensors-software/blob/master/airrohr-firmware/airrohr-cfg.h.py
+
+configshape_in = """
+String   wifi_ssid
+Password wifi_password
+UInt     wifi_timeout
+UInt     measurement_timestep
+UInt     csv_interval
+UInt     temperature_offset # Signed, actually. :-(
+UInt     altitude_above_sea_level
+UInt     atmospheric_co2_concentration
+Bool     auto_calibrate_sensor
+UInt     max_brightness
+UInt     min_brightness
+UInt     led_count
+String   http_user
+Password http_password
+UInt     mqtt_sending_interval
+String   mqtt_server
+UInt     mqtt_port
+String   mqtt_user
+String   mqtt_password
+String   ntp_server
+UInt     utc_offset_in_seconds
+UInt     bauds # Too large for unsigned int
+"""
+
+with open("ampel-firmware/save_config.h", "w") as h:
+    print("""
+
+// This file is generated, please do not edit.
+// Change generate_ampel_config_h.py instead.
+
+enum ConfigEntryType : unsigned short {
+  Config_Type_Bool,
+  Config_Type_UInt,
+  Config_Type_Time,
+  Config_Type_String,
+  Config_Type_Password
+};
+
+struct ConfigShapeEntry {
+  enum ConfigEntryType cfg_type;
+  unsigned short cfg_len;
+  const char* _cfg_key;
+  union {
+    void* as_void;
+    bool* as_bool;
+    unsigned int* as_uint;
+    char* as_str;
+  } cfg_val;
+  const __FlashStringHelper* cfg_key() const { return FPSTR(_cfg_key); }
+};
+
+enum ConfigShapeId {""", file=h)
+    entries = [row.strip().split()[:2] for row in configshape_in.strip().splitlines()]
+
+    for _, cfgkey in entries:
+        print("  Config_", cfgkey, ",", sep='', file=h)
+    print("};", file=h)
+
+    for _, cfgkey in entries:
+        print("static constexpr char CFG_KEY_", cfgkey.upper(),
+              "[] PROGMEM = \"", cfgkey, "\";", sep='', file=h)
+
+    print("static constexpr ConfigShapeEntry configShape[] PROGMEM = {",
+          file=h)
+
+    for cfgtype, cfgkey in entries:
+        print("  { Config_Type_", cfgtype,
+              ", sizeof(cfg::" + cfgkey + ")-1" if cfgtype in ('String', 'Password') else ", 0",
+              ", CFG_KEY_", cfgkey.upper(),
+              ", ", "" if cfgtype in ('String', 'Password') else "&",
+              "cfg::", cfgkey, " },", sep='', file=h)
+    print("};", file=h)