Efficient sensor data storage
This is one possible approach, although it does not produce exactly what you're asking for, it may be a proxy to get there:

-- Let's assume you have your data in "table_1" and "table_2"
-- They should have an index on column "time"
WITH table_1 (time, value_1) AS
(
VALUES
    ('2017-01-16 16:13:59'::timestamp, 18.9),
    ('2017-01-16 16:14:20', 17.9),
    ('2017-01-16 16:15:08', 19.9)
)
, table_2 (time, value_2) AS
(
VALUES
    ('2017-01-16 16:13:57'::timestamp, 348),
    ('2017-01-16 16:14:05', 350),
    ('2017-01-16 16:14:17', 353)
)


(I've changed "value" to "value_1" and "value_2" for ease)

At this point, we do two things: a UNION of table_1 and table_2 to get all the existing "time" values, then, for each time, make a subquery looking for the value_1 and value_2 closest in time...

-- We first make a UNION to have all present times, then, for each time a SUBQUERY, finding
-- the closest value ORDERing BY time
SELECT
    time, 
    (SELECT value_1 
       FROM table_1 
      WHERE table_1.time &lt;= times.time 
   ORDER BY time DESC 
      LIMIT 1
    ) AS value_1,
    (SELECT value_2 
       FROM table_2 
      WHERE table_2.time &lt;= times.time 
   ORDER BY time DESC 
      LIMIT 1
    ) AS value_2
FROM
    (
    SELECT "time" FROM table_1
    UNION DISTINCT
    SELECT "time" FROM table_2
    ) AS times
ORDER BY
    time ;


The result that you would get is:

|---------------------+---------+---------|
|        time         | value_1 | value_2 |
|---------------------+---------+---------|
| 2017-01-16 16:13:57 |         |   348   |
|---------------------+---------+---------|
| 2017-01-16 16:13:59 |  18.9   |   348   |
|---------------------+---------+---------|
| 2017-01-16 16:14:05 |  18.9   |   350   |
|---------------------+---------+---------|
| 2017-01-16 16:14:17 |  18.9   |   353   |
|---------------------+---------+---------|
| 2017-01-16 16:14:20 |  17.9   |   353   |
|---------------------+---------+---------|
| 2017-01-16 16:15:08 |  19.9   |   353   |
|---------------------+---------+---------|


This is probably not very efficient, but it does (more or less) what you're looking for. It requires that you have an index (DESC) on the "time" column; or the efficiency will be absolutely horrible.

If you want, you can change the "times" query by a generate_series call. It will also work. 

NOTE: value_1 on first column doesn't have a value... because we have not yet any reading. For this to work, you would need a whole set of readings at "start time".