This is an automated email from the ASF dual-hosted git repository.

cgarcia pushed a commit to branch feature/merlot
in repository https://gitbox.apache.org/repos/asf/plc4x-extras.git


The following commit(s) were added to refs/heads/feature/merlot by this push:
     new 560ab39  PB serialization for CS-Studio/Phoebus by integrating IoTDB 
with Archiver Appliance (#642)
560ab39 is described below

commit 560ab3912085a577a8be3bde9fc3449e3b80a116
Author: Lerb123 <[email protected]>
AuthorDate: Wed Apr 15 15:08:13 2026 -0400

    PB serialization for CS-Studio/Phoebus by integrating IoTDB with Archiver 
Appliance (#642)
    
    * –feat: PB serialization for CS-Studio/Phoebus, integrating IoTDB with 
Archiver Appliance.
    
    The conversion of VType data types to Protocol Buffers for displaying 
historical data in DataBrowser (Phoebus/CS-Studio) has been implemented. 
Support for multiple scalar types and byte formatting compatible with the 
Archiver Appliance engine has been enabled. The connection to IoTDB still needs 
to be refactored to allow for dynamic configuration of the connection.
---
 .../org.apache.plc4x.merlot.archiver/pom.xml       |  14 +-
 .../merlot/archiver/command/MerlotHtcCommand.java  | 122 ++++++------
 .../merlot/archiver/core/MerlotIoTDBMapping.java   | 122 ++++++++++++
 .../archiver/core/MerlotPBRawSerializer.java       | 180 +++++++++++++++---
 .../impl/MerlotDataBrowserIoTDBGetDataPVImpl.java  |  87 ++++++++-
 .../impl/MerlotDataBrowserIoTDBSearchPVImpl.java   |  22 +--
 .../merlot/archiver/impl/MerlotHtcIoTDBImpl.java   | 204 +++++++++++++++++----
 .../merlot/archiver/impl/MerlotHtcRTImpl.java      |   1 -
 .../OSGI-INF/blueprint/archiver-service.xml        |  34 +++-
 .../archiver/test/MerlotIoTDBMappingTest.java      |  49 +++++
 .../src/main/feature/feature.xml                   |   6 +-
 11 files changed, 698 insertions(+), 143 deletions(-)

diff --git a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/pom.xml 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/pom.xml
index a4fcf0c..97e7ab5 100644
--- a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/pom.xml
+++ b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/pom.xml
@@ -111,7 +111,12 @@
                 <configuration>
                     
<mainClass>org.apache.plc4x.merlot.archiver.test.NewMain</mainClass>
                 </configuration>
-            </plugin>            
+            </plugin>
+            <plugin>
+                <groupId>org.apache.maven.plugins</groupId>
+                <artifactId>maven-surefire-plugin</artifactId>
+                <version>2.22.0</version>
+            </plugin>
         </plugins>
     </build>
     <dependencies>
@@ -236,5 +241,12 @@
             <artifactId>lz4</artifactId>
             <version>1.3.0</version>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.13.2</version>
+            <scope>test</scope>
+            <type>jar</type>
+        </dependency>
     </dependencies>
 </project>
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/command/MerlotHtcCommand.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/command/MerlotHtcCommand.java
index 37b529f..9d751cd 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/command/MerlotHtcCommand.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/command/MerlotHtcCommand.java
@@ -16,12 +16,8 @@
  */
 package org.apache.plc4x.merlot.archiver.command;
 
-
 import java.time.Instant;
-import java.time.LocalDateTime;
 import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
-import org.apache.commons.lang3.tuple.Pair;
 import org.apache.karaf.shell.api.action.Action;
 import org.apache.karaf.shell.api.action.Argument;
 import org.apache.karaf.shell.api.action.Command;
@@ -30,52 +26,56 @@ import 
org.apache.karaf.shell.api.action.lifecycle.Reference;
 import org.apache.karaf.shell.api.action.lifecycle.Service;
 import org.apache.karaf.shell.support.table.ShellTable;
 import org.apache.plc4x.merlot.archiver.api.MerlotHtc;
-import org.epics.gpclient.PV;
+import org.apache.plc4x.merlot.archiver.impl.MerlotHtcIoTDBImpl;
+import org.apache.plc4x.merlot.archiver.impl.MerlotHtcRTImpl;
+import org.epics.vtype.Scalar;
+import org.epics.vtype.Time;
+import org.epics.vtype.VType;
 import org.osgi.framework.BundleContext;
+import org.slf4j.LoggerFactory;
 
 @Service
 @Command(scope = "plc4x", name = "htc", description = "Historical collector 
admin.")
-public class MerlotHtcCommand   implements Action {
+public class MerlotHtcCommand implements Action {
 
     @Reference
     BundleContext bc;
-    
+
     @Reference
-    volatile List<MerlotHtc> htcs;      
-    
+    volatile List<MerlotHtc> htcs;
+
     @Option(name = "-l", aliases = "--list", description = "List collector 
PVs.", required = false, multiValued = false)
-    String strHtc; 
+    String strHtc;
 
     @Option(name = "-p", aliases = "--pv", description = "Displays the stored 
values ​​of the process variable.", required = false, multiValued = false)
     String strPV;
 
     @Option(name = "-a", aliases = "--add", description = "The designated PV 
tags must be incorporated into the collector.", required = false, multiValued = 
false)
-    Boolean blnAdd;  
-    
+    Boolean blnAdd;
+
     @Option(name = "-f", aliases = "--from", description = "Start date for 
data query.", required = false, multiValued = false)
-    String from;      
-    
+    String from;
+
     @Option(name = "-t", aliases = "--to", description = "End date for data 
consultation.", required = false, multiValued = false)
-    String to;  
-    
+    String to;
+
     @Option(name = "-r", aliases = "--remove", description = "The designated 
PV tags must be remove from the collector.", required = false, multiValued = 
false)
-    String strRemovePV;       
-        
-    
+    String strRemovePV;
+
     @Argument(index = 0, name = "htc", description = "The Collector to which 
the PV tag will be assigned.", required = false, multiValued = false)
-    String strMainHtc;   
+    String strMainHtc;
 
     @Argument(index = 1, name = "rate", description = "Maximum rate at which a 
tag change must be acquired.", required = false, multiValued = false)
-    String strMaxRate;      
-    
+    String strMaxRate;
+
     @Argument(index = 2, name = "pvs", description = "List of PVS tags to 
htc.", required = false, multiValued = true)
-    List<String> strPVs;    
-    
-    
+    List<String> strPVs;
+
     
+    private static final org.slf4j.Logger LOGGER = 
LoggerFactory.getLogger(MerlotHtcCommand.class);
     @Override
     public Object execute() throws Exception {
-                
+      
         if ((null == strHtc) && (null == strMainHtc) ){
             ListCollectorsServices(null);
         } else  if ((null != strHtc) && (null == strMainHtc) && (null == 
strPV)) {
@@ -87,75 +87,75 @@ public class MerlotHtcCommand   implements Action {
          } else if ((null != strRemovePV) && (null != strMainHtc)) {
              removePV(strMainHtc, strRemovePV);
          }
+
         
         return null;
     }
-    
-    private void ListCollectorsServices(String id){
+
+    private void ListCollectorsServices(String id) {
         if (null == id) {
             ShellTable table = new ShellTable();
             table.column("Uid");
             table.column("Key");
             htcs.forEach(htc -> {
-                    table.addRow().addContent(htc.getID(),htc.getPVs().size());
+                table.addRow().addContent(htc.getID(), htc.getPVs().size());
             });
             table.print(System.out);
-            
+
         } else {
             htcs.forEach(h -> {
-                if(h.getID().equalsIgnoreCase(id)){
+                if (h.getID().equalsIgnoreCase(id)) {
                     int count = 1;
                     ShellTable table = new ShellTable();
                     table.column("Item");
-                    table.column("PV");  
+                    table.column("PV");
                     h.getPVs().forEach(pc -> {
                         table.addRow().addContent(count, pc);
                     });
-                    table.print(System.out);                        
+                    table.print(System.out);
                 }
             });
-            
+
         }
     }
-    
-    private void ListHistoricalValues(String pv, String init, String end){  
+
+    private void ListHistoricalValues(String pv, String init, String end) {
         int[] counter = new int[1];
         htcs.forEach(h -> {
-            if(h.getID().equalsIgnoreCase(strHtc)){
-                String strInit = (null == init)?Instant.MIN.toString():init;
-                String strEnd  = (null == end)?Instant.MAX.toString():end;     
                
+            if (h.getID().equalsIgnoreCase(strHtc)) {
+                String strInit = (null == init) ? Instant.MIN.toString() : 
init;
+                String strEnd = (null == end) ? Instant.MAX.toString() : end;
 
                 var pvs = h.getPVs(pv, strInit, strEnd);
                 ShellTable table = new ShellTable();
                 table.column("Date");
-                table.column("Value");  
+                table.column("Value");
                 counter[0] = 1;
-                pvs.forEach((p) ->{
-                    table.addRow().addContent(counter[0], p.toString());       
                 
+                pvs.forEach((p) -> {
+                    table.addRow().addContent(counter[0], p.toString());
                     counter[0]++;
                 });
-                table.print(System.out); 
+                table.print(System.out);
             }
-        });       
+        });
     }
-    
+
     private void addPV(String pv, String maxRate, List<String> listPVs) {
-            htcs.forEach(h -> {
-                if(h.getID().equalsIgnoreCase(strMainHtc)){
-                    listPVs.forEach(s ->{
-                        h.addPV(s, Double.MAX_VALUE);                        
-                    });
-                }   
-            });
+        htcs.forEach(h -> {
+            if (h.getID().equalsIgnoreCase(strMainHtc)) {
+                listPVs.forEach(s -> {
+                    h.addPV(s, Double.MAX_VALUE);
+                });
+            }
+        });
     }
-    
+
     private void removePV(String htc, String strpv) {
-            htcs.forEach(h -> {
-                if(h.getID().equalsIgnoreCase(htc)){
-                    h.removePV(strpv);
-                }   
-            });
-    }    
- 
-    
+        htcs.forEach(h -> {
+            if (h.getID().equalsIgnoreCase(htc)) {
+                h.removePV(strpv);
+            }
+        });
+    }
+
 }
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotIoTDBMapping.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotIoTDBMapping.java
new file mode 100644
index 0000000..8ce8ebb
--- /dev/null
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotIoTDBMapping.java
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.plc4x.merlot.archiver.core;
+
+import com.google.protobuf.ByteString;
+import java.util.function.BiFunction;
+import org.apache.iotdb.pipe.api.type.Type;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarByte;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarFloat;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarInt;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarString;
+
+public enum MerlotIoTDBMapping {
+    INT32(Type.INT32, (val, meta)
+            -> ScalarInt.newBuilder()
+                    .setSecondsintoyear(meta.seconds)
+                    .setNano(meta.nano)
+                    .setVal((Integer) val)
+                    .setSeverity(meta.severity)
+                    .setStatus(meta.status)
+                    .build()),
+    
+    INT64(Type.INT64, (val, meta) -> {
+        long numericValue = ((Number) val).longValue();
+
+        return 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble.newBuilder()
+                .setSecondsintoyear(meta.seconds)
+                .setNano(meta.nano)
+                .setVal((double) numericValue)
+                .setSeverity(meta.severity)
+                .setStatus(meta.status)
+                .build();
+    }),
+    
+    FLOAT(Type.FLOAT, (val, meta)
+            -> ScalarFloat.newBuilder()
+                    .setSecondsintoyear(meta.seconds)
+                    .setNano(meta.nano)
+                    .setVal((Float) val)
+                    .setSeverity(meta.severity)
+                    .setStatus(meta.status)
+                    .build()),
+    DOUBLE(Type.DOUBLE, (val, meta)
+            -> ScalarDouble.newBuilder()
+                    .setSecondsintoyear(meta.seconds)
+                    .setNano(meta.nano)
+                    .setVal((Double) val)
+                    .setSeverity(meta.severity)
+                    .setStatus(meta.status)
+                    .build()),
+    TEXT(Type.TEXT, (val, meta)
+            -> ScalarString.newBuilder()
+                    .setSecondsintoyear(meta.seconds)
+                    .setNano(meta.nano)
+                    .setVal(val.toString())
+                    .setSeverity(meta.severity)
+                    .setStatus(meta.status)
+                    .build()),
+    BOOLEAN(Type.BOOLEAN, (val, meta)
+            -> ScalarByte.newBuilder()
+                    .setSecondsintoyear(meta.seconds)
+                    .setNano(meta.nano)
+                    .setVal(ByteString.copyFrom(new byte[]{(byte) ((boolean) 
val ? 1 : 0)}))
+                    .setSeverity(meta.severity)
+                    .setStatus(meta.status)
+                    .build());
+
+   
+    private final Type iotdbType;
+    private final BiFunction<Object, EpicsMetadata, Object> converter;
+
+    MerlotIoTDBMapping(Type iotdbType, BiFunction<Object, EpicsMetadata, 
Object> converter) {
+        this.iotdbType = iotdbType;
+        this.converter = converter;
+    }
+
+    public Object convert(Object value, EpicsMetadata meta) {
+        return this.converter.apply(value, meta);
+    }
+
+    public static MerlotIoTDBMapping fromIotdb(Type type) {
+        for (MerlotIoTDBMapping c : values()) {
+            if (c.iotdbType == type) {
+                return c;
+            }
+        }
+        throw new UnsupportedOperationException("IoTDB type not supported: " + 
type);
+    }
+
+    /**
+     * Container for additional fields defined in EPICSEvent.proto
+     */
+    public static class EpicsMetadata {
+
+        public final int seconds;
+        public final int nano;
+        public final int severity;
+        public final int status;
+
+        public EpicsMetadata(int seconds, int nano, int severity, int status) {
+            this.seconds = seconds;
+            this.nano = nano;
+            this.severity = severity;
+            this.status = status;
+        }
+    }
+}
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotPBRawSerializer.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotPBRawSerializer.java
index 51af9f8..8e34d0c 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotPBRawSerializer.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/core/MerlotPBRawSerializer.java
@@ -16,38 +16,100 @@
  */
 package org.apache.plc4x.merlot.archiver.core;
 
+import com.google.protobuf.ByteString;
 import org.apache.plc4x.merlot.api.PB.EPICSEvent;
 import org.epics.vtype.VType;
 import java.io.IOException;
 import java.io.OutputStream;
-import java.time.Instant;
-import java.time.ZoneId;
+import java.time.OffsetDateTime;
 import java.time.ZoneOffset;
-import java.time.ZonedDateTime;
 import java.util.List;
 import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble;
+import org.epics.vtype.AlarmProvider;
+import org.epics.vtype.Time;
+import org.epics.vtype.TimeProvider;
+import org.epics.vtype.VByte;
 import org.epics.vtype.VDouble;
-
+import org.epics.vtype.VFloat;
+import org.epics.vtype.VInt;
+import org.epics.vtype.VString;
+import org.slf4j.LoggerFactory;
 
 /**
- * Clase utilitaria para la generación de archivos en formato PBRAW compatibles
- * con el EPICS Archiver Appliance.
+ * Utility class for generating PBRAW-format files compatible with the EPICS
+ * Archiver Appliance.
  */
 public final class MerlotPBRawSerializer {
 
-    // Constructor privado para evitar instanciación de clase utilitaria
-    private MerlotPBRawSerializer() {}
+    private static final org.slf4j.Logger LOGGER = 
LoggerFactory.getLogger(MerlotPBRawSerializer.class);
+
+    private MerlotPBRawSerializer() {
+    }
+
+    public static void serializeIoTDBToPBRaw(List<VType> events, String 
pvName, OutputStream out) throws IOException {
+        if (events == null || events.isEmpty()) {
+            throw new IllegalArgumentException("The list of events is empty or 
null");
+        }
+
+        VType primerElemento = events.get(0);
+        EPICSEvent.PayloadType type;
+        int year;
+
+        if (primerElemento instanceof VDouble) {
+            type = EPICSEvent.PayloadType.SCALAR_DOUBLE;
+            year = ((VDouble) 
primerElemento).getTime().getTimestamp().atOffset(ZoneOffset.UTC).getYear();
+        } else if (primerElemento instanceof VInt) {
+            type = EPICSEvent.PayloadType.SCALAR_INT;
+            year = ((VInt) 
primerElemento).getTime().getTimestamp().atOffset(ZoneOffset.UTC).getYear();
+        } else if (primerElemento instanceof VFloat) {
+            type = EPICSEvent.PayloadType.SCALAR_FLOAT;
+            year = ((VFloat) 
primerElemento).getTime().getTimestamp().atOffset(ZoneOffset.UTC).getYear();
+        } else if (primerElemento instanceof VString) {
+            type = EPICSEvent.PayloadType.SCALAR_STRING;
+            year = ((VString) 
primerElemento).getTime().getTimestamp().atOffset(ZoneOffset.UTC).getYear();
+        } else if (primerElemento instanceof VByte) {
+            type = EPICSEvent.PayloadType.SCALAR_BYTE;
+            year = ((VByte) 
primerElemento).getTime().getTimestamp().atOffset(ZoneOffset.UTC).getYear();
+        } else {
+            throw new UnsupportedOperationException("Class not supported for 
mapping: " + primerElemento.getClass().getName());
+        }
+
+        // Response to Phoebus
+        EPICSEvent.PayloadInfo info = EPICSEvent.PayloadInfo.newBuilder()
+                .setPvname(pvName)
+                .setType(type)
+                .setYear(year)
+                .setElementCount(1)
+                .build();
+        out.write(info.toByteArray());
+        out.write('\n');
+
+        for (int i = 0; i < events.size(); i++) {
+            byte[] data = serializeIoTDBToBytes(events.get(i));
+
+            //Samples converted to PB
+            if (data != null) {
+
+                out.write(data);
+                out.write('\n');
+            } else {
+                LOGGER.warn("The event {} could not be serialized (null)", i);
+            }
+        }
+
+        out.flush();
+    }
 
     /**
-     * Serializa una lista de eventos VType a un archivo en formato .pbraw. 
+     * Serializa una lista de eventos VType a un archivo en formato .pbraw.
      *
-     * @param events  Lista de eventos provenientes de la red de control.
-     * @param pvName  Nombre de la Variable de Proceso (PV).
+     * @param events Lista de eventos provenientes de la red de control.
+     * @param pvName Nombre de la Variable de Proceso (PV).
      * @param fileName Nombre del archivo de salida.
      * @throws IOException Si ocurre un error durante la escritura.
      */
     public static void serializeToPBRaw(List<VType> events, String pvName, 
OutputStream out) throws IOException {
-            
+
         if (events == null || events.isEmpty()) {
             return;
         }
@@ -55,13 +117,14 @@ public final class MerlotPBRawSerializer {
         // 1. Escribir el PayloadInfo (Metadatos obligatorios para 
pbrawclient) 
         // Se asume el tipo basado en el primer elemento de la lista
         MerlotPayloadMapping mapping = 
MerlotPayloadMapping.fromVType(events.get(0));
+        
         if (mapping == null) {
             throw new IOException("Tipo de VType no soportado para 
serialización.");
         }
 
         EPICSEvent.PayloadInfo info = EPICSEvent.PayloadInfo.newBuilder()
                 .setPvname(pvName)
-                .setType(EPICSEvent.PayloadType.SCALAR_DOUBLE)   
+                .setType(EPICSEvent.PayloadType.SCALAR_DOUBLE)
                 .setYear(((VDouble) events.get(0))
                         .getTime()
                         .getTimestamp()
@@ -71,8 +134,8 @@ public final class MerlotPBRawSerializer {
 
 //        info.writeDelimitedTo(out);
         out.write(info.toByteArray());
-        out.write('\n');  
-        
+        out.write('\n');
+
 //        
 //            // Tiempo actual
 //            Instant now = Instant.now();
@@ -85,8 +148,6 @@ public final class MerlotPBRawSerializer {
 //                    + zdt.getHour() * 3600
 //                    + zdt.getMinute() * 60
 //                    + zdt.getSecond();        
-        
-        
         // 2. Serializar cada evento VType usando la factoría 
MerlotPayloadMapping 
         for (VType vType : events) {
             Object pbEvent = MerlotPayloadMapping.createEvent(vType);
@@ -94,8 +155,8 @@ public final class MerlotPBRawSerializer {
             if (pbEvent != null) {
 //                writeEventToStream(out, pbEvent);
                 out.write(((ScalarDouble) pbEvent).toByteArray());
-                
-                out.write('\n');  
+
+                out.write('\n');
             }
         }
 //        
@@ -108,13 +169,21 @@ public final class MerlotPBRawSerializer {
 //                    .build();
 //
 //            out.write(event.toByteArray());        
-        
-        
+
         out.flush();
     }
 
     /**
-     * Escribe el objeto de Protocol Buffers en el stream usando formato 
delimitado. 
+     * Serializa una lista de eventos Type a un archivo en formato .pbraw.
+     *
+     * @param events Lista de eventos provenientes de IoTDB Database.
+     * @param pvName Nombre de la Variable de Proceso (PV).
+     * @param fileName Nombre del archivo de salida.
+     * @throws IOException Si ocurre un error durante la escritura.
+     */
+    /**
+     * Escribe el objeto de Protocol Buffers en el stream usando formato
+     * delimitado.
      */
     private static void writeEventToStream(OutputStream out, Object pbEvent) 
throws IOException {
         if (pbEvent instanceof com.google.protobuf.MessageLite) {
@@ -125,13 +194,14 @@ public final class MerlotPBRawSerializer {
             if (bytes != null) {
 //                writeVarint32(out, bytes.length);
                 out.write(bytes);
-                out.write(0x0A);                
+                out.write(0x0A);
             }
         }
     }
 
     /**
-     * Utilidad para escribir el prefijo de tamaño (Varint32) requerido por el 
protocolo. 
+     * Utilidad para escribir el prefijo de tamaño (Varint32) requerido por el
+     * protocolo.
      */
     private static void writeVarint32(OutputStream out, int value) throws 
IOException {
         while (true) {
@@ -146,15 +216,75 @@ public final class MerlotPBRawSerializer {
     }
 
     /**
-     * Convierte el objeto del evento en su representación de bytes. 
+     * Convierte el objeto del evento en su representación de bytes.
      */
     private static byte[] serializeToBytes(Object pbEvent) {
         if (pbEvent instanceof EPICSEvent.ScalarDouble) {
             return ((EPICSEvent.ScalarDouble) pbEvent).toByteArray();
         } else if (pbEvent instanceof EPICSEvent.ScalarInt) {
             return ((EPICSEvent.ScalarInt) pbEvent).toByteArray();
+        } else if (pbEvent instanceof EPICSEvent.ScalarFloat) {
+            return ((EPICSEvent.ScalarFloat) pbEvent).toByteArray();
+        } else if (pbEvent instanceof EPICSEvent.ScalarByte) {
+            return ((EPICSEvent.ScalarByte) pbEvent).toByteArray();
         }
         // Añadir otros tipos según sea necesario
         return null;
     }
+
+    private static byte[] serializeIoTDBToBytes(VType event) {
+        if (event == null) {
+            return null;
+        }
+
+        Time eventTime = ((TimeProvider) event).getTime();
+        OffsetDateTime time = 
eventTime.getTimestamp().atOffset(ZoneOffset.UTC);
+        int secondsIntoYear = (int) (time.toEpochSecond()
+                - 
time.withDayOfYear(1).withHour(0).withMinute(0).withSecond(0).toEpochSecond());
+        int nanos = eventTime.getTimestamp().getNano();
+        int severity = ((AlarmProvider) 
event).getAlarm().getSeverity().ordinal();
+
+        if (event instanceof VDouble) {
+            return EPICSEvent.ScalarDouble.newBuilder()
+                    .setSecondsintoyear(secondsIntoYear)
+                    .setNano(nanos)
+                    .setVal(((VDouble) event).getValue())
+                    .setSeverity(severity)
+                    .build().toByteArray();
+
+        } else if (event instanceof VInt) {
+            return EPICSEvent.ScalarInt.newBuilder()
+                    .setSecondsintoyear(secondsIntoYear)
+                    .setNano(nanos)
+                    .setVal(((VInt) event).getValue())
+                    .setSeverity(severity)
+                    .build().toByteArray();
+
+        } else if (event instanceof VFloat) {
+            return EPICSEvent.ScalarFloat.newBuilder()
+                    .setSecondsintoyear(secondsIntoYear)
+                    .setNano(nanos)
+                    .setVal(((VFloat) event).getValue())
+                    .setSeverity(severity)
+                    .build().toByteArray();
+
+        } else if (event instanceof VString) {
+            return EPICSEvent.ScalarString.newBuilder()
+                    .setSecondsintoyear(secondsIntoYear)
+                    .setNano(nanos)
+                    .setVal(((VString) event).getValue())
+                    .setSeverity(severity)
+                    .build().toByteArray();
+
+        } else if (event instanceof VByte) {
+            return EPICSEvent.ScalarByte.newBuilder()
+                    .setSecondsintoyear(secondsIntoYear)
+                    .setNano(nanos)
+                    .setVal(ByteString.copyFrom(new byte[]{((VByte) 
event).getValue()}))
+                    .setSeverity(severity)
+                    .build().toByteArray();
+        }
+        //If the type is not supported
+        return null;
+    }
 }
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBGetDataPVImpl.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBGetDataPVImpl.java
index 3535f9f..8d8760e 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBGetDataPVImpl.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBGetDataPVImpl.java
@@ -16,8 +16,93 @@
  */
 package org.apache.plc4x.merlot.archiver.impl;
 
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.ByteBufUtil;
+import io.netty.buffer.Unpooled;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.plc4x.merlot.archiver.api.MerlotHtc;
+import org.apache.plc4x.merlot.archiver.core.MerlotPBRawSerializer;
+import org.epics.vtype.VType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class MerlotDataBrowserIoTDBGetDataPVImpl extends HttpServlet {
-    
+
+    private static final Logger LOGGER = 
LoggerFactory.getLogger(MerlotDataBrowserRTGetDataPVImpl.class);
+
+    private final Pattern opti_pattern = 
Pattern.compile("optimized_11520\\(([^)]+)\\)");
+    private final Pattern ncount_pattern = 
Pattern.compile("ncount\\(([^)]+)\\)");
+    private final Pattern count_pattern = 
Pattern.compile("count_3600\\(([^)]+)\\)");
+
+    private Matcher opti_matcher = null;
+    private Matcher ncount_matcher = null;
+    private Matcher count_matcher = null;
+
+    private final MerlotHtc mhtc;
+
+    public MerlotDataBrowserIoTDBGetDataPVImpl(MerlotHtc mhtc) {
+        this.mhtc = mhtc;
+    }
+
+    @Override
+    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
+
+        
+        String from = req.getParameter("from");
+        String to = req.getParameter("to");
+        String[] pvs = req.getParameterValues("pv");
+        
+       
+        LOGGER.info("Inicio Servlet.");
+        if ((null == from) || (null == to)) {
+            return;
+        }
+        if ((null == pvs) || (pvs.length == 0)) {
+            return;
+        }
+
+        resp.setContentType("application/octet-stream");
+        for (String pv : pvs) {
+            opti_matcher = opti_pattern.matcher(pv);
+            ncount_matcher = ncount_pattern.matcher(pv);
+            count_matcher = count_pattern.matcher(pv);
+
+            if (opti_matcher.matches()) {
+                LOGGER.info("optimized_11520(pv) not supported.");
+            } else if (ncount_matcher.matches()) {
+                String strpv = ncount_matcher.group(1);
+                int countpv = mhtc.countPVs(strpv, from, to);
+                LOGGER.info("Number of events: " + countpv);
+                resp.getWriter().print(countpv);
+                resp.getWriter().close();
+            } else if (count_matcher.matches()) {
+                LOGGER.info("count_3600(pv) not supported.");
+            } else {
+                createRawResponse(pv, from, to, resp.getOutputStream());
+                resp.getOutputStream().close();
+            }
+        }
+
+    }
+
+    private void createRawResponse(String pv, String from, String to, 
OutputStream out) throws IOException {
+        
+        List<VType> values = mhtc.getPVs(pv, from, to);
+        
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        MerlotPBRawSerializer.serializeIoTDBToPBRaw(values, pv, bout);
+        ByteBuf buf = Unpooled.wrappedBuffer(bout.toByteArray());
+        System.out.println(ByteBufUtil.prettyHexDump(buf));
+        out.write(bout.toByteArray());
+    }
+
 }
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBSearchPVImpl.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBSearchPVImpl.java
index 47e26b5..da19fb7 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBSearchPVImpl.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotDataBrowserIoTDBSearchPVImpl.java
@@ -22,23 +22,23 @@ import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-
+import org.apache.plc4x.merlot.archiver.api.MerlotHtc;
 
 public class MerlotDataBrowserIoTDBSearchPVImpl extends HttpServlet {
 
+    private final MerlotHtc mhtc;
+
+    public MerlotDataBrowserIoTDBSearchPVImpl(MerlotHtc mhtc) {
+        this.mhtc = mhtc;
+    }
+
     @Override
     protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
throws ServletException, IOException {
         resp.setContentType("text/plain");
         try (PrintWriter writer = resp.getWriter()) {
-                    writer.println("uno");
-                    writer.println("dos");
-                    writer.println("tres");
-                    writer.println("cuatro");
-                    writer.println("cinco");
-                    writer.println("seis");
-                    writer.println("siete");
-                    writer.println("ocho");
-                }
+            mhtc.getPVs().forEach(s -> writer.println(s));
+        }
+
     }
-    
+
 }
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcIoTDBImpl.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcIoTDBImpl.java
index 18a54fa..d59b144 100755
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcIoTDBImpl.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcIoTDBImpl.java
@@ -16,11 +16,31 @@
  */
 package org.apache.plc4x.merlot.archiver.impl;
 
+import java.time.Instant;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.iotdb.isession.pool.SessionDataSetWrapper;
+import org.apache.iotdb.pipe.api.type.Type;
+import org.apache.iotdb.rpc.IoTDBConnectionException;
+import org.apache.iotdb.rpc.StatementExecutionException;
 import org.apache.iotdb.session.pool.SessionPool;
-import org.apache.plc4x.merlot.archiver.api.MerlotGPClient;
 import org.apache.plc4x.merlot.archiver.api.MerlotHtc;
+import org.apache.plc4x.merlot.archiver.core.MerlotIoTDBMapping;
+import org.apache.tsfile.read.common.Field;
+import org.apache.tsfile.read.common.RowRecord;
+import org.epics.vtype.Alarm;
+import org.epics.vtype.Display;
+import org.epics.vtype.Time;
+import org.epics.vtype.VByte;
+import org.epics.vtype.VDouble;
+import org.epics.vtype.VFloat;
+import org.epics.vtype.VInt;
+import org.epics.vtype.VString;
 import org.epics.vtype.VType;
 import org.slf4j.LoggerFactory;
 
@@ -29,71 +49,193 @@ import org.slf4j.LoggerFactory;
  * @author cgarcia
  */
 public class MerlotHtcIoTDBImpl implements MerlotHtc {
-    private static final org.slf4j.Logger LOGGER = 
LoggerFactory.getLogger(MerlotHtcIoTDBImpl.class); 
-    
-    
+
+    private static final org.slf4j.Logger LOGGER = 
LoggerFactory.getLogger(MerlotHtcIoTDBImpl.class);
+
     private static final String strID = "iotdb";
-    private SessionPool sp ;
-       
+    private SessionPool sp;
+
+    public MerlotHtcIoTDBImpl() {
 
-    public MerlotHtcIoTDBImpl(MerlotGPClient gpMerlotClient) {
-      
     }
-    
+
     @Override
     public void init() {
-       sp = new SessionPool.Builder()
-               .host("192.168.0.218")
-               .port(6667)
-               .user("root")
-               .password("root")
-               .maxSize(5)
-               .build();
-       
-        if (sp != null) {
-            LOGGER.info("Connection sucess");
+
+    }
+
+    public SessionPool getIoTDBConnection() throws IoTDBConnectionException, 
StatementExecutionException {
+        try {
+            //TODO: Leer datos desde archivo cfg
+            sp = new SessionPool.Builder()
+                    .nodeUrls(Arrays.asList("192.168.31.202:6667"))
+                    .user("root")
+                    .password("root")
+                    .maxSize(10)
+                    .enableAutoFetch(false)
+                    .build();
+
+            if (sp != null) {
+                return sp;
+            }
+        } catch (Exception e) {
+            System.out.println("Error: " + e.getMessage());
         }
+        return null;
     }
 
     @Override
     public void destroy() {
         if (sp != null) {
-           sp.close();
+            sp.close();
         }
     }
 
     @Override
     public String getID() {
         return strID;
-    }    
-    
+    }
+
     @Override
     public void addPV(String strPV, Double interval) {
         //
     }
 
     @Override
-    public void removePV(String strPV) {
+    public void removePV(String strPV
+    ) {
         //
     }
 
     @Override
     public Set<String> getPVs() {
-       
-        return null;
+        Set<String> pvs = new HashSet<>();
+
+        String pvNameQuery = "SHOW TIMESERIES root.**";
+
+        try (SessionDataSetWrapper ds = 
getIoTDBConnection().executeQueryStatement(pvNameQuery)) {
+            while (ds.hasNext()) {
+
+                String fullPath = 
ds.next().getFields().get(0).getStringValue();
+
+                pvs.add(fullPath.replaceFirst("^[^.]+\\.(.*)", "$1"));
+            }
+        } catch (Exception ex) {
+            LOGGER.error("Error retrieving PVs from IoTDB: {}", 
ex.getMessage());
+        }
+
+        return pvs;
     }
 
     @Override
     public List<VType> getPVs(String strPV, String init, String end) {
-        return null;
+        List<VType> listResult = new ArrayList<>();
+
+        try {
+            String device = getBasePath(strPV);
+            String measurement = getTimeserieNameSimple(strPV);
+
+            long startT = Instant.parse(init).toEpochMilli();
+            long endT = Instant.parse(end).toEpochMilli();
+
+            String sql = String.format("SELECT %s FROM root.%s WHERE time >= 
%d AND time <= %d",
+                    measurement, device, startT, endT);
+            try (SessionDataSetWrapper dataSet = 
getIoTDBConnection().executeQueryStatement(sql)) {
+
+                String typeStr = dataSet.getColumnTypes().get(1);
+                Type iotdbType = Type.valueOf(typeStr);
+                MerlotIoTDBMapping mapper = 
MerlotIoTDBMapping.fromIotdb(iotdbType);
+
+                while (dataSet.hasNext()) {
+                    RowRecord record = dataSet.next();
+                    long timestamp = record.getTimestamp();
+                    Field field = record.getFields().get(0);
+
+                    if (field.getDataType() != null) {
+                        Instant inst = Instant.ofEpochMilli(timestamp);
+
+                        MerlotIoTDBMapping.EpicsMetadata meta
+                                = new MerlotIoTDBMapping.EpicsMetadata((int) 
inst.getEpochSecond(), inst.getNano(), 0, 0);
+
+                        Object epicsEvent = 
mapper.convert(field.getObjectValue(field.getDataType()), meta);
+                        listResult.addAll(translateToScalarType(inst, 
epicsEvent));
+                    }
+                }
+            }
+        } catch (Exception e) {
+            LOGGER.error("Error retrieving PVs from IoTDB", e);
+        }
+
+        for (VType vType : listResult) {
+            LOGGER.info("EpicsEvent: {}", vType.toString());
+        }
+        return listResult;
+    }
+
+    private static List<VType> translateToScalarType(Instant inst, Object 
epicsEvent) {
+        List<VType> listEvents = new ArrayList<>();
+
+        // --- CONVERSION BASED STRICTLY ON MerlotIoTDBMapping ---
+        if (epicsEvent instanceof VType) {
+            listEvents.add((VType) epicsEvent);
+        } else if (epicsEvent instanceof 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble) {
+            var pbEvent = 
(org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble) epicsEvent;
+            listEvents.add(VDouble.of(pbEvent.getVal(), Alarm.none(), 
Time.of(inst), Display.none()));
+        } else if (epicsEvent instanceof 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarInt) {
+            var pbEvent = 
(org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarInt) epicsEvent;
+            listEvents.add(VInt.of(pbEvent.getVal(), Alarm.none(), 
Time.of(inst), Display.none()));
+        } else if (epicsEvent instanceof 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarFloat) {
+            var pb = (org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarFloat) 
epicsEvent;
+            listEvents.add(VFloat.of(pb.getVal(), Alarm.none(), Time.of(inst), 
Display.none()));
+        } else if (epicsEvent instanceof 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarString) {
+            var pb = (org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarString) 
epicsEvent;
+            listEvents.add(VString.of(pb.getVal(), Alarm.none(), 
Time.of(inst)));
+        } else if (epicsEvent instanceof 
org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarByte) {
+            var pb = (org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarByte) 
epicsEvent;
+
+            byte byteVal = pb.getVal().isEmpty() ? 0 : pb.getVal().byteAt(0);
+
+            listEvents.add(VByte.of(byteVal, Alarm.none(), Time.of(inst), 
Display.none()));
+        } else {
+            LOGGER.warn("PB event type not supported in the final conversion: 
{}", epicsEvent.getClass().getName());
+        }
+        return listEvents;
     }
 
     @Override
-    public int countPVs(String strPV, String init, String end) {
+    public int countPVs(String strPV, String init,
+            String end
+    ) {
+
         return 0;
     }
-    
-    
-    
-    
+
+    /*
+    Returns the variable stored in the IoTDB device (pvName)
+     */
+    private static String getTimeserieNameSimple(String pvName) {
+        Pattern pattern = Pattern.compile("[^.]+$");
+        Matcher matcher = pattern.matcher(pvName);
+
+        if (matcher.find()) {
+            return matcher.group();
+        }
+
+        return "";
+    }
+
+    /*
+    Returns the base path contained in the IoTDB device
+     */
+    public static String getBasePath(String pvName) {
+        if (pvName == null || pvName.isEmpty()) {
+            return "";
+        }
+
+        // Explicación del Regex:
+        // ^(?:root\.)?  -> Grupo opcional al inicio: busca "root." pero no lo 
captura.
+        // (.*)          -> Grupo 1: Captura codiciosamente todo el camino 
intermedio.
+        // \.[^.]+$      -> Busca el último punto y lo que sigue hasta el 
final (la medida).
+        return pvName.replaceFirst("^(?:root\\.)?(.*)\\.[^.]+$", "$1");
+    }
 }
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcRTImpl.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcRTImpl.java
index 017077c..d0f728b 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcRTImpl.java
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/java/org/apache/plc4x/merlot/archiver/impl/MerlotHtcRTImpl.java
@@ -143,7 +143,6 @@ public class MerlotHtcRTImpl implements MerlotHtc {
             })
             .collect(Collectors.toList());   
         if (listPVs.size() == 0) {
-            System.out.println("Tamaño es cero.");
             VType lastvalue = queue.get(0);
             VDouble valorOriginal = (VDouble) lastvalue;
             Time tv = Time.of(Instant.parse(init));
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/resources/OSGI-INF/blueprint/archiver-service.xml
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/resources/OSGI-INF/blueprint/archiver-service.xml
index 3b216f9..23a1d37 100644
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/resources/OSGI-INF/blueprint/archiver-service.xml
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/main/resources/OSGI-INF/blueprint/archiver-service.xml
@@ -103,8 +103,7 @@
             init-method="init"  
             destroy-method="destroy"                           
             scope="singleton"
-            activation="eager">
-            <argument ref="MerlotGPClientBean" />          
+            activation="eager">        
     </bean>          
     
 <!--    <bean id="MerlotDataBrowserIoTDBSearchPVBean" 
@@ -201,24 +200,30 @@
         </service-properties>
     </service>                
     
-   <service interface="javax.servlet.Servlet">
-        <service-properties>
-            <entry key="alias" value="/request/iotdb/bpl/searchForPVsRegex"/>
-            <entry key="servlet-name" value="IoTDBsearchForPVsRegex"/>
-        </service-properties>
-        <bean 
class="org.apache.plc4x.merlot.archiver.impl.MerlotDataBrowserIoTDBSearchPVImpl"/>
-    </service>   
     
+    <!--Returns of PV names-->
    <service interface="javax.servlet.Servlet">
         <service-properties>
+            <!--<entry key="alias" 
value="/request/rt/bpl/searchPVNameOnRuntime"/>-->
             <entry key="alias" value="/request/rt/bpl/searchForPVsRegex"/>
-            <entry key="servlet-name" value="RTsearchForPVsRegex"/>
+            <entry key="servlet-name" value="RTSearchPVNames"/>
         </service-properties>
         <bean 
class="org.apache.plc4x.merlot.archiver.impl.MerlotDataBrowserRTSearchPVImpl">
             <argument ref="MerlotHtcRTBean" />
         </bean>
     </service>  
+   <service interface="javax.servlet.Servlet">
+        <service-properties>
+            <!--<entry key="alias" 
value="/request/iotdb/bpl/searchPVNameOntoIoTDB"/>-->
+            <entry key="alias" value="/request/iotdb/bpl/searchForPVsRegex"/>
+            <entry key="servlet-name" value="IoTDBSearchPVNames"/>
+        </service-properties>
+        <bean 
class="org.apache.plc4x.merlot.archiver.impl.MerlotDataBrowserIoTDBSearchPVImpl">
+            <argument ref="MerlotHtcIoTDBBean"/>
+        </bean>
+    </service>  
     
+    <!--Returns of PV data-->
    <service interface="javax.servlet.Servlet">
         <service-properties>            
             <entry key="alias" value="/request/rt/data/getData.raw"/>
@@ -228,5 +233,14 @@
             <argument ref="MerlotHtcRTBean" />
         </bean>
     </service>                                      
+   <service interface="javax.servlet.Servlet">
+        <service-properties>            
+            <entry key="alias" value="/request/iotdb/data/getData.raw"/>
+            <entry key="servlet-name" value="IoTDBGetDataForPVs"/>
+        </service-properties>
+        <bean 
class="org.apache.plc4x.merlot.archiver.impl.MerlotDataBrowserIoTDBGetDataPVImpl">
+            <argument ref="MerlotHtcIoTDBBean"/>
+        </bean>
+    </service>                                      
 
 </blueprint>
\ No newline at end of file
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/test/java/org/apache/plc4x/merlot/archiver/test/MerlotIoTDBMappingTest.java
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/test/java/org/apache/plc4x/merlot/archiver/test/MerlotIoTDBMappingTest.java
new file mode 100644
index 0000000..1b9f686
--- /dev/null
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.archiver/src/test/java/org/apache/plc4x/merlot/archiver/test/MerlotIoTDBMappingTest.java
@@ -0,0 +1,49 @@
+package org.apache.plc4x.merlot.archiver.test;
+
+import org.apache.iotdb.pipe.api.type.Type;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarDouble;
+import org.apache.plc4x.merlot.api.PB.EPICSEvent.ScalarFloat;
+import org.apache.plc4x.merlot.archiver.core.MerlotIoTDBMapping;
+import org.junit.jupiter.api.Assertions; 
+import org.junit.jupiter.api.BeforeEach; // JUnit 5
+import org.junit.jupiter.api.Test;
+
+public class MerlotIoTDBMappingTest {
+    private MerlotIoTDBMapping.EpicsMetadata testMeta;
+
+    @BeforeEach
+    public void setUp() {
+        // Inicialización correcta antes de cada test
+        testMeta = new MerlotIoTDBMapping.EpicsMetadata(12345678, 999, 1, 2);
+    }
+
+    @Test
+    public void testConvertFloat() {
+        float value = 12.34f;
+        Object result = 
MerlotIoTDBMapping.fromIotdb(Type.FLOAT).convert(value, testMeta);
+
+        Assertions.assertTrue(result instanceof ScalarFloat);
+        ScalarFloat scalar = (ScalarFloat) result;
+        Assertions.assertEquals(value, scalar.getVal(), 0.001);
+        Assertions.assertEquals(testMeta.nano, scalar.getNano());
+    }
+
+    @Test
+    public void testConvertDouble() {
+        double value = 99.999;
+        Object result = 
MerlotIoTDBMapping.fromIotdb(Type.DOUBLE).convert(value, testMeta);
+
+        Assertions.assertTrue(result instanceof ScalarDouble);
+        ScalarDouble scalar = (ScalarDouble) result;
+        Assertions.assertEquals(value, scalar.getVal(), 0.00001);
+        Assertions.assertEquals(testMeta.status, scalar.getStatus());
+    }
+
+    @Test
+    public void testUnsupportedType() {
+        // Verificamos que lance la excepción esperada para tipos como BLOB
+        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
+            MerlotIoTDBMapping.fromIotdb(Type.BLOB);
+        });
+    }
+}
\ No newline at end of file
diff --git 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.features/src/main/feature/feature.xml
 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.features/src/main/feature/feature.xml
index e2e1566..120b6d0 100755
--- 
a/plc4j/tools/merlot/org.apache.plc4x.merlot.features/src/main/feature/feature.xml
+++ 
b/plc4j/tools/merlot/org.apache.plc4x.merlot.features/src/main/feature/feature.xml
@@ -102,7 +102,7 @@
         <!-- Internal boquer -->
 
         <feature>plc4x-core</feature>              
-        <!--<feature>plc4x-archiver</feature>-->                         
+        <feature>plc4x-archiver</feature>                         
         <!-- Plc4x-Merlot-Core> 
             1. Driver packages must have a "start-level" greater than 40.
         -->
@@ -728,7 +728,9 @@ dataSourceName=rtdb
         <bundle 
start-level="30">wrap:mvn:org.apache.iotdb/iotdb-thrift-commons/${iotdb.session.version}/$Bundle-SymbolicName=iotdb-thrift-commons&amp;Bundle-Version=${iotdb.session.version}&amp;Bundle-ManifestVersion=&quot;2&quot;&amp;Export-Package=*;version=&quot;${iotdb.session.version}&quot;,!*</bundle>
 
         <bundle 
start-level="30">mvn:org.apache.iotdb/iotdb-thrift/${iotdb.session.version}</bundle>
 
         
-        <bundle 
start-level="30">wrap:mvn:org.apache.tsfile/common/${tsfile.version}/$Bundle-SymbolicName=common&amp;Bundle-Version=${tsfile.version}&amp;Bundle-ManifestVersion=&quot;2&quot;&amp;Export-Package=*;version=&quot;${tsfile.version}&quot;,!*</bundle>
+        <!--<bundle 
start-level="30">wrap:mvn:org.apache.tsfile/common/${tsfile.version}/$Bundle-SymbolicName=common&amp;Bundle-Version=${tsfile.version}&amp;Bundle-ManifestVersion=&quot;2&quot;&amp;Export-Package=*;version=&quot;${tsfile.version}&quot;,!*</bundle>-->
+        
+        <bundle 
start-level="30">wrap:mvn:org.apache.tsfile/common/${tsfile.version}$Bundle-SymbolicName=common&amp;Bundle-Version=${tsfile.version}&amp;Export-Package=*;-org.apache.tsfile.utils</bundle>
         
         <bundle 
start-level="30">mvn:org.apache.tsfile/tsfile/${tsfile.version}</bundle> 
         <bundle start-level="30">mvn:net.jpountz.lz4/lz4/1.3.0</bundle> 

Reply via email to