Nested aggregate functions over different dimensions
Query
You can use generate_series() to generate a time raster to join to:
SELECT g AS ts_interval, host, sum(recv_bytes) AS recv_bytes
FROM  (
   SELECT g, host, interface, avg(recv_bytes) AS recv_bytes
   FROM   generate_series(timestamptz '2017-01-01 00:00:00+00'
                        , timestamptz '2017-01-01 00:00:10+00'  -- 10 - only lower bound
                        , interval '10 sec') g
   JOIN   net n ON ts &gt;= g
               AND ts &lt;  g + interval '10 sec'
   GROUP  BY g, host, interface
   ) sub
GROUP  BY g, host
ORDER  BY g, host;

Same result. Not less verbose, but much faster if you have an index on (ts).
Then again, the crucial point is to have &quot;sargable&quot; predicates, which you also get without generate_series() this way:
SELECT ts_interval, host, sum(recv_bytes) as recv_bytes
FROM  (
   SELECT to_timestamp(trunc(extract(epoch from ts) / 10) * 10) AS ts_interval
        , host, interface, avg(recv_bytes) as recv_bytes
   FROM   net
   WHERE  ts &gt;= '2017-01-01 00:00:00+00'
   AND    ts &lt;  '2017-01-01 00:00:20+00' -- just make sure to match bounds
   GROUP  BY 1, 2, 3
   ) avg_net
GROUP  BY 1, 2
ORDER  BY 1, 2;

Minor point: With exclusively positive numbers, trunc() is equivalent to floor() and a bit faster.
I am using ordinal numbers, since you asked for &quot;less verbose&quot; code. But that's not the core of the question here ...
Core question
You can run a window function over an aggregate function in one query level (though it's not typically faster than using a subquery).
But not the other way round: you cannot run an aggregate function over a window function in one query level. Just not possible. Window functions happen after aggregate functions in SQL.
Related:

Best way to get result count before LIMIT was applied
How do I get the aggregate of a window function in Postgres?
Return total number of rows and selected (aggregated) data
How will the order of operations in this query affect my results?