@@ -92,6 +92,12 @@ const humidityTestCases: TestCase[] = [
9292 { name : 'No prefix - ams_ht_humidity' , entityId : 'sensor.ams_ht_humidity' , expected : '128' } ,
9393 { name : 'No prefix - ams_luftfeuchtigkeit' , entityId : 'sensor.ams_luftfeuchtigkeit' , expected : '1' } ,
9494
95+ // User-renamed AMS devices (e.g., German left/right)
96+ { name : 'Renamed AMS "links" (left)' , entityId : 'sensor.h2d_ams_links_humidity' , expected : 'links' } ,
97+ { name : 'Renamed AMS "rechts" (right)' , entityId : 'sensor.h2d_ams_rechts_humidity' , expected : 'rechts' } ,
98+ { name : 'Renamed AMS "left"' , entityId : 'sensor.h2d_ams_left_humidity' , expected : 'left' } ,
99+ { name : 'Renamed AMS "right"' , entityId : 'sensor.h2d_ams_right_humidity' , expected : 'right' } ,
100+
95101 // Edge cases - should NOT match
96102 { name : 'Invalid - no ams' , entityId : 'sensor.x1c_humidity' , expected : null } ,
97103 { name : 'Invalid - wrong type' , entityId : 'sensor.x1c_ams_1_temperature' , expected : null } ,
@@ -159,6 +165,11 @@ const trayTestCases: TrayTestCase[] = [
159165 { name : 'No prefix - ams_ht_tray_2' , entityId : 'sensor.ams_ht_tray_2' , expected : { amsNumber : '128' , trayNumber : 2 } } ,
160166 { name : 'No prefix - ams_slot_1 German' , entityId : 'sensor.ams_slot_1' , expected : { amsNumber : '1' , trayNumber : 1 } } ,
161167
168+ // User-renamed AMS devices (e.g., German left/right)
169+ { name : 'Renamed AMS "links" Tray 1' , entityId : 'sensor.h2d_ams_links_tray_1' , expected : { amsNumber : 'links' , trayNumber : 1 } } ,
170+ { name : 'Renamed AMS "rechts" Tray 4' , entityId : 'sensor.h2d_ams_rechts_tray_4' , expected : { amsNumber : 'rechts' , trayNumber : 4 } } ,
171+ { name : 'Renamed AMS "links" Slot 2' , entityId : 'sensor.h2d_ams_links_slot_2' , expected : { amsNumber : 'links' , trayNumber : 2 } } ,
172+
162173 // Edge cases - should NOT match
163174 { name : 'Invalid - no tray number' , entityId : 'sensor.x1c_ams_1_tray' , expected : null } ,
164175 { name : 'Invalid - humidity not tray' , entityId : 'sensor.x1c_ams_1_humidity' , expected : null } ,
@@ -875,6 +886,97 @@ test('H2D: All entities from issue #45 are discovered', () => {
875886 assertEqual ( externalCount , 1 ) ;
876887} ) ;
877888
889+ // =============================================================================
890+ // User-Renamed AMS Devices (GitHub Issue #47 - Somaxax)
891+ // =============================================================================
892+
893+ console . log ( '\n=== User-Renamed AMS Devices (GitHub Issue #47 - Somaxax) ===\n' ) ;
894+
895+ // Somaxax's H2D entity list from issue #47 — AMS devices renamed to "links"/"rechts"
896+ const somaxaxEntities = [
897+ 'sensor.h2d_ams_links_humidity' ,
898+ 'sensor.h2d_ams_links_humidity_index' ,
899+ 'sensor.h2d_ams_links_remaining_drying_time' ,
900+ 'sensor.h2d_ams_links_temperature' ,
901+ 'sensor.h2d_ams_links_tray_1' ,
902+ 'sensor.h2d_ams_links_tray_2' ,
903+ 'sensor.h2d_ams_links_tray_3' ,
904+ 'sensor.h2d_ams_links_tray_4' ,
905+ 'sensor.h2d_ams_rechts_humidity' ,
906+ 'sensor.h2d_ams_rechts_humidity_index' ,
907+ 'sensor.h2d_ams_rechts_remaining_drying_time' ,
908+ 'sensor.h2d_ams_rechts_temperature' ,
909+ 'sensor.h2d_ams_rechts_tray_1' ,
910+ 'sensor.h2d_ams_rechts_tray_2' ,
911+ 'sensor.h2d_ams_rechts_tray_3' ,
912+ 'sensor.h2d_ams_rechts_tray_4' ,
913+ 'sensor.h2d_externalspool_external_spool' ,
914+ 'sensor.h2d_externalspool2_external_spool' ,
915+ ] ;
916+
917+ test ( 'Somaxax H2D: "links" AMS humidity detected' , ( ) => {
918+ assertEqual ( matchAmsHumidityEntity ( 'sensor.h2d_ams_links_humidity' ) , 'links' ) ;
919+ } ) ;
920+
921+ test ( 'Somaxax H2D: "rechts" AMS humidity detected' , ( ) => {
922+ assertEqual ( matchAmsHumidityEntity ( 'sensor.h2d_ams_rechts_humidity' ) , 'rechts' ) ;
923+ } ) ;
924+
925+ test ( 'Somaxax H2D: Non-humidity sensors should NOT match' , ( ) => {
926+ assertEqual ( matchAmsHumidityEntity ( 'sensor.h2d_ams_links_humidity_index' ) , null ) ;
927+ assertEqual ( matchAmsHumidityEntity ( 'sensor.h2d_ams_links_remaining_drying_time' ) , null ) ;
928+ assertEqual ( matchAmsHumidityEntity ( 'sensor.h2d_ams_links_temperature' ) , null ) ;
929+ } ) ;
930+
931+ test ( 'Somaxax H2D: All 4 "links" trays detected' , ( ) => {
932+ for ( let i = 1 ; i <= 4 ; i ++ ) {
933+ const result = matchTrayEntity ( `sensor.h2d_ams_links_tray_${ i } ` ) ;
934+ if ( ! result ) throw new Error ( `Tray ${ i } not detected` ) ;
935+ assertEqual ( result . amsNumber , 'links' ) ;
936+ assertEqual ( result . trayNumber , i ) ;
937+ }
938+ } ) ;
939+
940+ test ( 'Somaxax H2D: All 4 "rechts" trays detected' , ( ) => {
941+ for ( let i = 1 ; i <= 4 ; i ++ ) {
942+ const result = matchTrayEntity ( `sensor.h2d_ams_rechts_tray_${ i } ` ) ;
943+ if ( ! result ) throw new Error ( `Tray ${ i } not detected` ) ;
944+ assertEqual ( result . amsNumber , 'rechts' ) ;
945+ assertEqual ( result . trayNumber , i ) ;
946+ }
947+ } ) ;
948+
949+ test ( 'Somaxax H2D: "links" and "rechts" do not collide' , ( ) => {
950+ const links = matchAmsHumidityEntity ( 'sensor.h2d_ams_links_humidity' ) ;
951+ const rechts = matchAmsHumidityEntity ( 'sensor.h2d_ams_rechts_humidity' ) ;
952+ if ( links === rechts ) throw new Error ( 'links and rechts should have different AMS identifiers' ) ;
953+ } ) ;
954+
955+ test ( 'Somaxax H2D: External spools detected' , ( ) => {
956+ assertEqual ( matchExternalSpoolEntity ( 'sensor.h2d_externalspool_external_spool' ) , true ) ;
957+ assertEqual ( matchExternalSpoolEntity ( 'sensor.h2d_externalspool2_external_spool' ) , true ) ;
958+ } ) ;
959+
960+ test ( 'Somaxax H2D: buildTrayPattern works with non-numeric amsNumber' , ( ) => {
961+ const pattern = buildTrayPattern ( 'h2d' , 'links' , 1 ) ;
962+ const match = 'sensor.h2d_ams_links_tray_1' . match ( pattern ) ;
963+ if ( ! match ) throw new Error ( 'buildTrayPattern should match renamed AMS tray' ) ;
964+ } ) ;
965+
966+ test ( 'Somaxax H2D: All entities from issue #47 are discovered' , ( ) => {
967+ let humidityCount = 0 ;
968+ let trayCount = 0 ;
969+ let externalCount = 0 ;
970+ for ( const entity of somaxaxEntities ) {
971+ if ( matchAmsHumidityEntity ( entity ) ) humidityCount ++ ;
972+ if ( matchTrayEntity ( entity ) ) trayCount ++ ;
973+ if ( matchExternalSpoolEntity ( entity ) ) externalCount ++ ;
974+ }
975+ assertEqual ( humidityCount , 2 ) ; // links + rechts
976+ assertEqual ( trayCount , 8 ) ; // 4 links trays + 4 rechts trays
977+ assertEqual ( externalCount , 2 ) ; // externalspool + externalspool2
978+ } ) ;
979+
878980// =============================================================================
879981// Summary
880982// =============================================================================
0 commit comments