diff --git a/denon/__init__.py b/denon/__init__.py
index 04f83d4c0..275efa482 100755
--- a/denon/__init__.py
+++ b/denon/__init__.py
@@ -57,10 +57,6 @@ class denon(SmartDevicePlugin):
 
     PLUGIN_VERSION = '1.0.1'
 
-    def on_connect(self, by=None):
-        self.logger.debug("Checking for custom input names.")
-        self.send_command('general.custom_inputnames')
-
     def _set_device_defaults(self):
         self._use_callbacks = True
         self._custom_inputnames = {}
diff --git a/denon/commands.py b/denon/commands.py
index 908e3e345..041c178c1 100755
--- a/denon/commands.py
+++ b/denon/commands.py
@@ -36,32 +36,32 @@
     'info': {
         'fullmodel': {'read': True, 'write': False, 'read_cmd': 'NSFRN ?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'NSFRN\s(.*)', 'item_attrs': {'initial': True}},
         'model': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': 'VIALL(AVR.*)', 'item_attrs': {'initial': True}},
-        'serialnumber': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLS/N\.(.*)'},
-        'main': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLMAIN:(.*)'},
-        'mainfbl': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLMAINFBL:(.*)'},
-        'dsp1': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP1:(.*)'},
-        'dsp2': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP2:(.*)'},
-        'dsp3': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP3:(.*)'},
-        'dsp4': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP4:(.*)'},
-        'apld': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLAPLD:(.*)'},
-        'vpld': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLVPLD:(.*)'},
-        'guidat': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLGUIDAT:(.*)'},
-        'heosversion': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSVER:(.*)'},
-        'heosbuild': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSBLD:(.*)'},
-        'heosmod': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSMOD:(.*)'},
-        'heoscnf': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLHEOSCNF:(.*)'},
-        'heoslanguage': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLHEOSLCL:(.*)'},
-        'mac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLMAC:(.*)'},
-        'wifimac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLWIFIMAC:(.*)'},
-        'btmac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLBTMAC:(.*)'},
-        'audyif': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLAUDYIF:(.*)'},
-        'productid': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLPRODUCTID:(.*)'},
-        'packageid': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLPACKAGEID:(.*)'},
-        'cmp': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLCMP:(.*)'},
+        'serialnumber': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLS/N\.(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'main': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLMAIN:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'mainfbl': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLMAINFBL:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'dsp1': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP1:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'dsp2': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP2:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'dsp3': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP3:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'dsp4': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLDSP4:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'apld': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLAPLD:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'vpld': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLVPLD:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'guidat': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLGUIDAT:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'heosversion': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSVER:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'heosbuild': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSBLD:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'heosmod': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLHEOSMOD:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'heoscnf': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLHEOSCNF:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'heoslanguage': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLHEOSLCL:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'mac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLMAC:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'wifimac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLWIFIMAC:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'btmac': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLBTMAC:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'audyif': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLAUDYIF:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'productid': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLPRODUCTID:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'packageid': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'num', 'dev_datatype': 'raw', 'reply_pattern': r'VIALLPACKAGEID:(.*)', 'item_attrs': {'read_group_levels': 0}},
+        'cmp': {'read': True, 'write': False, 'read_cmd': 'VIALL?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'VIALLCMP:(.*)', 'item_attrs': {'read_group_levels': 0}},
         'region': {'read': True, 'write': False, 'read_cmd': 'SYMODTUN ?', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'SYMODTUN\s(.*)', 'item_attrs': {'initial': True}},
     },
     'general': {
-        'custom_inputnames': {'read': True, 'write': False, 'read_cmd': 'SSFUN ?', 'item_type': 'dict', 'dev_datatype': 'DenonCustominput', 'reply_pattern': 'SSFUN(.*)', 'item_attrs': {'item_template': 'custom_inputnames'}},
+        'custom_inputnames': {'read': True, 'write': False, 'read_cmd': 'SSFUN ?', 'item_type': 'dict', 'dev_datatype': 'DenonCustominput', 'reply_pattern': 'SSFUN(.*)', 'item_attrs': {'read_groups': [{'name': 'custom_inputnames', 'trigger': 'update'}], 'initial': True, 'item_template': 'custom_inputnames'}},
         'power': {'read': True, 'write': True, 'read_cmd': 'PW?', 'write_cmd': 'PW{VALUE}', 'item_type': 'bool', 'dev_datatype': 'str', 'reply_pattern': 'PW{LOOKUP}', 'lookup': 'POWER'},
         'setupmenu': {'read': True, 'write': True, 'read_cmd': 'MNMEN?', 'write_cmd': 'MNMEN {VALUE}', 'item_type': 'bool', 'dev_datatype': 'onoff', 'reply_pattern': 'MNMEN (ON|OFF)'},
         'display': {'read': True, 'write': False, 'read_cmd': 'NSE', 'item_type': 'str', 'dev_datatype': 'DenonDisplay', 'reply_pattern': 'NSE(.*)'},
@@ -108,7 +108,7 @@
             'volumedown': {'read': False, 'write': True, 'write_cmd': 'MVDOWN', 'item_type': 'bool', 'dev_datatype': 'raw'},
             'volumemax': {'opcode': '{VALUE}', 'read': True, 'write': False, 'item_type': 'num', 'dev_datatype': 'str', 'reply_pattern': r'MVMAX (\d{2,3})', 'item_attrs': {'read_group_levels': 0}},
             'input': {'read': True, 'write': True, 'read_cmd': 'SI?', 'write_cmd': 'SI{VALUE}', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': 'SI{LOOKUP}', 'lookup': 'INPUT', 'item_attrs': {'item_template': 'input', 'initial': True}},
-            'listeningmode': {'read': True, 'write': True, 'cmd_settings': {'valid_list_ci': ['MOVIE', 'MUSIC', 'GAME', 'DIRECT', 'PURE DIRECT', 'STEREO', 'AUTO', 'DOLBY DIGITAL', 'DOLBY SURROUND', 'DTS SURROUND', 'NEURAL:X', 'AURO3D', 'AURO2DSURR', 'MCH STEREO', 'ROCK ARENA', 'JAZZ CLUB', 'MONO MOVIE', 'MATRIX', 'VIDEO GAME', 'VIRTUAL', 'LEFT', 'RIGHT']}, 'read_cmd': 'MS?', 'write_cmd': 'MS{RAW_VALUE_UPPER}', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'\s?MS(.*)', 'item_attrs': {'initial': True}},
+            'listeningmode': {'read': True, 'write': True, 'cmd_settings': {'valid_list_ci': ['MOVIE', 'MUSIC', 'GAME', 'DIRECT', 'PURE DIRECT', 'STEREO', 'AUTO', 'DOLBY DIGITAL', 'DOLBY SURROUND', 'DTS SURROUND', 'NEURAL:X', 'AURO3D', 'AURO2DSURR', 'MCH STEREO', 'ROCK ARENA', 'JAZZ CLUB', 'MONO MOVIE', 'MATRIX', 'VIDEO GAME', 'VIRTUAL', 'LEFT', 'RIGHT']}, 'read_cmd': 'MS?', 'write_cmd': 'MS{RAW_VALUE_UPPER}', 'item_type': 'str', 'dev_datatype': 'str', 'reply_pattern': r'\x00?MS(.*)', 'item_attrs': {'initial': True}},
             'sleep': {'read': True, 'write': True, 'item_type': 'num', 'read_cmd': 'SLP?', 'write_cmd': 'SLP{VALUE}', 'dev_datatype': 'convert0', 'reply_pattern': r'SLP(\d{3}|OFF)', 'cmd_settings': {'force_min': 0, 'force_max': 120}, 'item_attrs': {'initial': True}},
             'standby': {'read': True, 'write': True, 'item_type': 'num', 'read_cmd': 'STBY?', 'write_cmd': 'STBY{VALUE}', 'dev_datatype': 'DenonStandby1', 'reply_pattern': r'STBY(\d{2}M|OFF)', 'cmd_settings': {'valid_list_ci': [0, 15, 30, 60]}, 'item_attrs': {'initial': True}},
         },
@@ -421,10 +421,10 @@
         }
     },
     'input': {
-        'on_change': [".custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]",],
+        'on_change': [".custom_name = sh.....general.custom_inputnames().get(value, '')"],
         'custom_name': {
             'type': 'str',
-            'on_change': "sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None"
+            'on_change': "sh...(sh......general.custom_inputnames.reverse().get(value, ''))"
         }
     }
 }
diff --git a/denon/plugin.yaml b/denon/plugin.yaml
index 7994315b6..0e79b628d 100755
--- a/denon/plugin.yaml
+++ b/denon/plugin.yaml
@@ -364,176 +364,132 @@ item_structs:
             denon_command@instance: info.serialnumber
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         main:
             type: str
             denon_command@instance: info.main
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         mainfbl:
             type: num
             denon_command@instance: info.mainfbl
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         dsp1:
             type: num
             denon_command@instance: info.dsp1
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         dsp2:
             type: num
             denon_command@instance: info.dsp2
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         dsp3:
             type: num
             denon_command@instance: info.dsp3
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         dsp4:
             type: num
             denon_command@instance: info.dsp4
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         apld:
             type: num
             denon_command@instance: info.apld
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         vpld:
             type: num
             denon_command@instance: info.vpld
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         guidat:
             type: num
             denon_command@instance: info.guidat
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         heosversion:
             type: str
             denon_command@instance: info.heosversion
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         heosbuild:
             type: num
             denon_command@instance: info.heosbuild
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         heosmod:
             type: num
             denon_command@instance: info.heosmod
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         heoscnf:
             type: str
             denon_command@instance: info.heoscnf
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         heoslanguage:
             type: str
             denon_command@instance: info.heoslanguage
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         mac:
             type: str
             denon_command@instance: info.mac
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         wifimac:
             type: str
             denon_command@instance: info.wifimac
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         btmac:
             type: str
             denon_command@instance: info.btmac
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         audyif:
             type: num
             denon_command@instance: info.audyif
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         productid:
             type: num
             denon_command@instance: info.productid
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         packageid:
             type: num
             denon_command@instance: info.packageid
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         cmp:
             type: str
             denon_command@instance: info.cmp
             denon_read@instance: true
             denon_write@instance: false
-            denon_read_group@instance:
-            -   info
 
         region:
             type: str
@@ -558,6 +514,8 @@ item_structs:
             denon_write@instance: false
             denon_read_group@instance:
             -   general
+            -   custom_inputnames
+            denon_read_initial@instance: true
             cache: true
 
             reverse:
@@ -569,6 +527,11 @@ item_structs:
                     eval: sh...timer(2, {})
                     eval_trigger: '...'
 
+            update:
+                type: bool
+                enforce_updates: 'true'
+                denon_read_group_trigger: custom_inputnames
+
         power:
             type: bool
             denon_command@instance: general.power
@@ -895,11 +858,11 @@ item_structs:
                 -   zone1.control
                 denon_read_initial@instance: true
                 on_change:
-                -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                 custom_name:
                     type: str
-                    on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                    on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
             listeningmode:
                 type: str
@@ -1506,11 +1469,11 @@ item_structs:
                 -   zone2
                 -   zone2.control
                 on_change:
-                -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                 custom_name:
                     type: str
-                    on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                    on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
             sleep:
                 type: num
@@ -1735,11 +1698,11 @@ item_structs:
                 -   zone3
                 -   zone3.control
                 on_change:
-                -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                 custom_name:
                     type: str
-                    on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                    on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
         settings:
 
@@ -1877,6 +1840,8 @@ item_structs:
                 denon_read_group@instance:
                 -   ALL
                 -   ALL.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -1888,6 +1853,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -2117,11 +2087,11 @@ item_structs:
                     -   ALL.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -2569,11 +2539,11 @@ item_structs:
                     -   ALL.zone2
                     -   ALL.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num
@@ -2667,198 +2637,132 @@ item_structs:
                 denon_command@instance: info.serialnumber
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             main:
                 type: str
                 denon_command@instance: info.main
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             mainfbl:
                 type: num
                 denon_command@instance: info.mainfbl
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             dsp1:
                 type: num
                 denon_command@instance: info.dsp1
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             dsp2:
                 type: num
                 denon_command@instance: info.dsp2
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             dsp3:
                 type: num
                 denon_command@instance: info.dsp3
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             dsp4:
                 type: num
                 denon_command@instance: info.dsp4
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             apld:
                 type: num
                 denon_command@instance: info.apld
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             vpld:
                 type: num
                 denon_command@instance: info.vpld
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             guidat:
                 type: num
                 denon_command@instance: info.guidat
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             heosversion:
                 type: str
                 denon_command@instance: info.heosversion
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             heosbuild:
                 type: num
                 denon_command@instance: info.heosbuild
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             heosmod:
                 type: num
                 denon_command@instance: info.heosmod
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             heoscnf:
                 type: str
                 denon_command@instance: info.heoscnf
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             heoslanguage:
                 type: str
                 denon_command@instance: info.heoslanguage
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             mac:
                 type: str
                 denon_command@instance: info.mac
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             wifimac:
                 type: str
                 denon_command@instance: info.wifimac
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             btmac:
                 type: str
                 denon_command@instance: info.btmac
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             audyif:
                 type: num
                 denon_command@instance: info.audyif
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             productid:
                 type: num
                 denon_command@instance: info.productid
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             packageid:
                 type: num
                 denon_command@instance: info.packageid
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             cmp:
                 type: str
                 denon_command@instance: info.cmp
                 denon_read@instance: true
                 denon_write@instance: false
-                denon_read_group@instance:
-                -   AVR-X6300H
-                -   AVR-X6300H.info
 
             region:
                 type: str
@@ -2885,6 +2789,8 @@ item_structs:
                 denon_read_group@instance:
                 -   AVR-X6300H
                 -   AVR-X6300H.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -2896,6 +2802,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -3204,11 +3115,11 @@ item_structs:
                     -   AVR-X6300H.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -3776,11 +3687,11 @@ item_structs:
                     -   AVR-X6300H.zone2
                     -   AVR-X6300H.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num
@@ -4019,11 +3930,11 @@ item_structs:
                     -   AVR-X6300H.zone3
                     -   AVR-X6300H.zone3.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
             settings:
 
@@ -4166,6 +4077,8 @@ item_structs:
                 denon_read_group@instance:
                 -   AVR-X4300H
                 -   AVR-X4300H.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -4177,6 +4090,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -4406,11 +4324,11 @@ item_structs:
                     -   AVR-X4300H.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -5002,11 +4920,11 @@ item_structs:
                     -   AVR-X4300H.zone2
                     -   AVR-X4300H.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num
@@ -5245,11 +5163,11 @@ item_structs:
                     -   AVR-X4300H.zone3
                     -   AVR-X4300H.zone3.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
             settings:
 
@@ -5392,6 +5310,8 @@ item_structs:
                 denon_read_group@instance:
                 -   AVR-X3300W
                 -   AVR-X3300W.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -5403,6 +5323,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -5663,11 +5588,11 @@ item_structs:
                     -   AVR-X3300W.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -6236,11 +6161,11 @@ item_structs:
                     -   AVR-X3300W.zone2
                     -   AVR-X3300W.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num
@@ -6415,6 +6340,8 @@ item_structs:
                 denon_read_group@instance:
                 -   AVR-X2300W
                 -   AVR-X2300W.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -6426,6 +6353,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -6686,11 +6618,11 @@ item_structs:
                     -   AVR-X2300W.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -7258,11 +7190,11 @@ item_structs:
                     -   AVR-X2300W.zone2
                     -   AVR-X2300W.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num
@@ -7370,6 +7302,8 @@ item_structs:
                 denon_read_group@instance:
                 -   AVR-X1300W
                 -   AVR-X1300W.general
+                -   custom_inputnames
+                denon_read_initial@instance: true
                 cache: true
 
                 reverse:
@@ -7381,6 +7315,11 @@ item_structs:
                         eval: sh...timer(2, {})
                         eval_trigger: '...'
 
+                update:
+                    type: bool
+                    enforce_updates: 'true'
+                    denon_read_group_trigger: custom_inputnames
+
             power:
                 type: bool
                 denon_command@instance: general.power
@@ -7641,11 +7580,11 @@ item_structs:
                     -   AVR-X1300W.zone1.control
                     denon_read_initial@instance: true
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 listeningmode:
                     type: str
@@ -8129,11 +8068,11 @@ item_structs:
                     -   AVR-X1300W.zone2
                     -   AVR-X1300W.zone2.control
                     on_change:
-                    -   .custom_name = '' if sh.....general.custom_inputnames() == {} else sh.....general.custom_inputnames()[value]
+                    -   .custom_name = sh.....general.custom_inputnames().get(value, '')
 
                     custom_name:
                         type: str
-                        on_change: sh...(sh......general.custom_inputnames.reverse()[value]) if sh......general.custom_inputnames.reverse() != {} else None
+                        on_change: sh...(sh......general.custom_inputnames.reverse().get(value, ''))
 
                 sleep:
                     type: num