This will not explain your problems, but it will show you a positive example with a good performance, so you can compare it with your case.
Test Data
-- 18 silos
insert into silo (ID, NAME)
select rownum id, 'S'||rownum name from dual connect by level <= 18;
-- 20 devices per silo, total 360
insert into HANGINGTHREAD_SILO (DEVICES_ID, ID_SILO)
select  rownum DEVICES_ID, 1+trunc((rownum-1)/20) ID_SILO  from dual connect by level <= 18*20;
insert into IOT_DEVICES(ID, NAME, ORGANIZATION, OUTGUID)
select rownum ID, 'P'||rownum NAME, 1 ORGANIZATION,  rownum OUTGUID from dual connect by level <= 18*20;
-- 100 sensors per device, total 36.0000
insert into SILO_SENSOR(ID, NAME, DEVICES_ID)
select rownum ID, 'SENSOR_'||rownum NAME,   1+trunc((rownum-1)/100) DEVICES_ID from dual connect by level <= 18*20*100;
-- 1000 trans_id per sensor, total 36.000.000 rows
insert into TEMPR_SILO(NAME, TEMP, ID_TRANS)
with temp as (select rownum TEMP, rownum ID_TRANS from dual connect by level <= 1000)
select s.NAME, temp.TEMP, temp.ID_TRANS from SILO_SENSOR s
cross join temp;
The only index you need is on the table TEMPR_SILO to support the access for the last ID_TRANS
create index TEMPR_SILO_IDX1 on TEMPR_SILO(ID_TRANS, NAME, TEMP);
The query returns the 360 rows in a subseconds elapsed time (see A-Time= actual time) in the plan below
 SELECT /*+ gather_plan_statistics */
    TYP.NAME   AS SILO_NAME,
    TR.OUTGUID,
    TR.NAME    AS DEV_NAME,
    TR.id,
    TYP.ORGANIZATION as ID_ORG,
    rt.name as ORGANIZATION,
   MAX(TS.TEMP) AS MAX_TEMP,
   MIN(NS.TEMP) AS MIN_TEMP 
FROM
    HANGINGTHREAD_SILO EV
    LEFT JOIN SILO TYP ON EV.ID_SILO = TYP.ID 
    LEFT JOIN IOT_DEVICES TR ON EV.DEVICES_ID = TR.ID  
    LEFT JOIN SILO_SENSOR SS ON SS.DEVICES_ID = TR.OUTGUID
    LEFT JOIN TEMPR_SILO TS ON TS.NAME = SS.NAME
    LEFT JOIN TEMPR_SILO NS ON NS.NAME = SS.NAME
    LEFT JOIN ORGANIZATIONS rt ON rt.id = TR.ORGANIZATION  
where TS.ID_TRANS IN (
        SELECT
            MAX(ID_TRANS)
        FROM
            TEMPR_SILO 
    ) and NS.ID_TRANS IN (
        SELECT
            MIN(ID_TRANS)
        FROM
            TEMPR_SILO 
    )
GROUP BY
    EV.ID,
    TYP.NAME,
    TR.OUTGUID,
     TR.id,
      TYP.ORGANIZATION,
       rt.name,
    TR.NAME;
You get the plan and statistics from the above query right after the execution with the query
select * from table(dbms_xplan.display_cursor(null,null,'ALLSTATS LAST'));   
that returns
----------------------------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                          | Name               | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
----------------------------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT                   |                    |      1 |        |    360 |00:00:00.17 |    7792 |       |       |          |
|   1 |  HASH GROUP BY                     |                    |      1 |      1 |    360 |00:00:00.17 |    7792 |   888K|   888K| 1390K (0)|
|*  2 |   HASH JOIN OUTER                  |                    |      1 |      1 |  36000 |00:00:00.15 |    7792 |  3649K|  1579K| 4273K (0)|
|*  3 |    HASH JOIN                       |                    |      1 |      1 |  36000 |00:00:00.13 |    7785 |  3476K|  1686K| 4337K (0)|
|*  4 |     HASH JOIN OUTER                |                    |      1 |      1 |  36000 |00:00:00.12 |    7778 |  3458K|  1730K| 3695K (0)|
|*  5 |      HASH JOIN                     |                    |      1 |      1 |  36000 |00:00:00.10 |    7771 |  3339K|  2324K| 3320K (0)|
|   6 |       NESTED LOOPS                 |                    |      1 |      1 |  36000 |00:00:00.10 |    7764 |       |       |          |
|*  7 |        HASH JOIN                   |                    |      1 |      1 |  36000 |00:00:00.03 |     332 |  3385K|  2007K| 2553K (0)|
|*  8 |         INDEX RANGE SCAN           | TEMPR_SILO_IDX1    |      1 |      1 |  36000 |00:00:00.01 |     157 |       |       |          |
|   9 |          SORT AGGREGATE            |                    |      1 |      1 |      1 |00:00:00.01 |       4 |       |       |          |
|  10 |           INDEX FULL SCAN (MIN/MAX)| TEMPR_SILO_IDX1    |      1 |      1 |      1 |00:00:00.01 |       4 |       |       |          |
|  11 |         TABLE ACCESS FULL          | SILO_SENSOR        |      1 |  24745 |  36000 |00:00:00.01 |     175 |       |       |          |
|* 12 |        INDEX RANGE SCAN            | TEMPR_SILO_IDX1    |  36000 |      1 |  36000 |00:00:00.05 |    7432 |       |       |          |
|  13 |         SORT AGGREGATE             |                    |      1 |      1 |      1 |00:00:00.01 |       4 |       |       |          |
|  14 |          INDEX FULL SCAN (MIN/MAX) | TEMPR_SILO_IDX1    |      1 |      1 |      1 |00:00:00.01 |       4 |       |       |          |
|  15 |       TABLE ACCESS FULL            | IOT_DEVICES        |      1 |    360 |    360 |00:00:00.01 |       7 |       |       |          |
|  16 |      TABLE ACCESS FULL             | ORGANIZATIONS      |      1 |      1 |      1 |00:00:00.01 |       7 |       |       |          |
|  17 |     TABLE ACCESS FULL              | HANGINGTHREAD_SILO |      1 |    360 |    360 |00:00:00.01 |       7 |       |       |          |
|  18 |    TABLE ACCESS FULL               | SILO               |      1 |     18 |     18 |00:00:00.01 |       7 |       |       |          |
----------------------------------------------------------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("EV"."ID_SILO"="TYP"."ID")
   3 - access("EV"."DEVICES_ID"="TR"."ID")
   4 - access("RT"."ID"="TR"."ORGANIZATION")
   5 - access("SS"."DEVICES_ID"="TR"."OUTGUID")
   7 - access("TS"."NAME"="SS"."NAME")
   8 - access("TS"."ID_TRANS"=)
  12 - access("NS"."ID_TRANS"= AND "NS"."NAME"="SS"."NAME")
Some Discussion
Your query is more an analytic than an OLTP, so don't care much about indexes, you scan in the most tables full data, so full table scan and hash join are OK.
The only exception is the TEMPR_SILO where you have lot of ID_TRANS and you need only the last one. Here helps index, but partitioning on the ID_TRANS may be even better.
You typically do not wan't to see in the execution plan for such queries a mixture of hash joins and nested loops (which is what you observe) - this may be an indication that your object statistics are not up to date.
It seems that your outer join to the table TEMPR_SILO is meaningless as you overide it to an inner join with the where condition
where TS.ID_TRANS IN (SELECT MAX(ID_TRANS) FROM TEMPR_SILO)
even worst you use the exact same where condition for the joins to tsand ns - you get therefore the exact same result in both joins. Please check if this is a typo and either modify the where condition or remove one join.
Last but not least - to post explain plans as image is suboptimal as you mostly post only part of the information (e.g. predicate information is missing). Pls check th elink in my comment how to get execution plan in a text form.