diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
index ed10c3b40559003610fb2ff20702fcc3b014690b..e205348f4a9e392b952760fb525d084c284033a6 100755
--- a/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/ObservationBean.java
@@ -29,18 +29,9 @@ import java.nio.file.Files;
 import java.nio.file.Paths;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Calendar;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.Map.Entry;
-import java.util.ResourceBundle;
-import java.util.Set;
+import java.util.function.Function;
 import java.util.stream.Collectors;
 import javax.ejb.EJB;
 import javax.ejb.Stateless;
@@ -78,6 +69,9 @@ public class ObservationBean {
     @EJB
     UserBean userBean;
 
+    @EJB
+    ObservationTimeSeriesBean observationTimeSeriesBean;
+
     public List<Observation> getObservations(Integer organizationId) {
         Organization organization = em.find(Organization.class, organizationId);
         List<Observation> observations = em.createNamedQuery("Observation.findByOrganizationId")
@@ -508,6 +502,30 @@ public class ObservationBean {
         return observations;
     }
 
+    public List<Observation> getObservationsWithTimeSeries(List<Observation> observations) {
+        Set<Integer> observationTimeSeriesIds = observations.stream()
+                .map(Observation::getObservationTimeSeriesId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+        if (observationTimeSeriesIds.isEmpty()) {
+            return observations;
+        }
+
+        List<ObservationTimeSeries> timeSeriesList = observationTimeSeriesBean.getObservationTimeSeriesList(observationTimeSeriesIds);
+        Map<Integer, ObservationTimeSeries> timeSeriesMap = timeSeriesList.stream()
+                .collect(Collectors.toMap(ObservationTimeSeries::getObservationTimeSeriesId, Function.identity()));
+
+        observations.stream()
+                .filter(o -> o.getObservationTimeSeriesId() != null)
+                .forEach(o -> o.setObservationTimeSeries(timeSeriesMap.get(o.getObservationTimeSeriesId())));
+
+        for (Observation o : observations) {
+            LOGGER.info("{}", o);
+        }
+
+        return observations;
+    }
     private List<Observation> getObservationsWithObservers(List<Observation> observations) {
         Set<Integer> userIds = new HashSet<>();
         observations.stream().filter((o) -> (o.getUserId() != null)).forEach((o) -> {
@@ -555,13 +573,13 @@ public class ObservationBean {
 
     public List<Observation> getFilteredObservations(
             Integer organizationId,
+            Integer observationTimeSeriesId,
             Integer pestId,
             Integer cropId,
             List<Integer> cropCategoryId,
             Date from,
             Date to,
-            Boolean isPositive
-    ) {
+            Boolean isPositive) {
         // The minimum SQL
         String sql = "SELECT * FROM public.observation \n" +
                 "WHERE status_type_id = :statusTypeId \n " +
@@ -571,6 +589,11 @@ public class ObservationBean {
         parameters.put("statusTypeId", ObservationStatusType.STATUS_APPROVED);
         parameters.put("organizationId", organizationId);
 
+        // Filter for observation time series
+        if (observationTimeSeriesId != null && observationTimeSeriesId > 0) {
+            sql += "AND observation_time_series_id = :observationTimeSeriesId \n";
+            parameters.put("observationTimeSeriesId", observationTimeSeriesId);
+        }
         // Filter for pest
         if (pestId != null && pestId > 0) {
             sql += "AND organism_id = :organismId \n";
@@ -637,11 +660,10 @@ public class ObservationBean {
             //start = new Date();
             retVal = this.getObservationsWithLocations(retVal);
             //System.out.println("Finding locations took " + (new Date().getTime() - start.getTime()) + " milliseconds");
+            retVal = this.getObservationsWithTimeSeries(retVal);
         }
 
-
         return retVal;
-
     }
 
     public List<Organism> getObservedPests(Integer organizationId) {
diff --git a/src/main/java/no/nibio/vips/logic/controller/session/ObservationTimeSeriesBean.java b/src/main/java/no/nibio/vips/logic/controller/session/ObservationTimeSeriesBean.java
index eb1ff5752e4d1eff1a37f6809dc23631409f396b..9f11580789bd659f6df481824248564746e2bbb8 100644
--- a/src/main/java/no/nibio/vips/logic/controller/session/ObservationTimeSeriesBean.java
+++ b/src/main/java/no/nibio/vips/logic/controller/session/ObservationTimeSeriesBean.java
@@ -18,15 +18,14 @@
 
 package no.nibio.vips.logic.controller.session;
 
-import no.nibio.vips.logic.entity.ObservationTimeSeries;
-import no.nibio.vips.logic.entity.PointOfInterest;
-import no.nibio.vips.logic.entity.VipsLogicUser;
-
+import java.util.*;
 import javax.ejb.EJB;
 import javax.ejb.Stateless;
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
-import java.util.*;
+import no.nibio.vips.logic.entity.ObservationTimeSeries;
+import no.nibio.vips.logic.entity.PointOfInterest;
+import no.nibio.vips.logic.entity.VipsLogicUser;
 
 @Stateless
 public class ObservationTimeSeriesBean {
@@ -49,8 +48,13 @@ public class ObservationTimeSeriesBean {
         return resultList;
     }
 
-    public ObservationTimeSeries getObservationTimeSeries(Integer id) {
-        ObservationTimeSeries ots = em.find(ObservationTimeSeries.class, id);
+    /**
+     * Get observation time series with given id. Enrich object with user information before returning.
+     * @param observationTimeSeriesId the id of the observation time series to retrieve
+     * @return the observation time series with the given id
+     */
+    public ObservationTimeSeries getObservationTimeSeries(Integer observationTimeSeriesId) {
+        ObservationTimeSeries ots = em.find(ObservationTimeSeries.class, observationTimeSeriesId);
         if (ots != null) {
             ots.setUser(em.find(VipsLogicUser.class, ots.getUserId()));
             if (ots.getLastModifiedBy() != null) {
@@ -60,6 +64,12 @@ public class ObservationTimeSeriesBean {
         return ots;
     }
 
+    public List<ObservationTimeSeries> getObservationTimeSeriesList(Set<Integer> observationTimeSeriesIds) {
+        return em.createNamedQuery("ObservationTimeSeries.findByObservationTimeSeriesIds")
+                .setParameter("observationTimeSeriesIds", observationTimeSeriesIds)
+                .getResultList();
+    }
+
     /**
      * @param ots the observation time series
      * @return The merged object
diff --git a/src/main/java/no/nibio/vips/logic/entity/Observation.java b/src/main/java/no/nibio/vips/logic/entity/Observation.java
index b0b092d053042e9187d30be2022dd9108e84cc7f..241e0c14ad16f334804c251a2f47dc698315c2f1 100755
--- a/src/main/java/no/nibio/vips/logic/entity/Observation.java
+++ b/src/main/java/no/nibio/vips/logic/entity/Observation.java
@@ -558,6 +558,11 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         this.observationIllustrationSet = observationIllustrationSet;
     }
 
+    @Transient
+    public Integer getObservationTimeSeriesId() {
+        return observationTimeSeries != null ? observationTimeSeries.getObservationTimeSeriesId() : null;
+    }
+
     /**
       * @return the observation time series
      */
@@ -686,11 +691,13 @@ public class Observation implements Serializable, no.nibio.vips.observation.Obse
         }
         return new ObservationListItem(
                 this.getObservationId(),
+                this.getObservationTimeSeriesId(),
                 this.getTimeOfObservation(),
                 this.getOrganismId(),
                 ! this.getOrganism().getLocalName(locale).trim().isBlank() ? this.getOrganism().getLocalName(locale) : this.getOrganism().getLatinName(),
                 this.getCropOrganismId(),
                 ! this.getCropOrganism().getLocalName(locale).trim().isBlank() ? this.getCropOrganism().getLocalName(locale) : this.getCropOrganism().getLatinName(),
+                this.observationTimeSeries != null ? this.observationTimeSeries.getLabel() : null,
                 // Specific geoInfo trumps location. This is to be interpreted 
                 // as that the observation has been geographically masked by
                 // choice of the observer
diff --git a/src/main/java/no/nibio/vips/logic/entity/ObservationTimeSeries.java b/src/main/java/no/nibio/vips/logic/entity/ObservationTimeSeries.java
index b222732163440a174fb531b8d86a2fcfc4dd4ec4..d7adac276d965c3bae93528548e0128be8b5c0f3 100644
--- a/src/main/java/no/nibio/vips/logic/entity/ObservationTimeSeries.java
+++ b/src/main/java/no/nibio/vips/logic/entity/ObservationTimeSeries.java
@@ -35,6 +35,7 @@ import java.util.Date;
 @NamedQueries({
         @NamedQuery(name = "ObservationTimeSeries.findAll", query = "SELECT ots FROM ObservationTimeSeries ots"),
         @NamedQuery(name = "ObservationTimeSeries.findByObservationTimeSeriesId", query = "SELECT ots FROM ObservationTimeSeries ots WHERE ots.observationTimeSeriesId = :id"),
+        @NamedQuery(name = "ObservationTimeSeries.findByObservationTimeSeriesIds", query = "SELECT ots FROM ObservationTimeSeries ots WHERE ots.observationTimeSeriesId IN :observationTimeSeriesIds"),
         @NamedQuery(name = "ObservationTimeSeries.findByOrganizationId", query = "SELECT ots FROM ObservationTimeSeries ots WHERE ots.userId IN(SELECT v.userId FROM VipsLogicUser v WHERE v.organizationId = :organizationId OR  v.organizationId IN(SELECT o.organizationId FROM Organization o WHERE o.parentOrganizationId = :organizationId))"),
         @NamedQuery(name = "ObservationTimeSeries.findByUserId", query = "SELECT ots FROM ObservationTimeSeries ots WHERE ots.userId IN(:userId)")
 })
@@ -163,6 +164,21 @@ public class ObservationTimeSeries implements Serializable {
         this.name = name;
     }
 
+    /**
+     * This logic if also implemented in the observation app, see the function timeSeriesLabel in CommonUtil.vue
+     * @return the first eight letters of the given name, in uppercase with spaces removed
+     */
+    @Transient
+    public String getLabel() {
+        if (this.name == null) {
+            return null;
+        }
+        String timeSeriesName = this.name;
+        timeSeriesName = timeSeriesName.replaceAll("\\s", "");
+        timeSeriesName = timeSeriesName.substring(0, Math.min(timeSeriesName.length(), 8));
+        return timeSeriesName.toUpperCase();
+    }
+
     /**
      * @return the description of the observation time series
      */
diff --git a/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
index 51c5a348f92692caab202fe87a1a49ea7c705d54..a4dd12f901526bfda95fb6c5edadc1c793218772 100644
--- a/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
+++ b/src/main/java/no/nibio/vips/logic/entity/rest/ObservationListItem.java
@@ -27,9 +27,10 @@ import no.nibio.vips.observationdata.ObservationDataSchema;
  * @author Tor-Einar Skog <tor-einar.skog@nibio.no>
  */
 public class ObservationListItem implements Comparable{
-    private Integer observationId, organismId, cropOrganismId;
+    private Integer observationId, observationTimeSeriesId, organismId, cropOrganismId;
     private Date timeOfObservation;
     private String organismName, cropOrganismName;
+    private String observationTimeSeriesLabel;
     private String geoInfo;
     private String observationHeading;
     private String observationData;
@@ -40,11 +41,13 @@ public class ObservationListItem implements Comparable{
 
     public ObservationListItem(
             Integer observationId,
+            Integer observationTimeSeriesId,
             Date timeOfObservation,
             Integer organismId,
             String organismName,
             Integer cropOrganismId,
             String cropOrganismName,
+            String observationTimeSeriesLabel,
             String geoinfo,
             String observationHeading,
             Boolean broadcastMessage,
@@ -54,11 +57,13 @@ public class ObservationListItem implements Comparable{
             ObservationDataSchema observationDataSchema
     ){
         this.observationId = observationId;
+        this.observationTimeSeriesId = observationTimeSeriesId;
         this.timeOfObservation = timeOfObservation;
         this.organismId = organismId;
         this.organismName = organismName;
         this.cropOrganismId = cropOrganismId;
         this.cropOrganismName = cropOrganismName;
+        this.observationTimeSeriesLabel = observationTimeSeriesLabel;
         this.geoInfo = geoinfo;
         this.observationHeading = observationHeading;
         this.broadcastMessage = broadcastMessage;
@@ -93,6 +98,20 @@ public class ObservationListItem implements Comparable{
         this.observationId = observationId;
     }
 
+    /**
+     * @return the observationTimeSeriesId
+     */
+    public Integer getObservationTimeSeriesId() {
+        return observationTimeSeriesId;
+    }
+
+    /**
+     * @param observationTimeSeriesId the observationTimeSeriesId to set
+     */
+    public void setObservationTimeSeriesId(Integer observationTimeSeriesId) {
+        this.observationTimeSeriesId = observationTimeSeriesId;
+    }
+
     /**
      * @return the timeOfObservation
      */
@@ -135,6 +154,14 @@ public class ObservationListItem implements Comparable{
         this.cropOrganismName = cropOrganismName;
     }
 
+    public String getObservationTimeSeriesLabel() {
+        return observationTimeSeriesLabel;
+    }
+
+    public void setObservationTimeSeriesLabel(String observationTimeSeriesLabel) {
+        this.observationTimeSeriesLabel = observationTimeSeriesLabel;
+    }
+
     /**
      * @return the geoInfo
      */
diff --git a/src/main/java/no/nibio/vips/logic/service/ObservationService.java b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
index ba9704572df2336831fff1d303ca1c5ae9e3d015..57382908126aae8fcc0d164bc18a8e298640b270 100755
--- a/src/main/java/no/nibio/vips/logic/service/ObservationService.java
+++ b/src/main/java/no/nibio/vips/logic/service/ObservationService.java
@@ -109,6 +109,7 @@ public class ObservationService {
     @TypeHint(Observation[].class)
     public Response getFilteredObservations(
             @PathParam("organizationId") Integer organizationId,
+            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
             @QueryParam("pestId") Integer pestId,
             @QueryParam("cropId") Integer cropId,
             @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
@@ -118,6 +119,7 @@ public class ObservationService {
     ) {
         return Response.ok().entity(getFilteredObservationsFromBackend(
                 organizationId,
+                observationTimeSeriesId,
                 pestId,
                 cropId,
                 cropCategoryId,
@@ -143,6 +145,7 @@ public class ObservationService {
     @TypeHint(ObservationListItem.class)
     public Response getFilteredObservationListItemsAsJson(
             @PathParam("organizationId") Integer organizationId,
+            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
             @QueryParam("pestId") Integer pestId,
             @QueryParam("cropId") Integer cropId,
             @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
@@ -152,11 +155,12 @@ public class ObservationService {
             @QueryParam("locale") String localeStr,
             @QueryParam("isPositive") Boolean isPositive
     ) {
-        return Response.ok().entity(this.getFilteredObservationListItems(organizationId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive)).build();
+        return Response.ok().entity(this.getFilteredObservationListItems(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive)).build();
     }
 
     private List<ObservationListItem> getFilteredObservationListItems(
             Integer organizationId,
+            Integer observationTimeSeriesId,
             Integer pestId,
             Integer cropId,
             List<Integer> cropCategoryId,
@@ -164,8 +168,7 @@ public class ObservationService {
             String toStr,
             String userUUID,
             String localeStr,
-            Boolean isPositive
-    ) {
+            Boolean isPositive) {
         VipsLogicUser user = (VipsLogicUser) httpServletRequest.getSession().getAttribute("user");
 
         if (user == null && userUUID != null) {
@@ -178,6 +181,7 @@ public class ObservationService {
         LOGGER.info("Get filtered observations for user {}", user != null ? user.getUserId() : "<no user>");
         List<ObservationListItem> observations = getFilteredObservationsFromBackend(
                 organizationId,
+                observationTimeSeriesId,
                 pestId,
                 cropId,
                 cropCategoryId,
@@ -219,6 +223,7 @@ public class ObservationService {
     @TypeHint(ObservationListItem.class)
     public Response getFilteredObservationListItemsAsCSV(
             @PathParam("organizationId") Integer organizationId,
+            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
             @QueryParam("pestId") Integer pestId,
             @QueryParam("cropId") Integer cropId,
             @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
@@ -228,7 +233,7 @@ public class ObservationService {
             @QueryParam("locale") String localeStr,
             @QueryParam("isPositive") Boolean isPositive
     ) {
-        List<ObservationListItem> observations = this.getFilteredObservationListItems(organizationId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive);
+        List<ObservationListItem> observations = this.getFilteredObservationListItems(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, userUUID, localeStr, isPositive);
         Collections.sort(observations);
         String retVal = "ObservationID;organismName;cropOrganismName;timeOfObservation;lat/lon;observationHeading;observationData";
         GISUtil gisUtil = new GISUtil();
@@ -251,23 +256,24 @@ public class ObservationService {
     }
 
     /**
-     * @param organizationId Database ID of the organization
-     * @param pestId         Database ID of the pest
-     * @param cropId         Database ID of the crop
-     * @param cropCategoryId cropCategoryId Database IDs of the crop category/categories
-     * @param fromStr        format "yyyy-MM-dd"
-     * @param toStr          format "yyyy-MM-dd"
+     * @param organizationId          Database ID of the organization
+     * @param observationTimeSeriesId Database ID of the observation time series
+     * @param pestId                  Database ID of the pest
+     * @param cropId                  Database ID of the crop
+     * @param cropCategoryId          cropCategoryId Database IDs of the crop category/categories
+     * @param fromStr                 format "yyyy-MM-dd"
+     * @param toStr                   format "yyyy-MM-dd"
      * @return Observation objects for which the user is authorized to observe with properties relevant for lists
      */
     private List<Observation> getFilteredObservationsFromBackend(
             Integer organizationId,
+            Integer observationTimeSeriesId,
             Integer pestId,
             Integer cropId,
             List<Integer> cropCategoryId,
             String fromStr,
             String toStr,
-            Boolean isPositive
-    ) {
+            Boolean isPositive) {
         SimpleDateFormat format = new SimpleDateFormat(Globals.defaultDateFormat);
         //TODO Set correct timeZone!!!
         Date from = null;
@@ -281,6 +287,7 @@ public class ObservationService {
 
         return observationBean.getFilteredObservations(
                 organizationId,
+                observationTimeSeriesId,
                 pestId,
                 cropId,
                 cropCategoryId,
@@ -405,6 +412,7 @@ public class ObservationService {
     @TypeHint(GeoJSON.class)
     public Response getFilteredObservationsAsGeoJSON(
             @PathParam("organizationId") Integer organizationId,
+            @QueryParam("observationTimeSeriesId") Integer observationTimeSeriesId,
             @QueryParam("pestId") Integer pestId,
             @QueryParam("cropId") Integer cropId,
             @QueryParam("cropCategoryId") List<Integer> cropCategoryId,
@@ -426,6 +434,7 @@ public class ObservationService {
 
         List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(
                 organizationId,
+                observationTimeSeriesId,
                 pestId,
                 cropId,
                 cropCategoryId,
@@ -758,6 +767,7 @@ public class ObservationService {
 
     /**
      * @param organizationId Database id of the organization
+     * @param observationTimeSeriesId Database id of the observation time series
      * @param pestId         Database id of the pest
      * @param cropId         Database id of the crop
      * @param cropCategoryId Database ids of the crop categories
@@ -768,6 +778,7 @@ public class ObservationService {
      */
     private List<Observation> getFilteredObservationsFromBackend(
             Integer organizationId,
+            Integer observationTimeSeriesId,
             Integer pestId,
             Integer cropId,
             List<Integer> cropCategoryId,
@@ -776,7 +787,7 @@ public class ObservationService {
             Boolean isPositive,
             VipsLogicUser user
     ) {
-        List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(organizationId, pestId, cropId, cropCategoryId, fromStr, toStr, isPositive);
+        List<Observation> filteredObservations = this.getFilteredObservationsFromBackend(organizationId, observationTimeSeriesId, pestId, cropId, cropCategoryId, fromStr, toStr, isPositive);
 
         // If superuser or orgadmin: Return everything, unchanged, uncensored
         if (user != null && (user.isSuperUser() || user.isOrganizationAdmin())) {
diff --git a/src/main/java/no/nibio/vips/logic/service/ObservationTimeSeriesService.java b/src/main/java/no/nibio/vips/logic/service/ObservationTimeSeriesService.java
index 643e0ea134d665a8fd6fe14e85366c2c333ffdf4..3d428239d30a2104f26008039d5173f0d150ce8c 100644
--- a/src/main/java/no/nibio/vips/logic/service/ObservationTimeSeriesService.java
+++ b/src/main/java/no/nibio/vips/logic/service/ObservationTimeSeriesService.java
@@ -107,15 +107,14 @@ public class ObservationTimeSeriesService {
         if (requester == null && userUUID != null) {
             requester = userBean.findVipsLogicUser(UUID.fromString(userUUID));
         }
+        observationTimeSeriesBean.enrichObservationTimeSeriesWithPointOfInterest(ots);
 
         boolean requesterNotValidUser = requester == null;
         boolean requesterRegularUser = requester != null && !requester.isSuperUser() && !requester.isOrganizationAdmin();
         boolean requesterNotCreator = requester != null && !ots.getUserId().equals(requester.getUserId());
-
         if (requesterNotValidUser || requesterRegularUser) {
             // Mask for all users except creator, super and orgadmin
             if (!(ots.getLocationIsPrivate() && (requesterNotValidUser || requesterNotCreator)) && ots.getPolygonService() != null) {
-                observationTimeSeriesBean.enrichObservationTimeSeriesWithPointOfInterest(ots);
                 this.maskLocation(ots.getPolygonService(), ots);
             }
         }