diff --git a/wetb/flex/__init__.py b/wetb/flex/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..4d88eaf1e090114e4fe440c509ee4f83e9605c60
--- /dev/null
+++ b/wetb/flex/__init__.py
@@ -0,0 +1,6 @@
+from ._io import load, read_sensor_info
+from wetb import gtsdf
+
+class Dataset(gtsdf.Dataset):
+    def __init__(self, filename):
+        self.time, self.data, self.info = load(filename)
\ No newline at end of file
diff --git a/wetb/flex/_io.py b/wetb/flex/_io.py
new file mode 100644
index 0000000000000000000000000000000000000000..d3e4e3ea71cdd16bbc8b5b4e1fa990899de4d7eb
--- /dev/null
+++ b/wetb/flex/_io.py
@@ -0,0 +1,159 @@
+'''
+Created on 11. apr. 2017
+
+@author: mmpe
+'''
+import struct
+import numpy as np
+import os
+
+def load(filename, dtype=np.float):
+    if isinstance(filename, str):
+        fid = open(filename,'rb')
+    elif hasattr(filename, "name"):
+        fid = filename
+        filename = fid.name
+    try:
+        _ = struct.unpack('i', fid.read(4))
+        _ = struct.unpack('i', fid.read(4))
+        title = fid.read(60).strip()
+     
+        _ = struct.unpack('i', fid.read(4))
+        _ = struct.unpack('i', fid.read(4))
+        no_sensors = struct.unpack('i', fid.read(4))[0]
+     
+        sensor_numbers = [struct.unpack('i', fid.read(4))[0] for _ in range(no_sensors)]
+        _ = struct.unpack('i', fid.read(4))
+        _ = struct.unpack('i', fid.read(4))
+        time_start = struct.unpack('f', fid.read(4))[0]
+        time_step = struct.unpack('f', fid.read(4))[0]
+        scale_factors = np.array([struct.unpack('f', fid.read(4))[0] for _ in range(no_sensors)], dtype=np.double)
+        data = np.fromstring(fid.read(), 'int16').astype(dtype)
+    finally: 
+        fid.close()
+ 
+#     if title.isalnum():
+#         self.set_info(title, "", self.filename)
+#     else:
+#         self.set_info(os.path.basename(self.name), "", self.name)
+    try:
+        data = data.reshape(len(data) // no_sensors, no_sensors)
+    except ValueError:
+        raise ValueError("The number of data values (%d) is not divisible by the number of sensors (%d)" % (len(data), no_sensors))
+ 
+    for i in range(data.shape[1]):
+        data[:, i] *= scale_factors[i]
+    no_scans = data.shape[0]
+     
+ 
+    # Load sensor file if exists
+    
+    
+    sensor_filename = os.path.join(os.path.dirname(filename), "sensor")
+    sensor_info = {info[0]:info[1:] for info in read_sensor_info(sensor_filename) }
+
+    # set gain and offset for "Time"
+    gains = []
+    offsets = []
+    names, units, descriptions = [], [], []
+    
+    for sensor_nr in sensor_numbers:
+ 
+        name, unit, description, gain, offset = sensor_info.get(sensor_nr, ["Attribute %d"%sensor_nr, '-','',1,0])
+        if sensor_nr==1 and name=="Time" and unit=="s":
+            data = data[:,1:]
+            continue
+        names.append(name)
+        units.append(unit)
+        descriptions.append(description)
+        gains.append(gain)
+        offsets.append(offset)
+    
+    time = np.arange(time_start, time_start + data.shape[0] * time_step, time_step).reshape((no_scans, 1))
+    #data = np.concatenate((time, data), axis=1)
+    #gains = np.r_[1,gains]
+    #offsets = np.r_[0,offsets]
+    # self[:]*=self.gains
+    # self[:]+=self.offsets
+    info = {"name": title,
+            "description": filename,
+            "attribute_names": names, 
+            "attribute_units": units, 
+            "attribute_descriptions": descriptions}
+    return time, data, info 
+
+
+def read_sensor_info(sensor_file):
+
+    if hasattr(sensor_file, 'readlines'):
+        sensor_info_lines = sensor_file.readlines()[2:]
+    else:
+        with open(sensor_file, encoding="utf-8") as fid:
+            sensor_info_lines = fid.readlines()[2:]
+    sensor_info = []
+    for line in sensor_info_lines:
+        # while "  " in line:
+        #    line = line.replace("  "," ")
+        line = line.strip().split()
+        nr = int(line[0])
+        gain = float(line[1])
+        offset = float(line[2])
+        unit = line[5]
+        name_desc = " ".join(line[6:])
+        name = name_desc[:8].split()[0]
+        description = name_desc[8:]
+#        name = line[6]
+#        description = " ".join(line[7:])
+
+
+        sensor_info.append((nr, name, unit, description, gain, offset))
+    return sensor_info
+
+# def save(dataset, filename):
+#     ds = dataset
+#     # Write int data file
+#     f = open(filename, 'wb')
+#     time_att = ds.basis_attribute()
+#     sensors = [s for s in ds.attributes() if s is not time_att]
+#     
+#     if isinstance(ds, FLEX4Dataset):
+#         data = ds[:]  # (ds[:]-ds.offsets)/ds.gains
+#     else:
+#         data = ds[:]
+#     if time_att.index != -1:  # time_att may be "Index" with index=-1 if "Time" not exists
+#         data = np.delete(data, time_att.index, axis=1)
+#     f.write(struct.pack('ii', 0, 0))  # 2x empty int
+#     title = ("%-60s" % str(ds.name)).encode()
+#     f.write(struct.pack('60s', title))  # title
+#     f.write(struct.pack('ii', 0, 0))  # 2x empty int
+#     ns = len(sensors)
+#     f.write(struct.pack('i', ns))
+#     f.write(struct.pack('i' * ns, *range(1, ns + 1)))  # sensor number
+#     f.write(struct.pack('ii', 0, 0))  # 2x empty int
+#     time = ds.basis_attribute()
+#     f.write(struct.pack('ff', time[0], time[1] - time[0]))  # start time and time step
+# 
+#     scale_factors = np.max(np.abs(data), 0) / 32000
+#     f.write(struct.pack('f' * len(scale_factors), *scale_factors))
+#     # avoid dividing by zero
+#     not0 = np.where(scale_factors != 0)
+#     data[:, not0] /= scale_factors[not0]
+#     #flatten and round
+#     data = np.round(data.flatten()).astype(np.int16)
+#     f.write(struct.pack('h' * len(data), *data.tolist()))
+#     f.close()
+# 
+#     # write sensor file
+#     f = open(os.path.join(os.path.dirname(filename), 'sensor'), 'w')
+#     f.write("Sensor list for %s\n" % filename)
+#     f.write(" No   forst  offset  korr. c  Volt    Unit   Navn    Beskrivelse------------\n")
+#     sensorlineformat = "%3s  %.3f   %.3f      1.00     0.00 %7s %-8s %s\n"
+# 
+#     if isinstance(ds, FLEX4Dataset):
+#         gains = np.r_[ds.gains[1:], np.ones(ds.shape[1] - len(ds.gains))]
+#         offsets = np.r_[ds.offsets[1:], np.zeros(ds.shape[1] - len(ds.offsets))]
+#         sensorlines = [sensorlineformat % ((nr + 1), gain, offset, att.unit[:7], att.name.replace(" ", "_")[:8], att.description[:512]) for nr, att, gain, offset in zip(range(ns), sensors, gains, offsets)]
+#     else:
+#         sensorlines = [sensorlineformat % ((nr + 1), 1, 0, att.unit[:7], att.name.replace(" ", "_")[:8], att.description[:512]) for nr, att in enumerate(sensors)]
+#     f.writelines(sensorlines)
+#     f.close()
\ No newline at end of file
diff --git a/wetb/flex/tests/__init__.py b/wetb/flex/tests/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/wetb/flex/tests/test_files/test1/sensor b/wetb/flex/tests/test_files/test1/sensor
new file mode 100644
index 0000000000000000000000000000000000000000..88e89f63990b9e53bef2ba37ebcd5abef5083e88
--- /dev/null
+++ b/wetb/flex/tests/test_files/test1/sensor
@@ -0,0 +1,9 @@
+Sensor list for C:/mmpe/programming/python/WindEnergyToolbox/wetb/flex/tests/test_files/test1/test.int
+ No   forst  offset  korr. c  Volt    Unit   Navn    Beskrivelse------------
+  1  1.000   0.000      1.00     0.00     m/s WSP_gl._ Free wind speed Vy, gl. coo, of gl. pos    0.75,   0.00, -40.75
+  2  1.000   0.000      1.00     0.00     m/s WSP_gl._ Free wind speed Vy, gl. coo, of gl. pos    1.00,   0.00, -39.00
+  3  1.000   0.000      1.00     0.00     m/s WSP_gl._ Free wind speed Vy, gl. coo, of gl. pos    7.00,   0.00, -33.00
+  4  1.000   0.000      1.00     0.00   rad/s Omega    Rotor speed
+  5  1.000   0.000      1.00     0.00       m Ae_pos_x Aero position x  of blade  1 at radius  20.50, global coo.
+  6  1.000   0.000      1.00     0.00       m Ae_pos_y Aero position y  of blade  1 at radius  20.50, global coo.
+  7  1.000   0.000      1.00     0.00       m Ae_pos_z Aero position z  of blade  1 at radius  20.50, global coo.
diff --git a/wetb/flex/tests/test_files/test1/test.int b/wetb/flex/tests/test_files/test1/test.int
new file mode 100644
index 0000000000000000000000000000000000000000..5df18a5d5b28c9b45ec0b48786925a5fb7d9a306
Binary files /dev/null and b/wetb/flex/tests/test_files/test1/test.int differ
diff --git a/wetb/flex/tests/test_files/test_sensor_info/sensor b/wetb/flex/tests/test_files/test_sensor_info/sensor
new file mode 100644
index 0000000000000000000000000000000000000000..593044b9a59183b02162c7acc03652b2fa20f864
--- /dev/null
+++ b/wetb/flex/tests/test_files/test_sensor_info/sensor
@@ -0,0 +1,69 @@
+  Version ID : HAWC2MB 12.3 (beta -rev_TJ6)
+ No   forst  offset  korr. c  Volt    Unit   Navn    Beskrivelse---------------
+   1    1.0    0.0    0.00      1.0    s      Time    Time
+   2    1.0    0.0    0.00      1.0    deg    bea1 an shaft_rot angle
+   3    1.0    0.0    0.00      1.0    rpm    bea1 an shaft_rot angle speed
+   4    1.0    0.0    0.00      1.0    deg    bea2 an pitch1 angle
+   5    1.0    0.0    0.00      1.0    deg/s  bea2 an pitch1 angle speed
+   6    1.0    0.0    0.00      1.0    deg    bea2 an pitch2 angle
+   7    1.0    0.0    0.00      1.0    deg/s  bea2 an pitch2 angle speed
+   8    1.0    0.0    0.00      1.0    deg    bea2 an pitch3 angle
+   9    1.0    0.0    0.00      1.0    deg/s  bea2 an pitch3 angle speed
+  10    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  11    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  12    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  13    1.0    0.0    0.00      1.0    kN     Fx coo: Force  Fx Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  14    1.0    0.0    0.00      1.0    kN     Fy coo: Force  Fy Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  15    1.0    0.0    0.00      1.0    kN     Fz coo: Force  Fz Mbdy:towertop nodenr:   1 coo: tower  tower top -1: below top mass
+  16    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:tower nodenr:   1 coo: tower  tower base flange
+  17    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:tower nodenr:   1 coo: tower  tower base flange
+  18    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:tower nodenr:   1 coo: tower  tower base flange
+  19    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:towertop nodenr:   2 coo: towertop  yaw bearing
+  20    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:towertop nodenr:   2 coo: towertop  yaw bearing
+  21    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:towertop nodenr:   2 coo: towertop  yaw bearing
+  22    1.0    0.0    0.00      1.0    kN     Fx coo: Force  Fx Mbdy:towertop nodenr:   2 coo: towertop  yaw bering
+  23    1.0    0.0    0.00      1.0    kN     Fy coo: Force  Fy Mbdy:towertop nodenr:   2 coo: towertop  yaw bering
+  24    1.0    0.0    0.00      1.0    kN     Fz coo: Force  Fz Mbdy:towertop nodenr:   2 coo: towertop  yaw bering
+  25    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:shaft nodenr:   4 coo: shaft  main bearing
+  26    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:shaft nodenr:   4 coo: shaft  main bearing
+  27    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:shaft nodenr:   4 coo: shaft  main bearing
+  28    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:blade1 nodenr:   3 coo: blade1  blade 1 root
+  29    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:blade1 nodenr:   3 coo: blade1  blade 1 root
+  30    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:blade1 nodenr:   3 coo: blade1  blade 1 root
+  31    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:blade1 nodenr:  10 coo: local  blade 1 50% local e coo
+  32    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:blade1 nodenr:  10 coo: local  blade 1 50% local e coo
+  33    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:blade1 nodenr:  10 coo: local  blade 1 50% local e coo
+  34    1.0    0.0    0.00      1.0    kN     Fx coo: Force  Fx Mbdy:blade1 nodenr:   1 coo: blade1  blade 1 root
+  35    1.0    0.0    0.00      1.0    kN     Fy coo: Force  Fy Mbdy:blade1 nodenr:   1 coo: blade1  blade 1 root
+  36    1.0    0.0    0.00      1.0    kN     Fz coo: Force  Fz Mbdy:blade1 nodenr:   1 coo: blade1  blade 1 root
+  37    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:blade2 nodenr:   1 coo: blade2  blade 2 root
+  38    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:blade2 nodenr:   1 coo: blade2  blade 2 root
+  39    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:blade2 nodenr:   1 coo: blade2  blade 2 root
+  40    1.0    0.0    0.00      1.0    kNm    Mx coo: MomentMx Mbdy:blade3 nodenr:   1 coo: blade3  blade 3 root
+  41    1.0    0.0    0.00      1.0    kNm    My coo: MomentMy Mbdy:blade3 nodenr:   1 coo: blade3  blade 3 root
+  42    1.0    0.0    0.00      1.0    kNm    Mz coo: MomentMz Mbdy:blade3 nodenr:   1 coo: blade3  blade 3 root
+  43    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:towertop E-nr:   1 Z-rel:1.00 coo: global  tower top flange position
+  44    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:towertop E-nr:   1 Z-rel:1.00 coo: global  tower top flange position
+  45    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:towertop E-nr:   1 Z-rel:1.00 coo: global  tower top flange position
+  46    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: blade1  blade 1 tip pos
+  47    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: blade1  blade 1 tip pos
+  48    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: blade1  blade 1 tip pos
+  49    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: blade2  blade 2 tip pos
+  50    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: blade2  blade 2 tip pos
+  51    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: blade2  blade 2 tip pos
+  52    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: blade3  blade 3 tip pos
+  53    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: blade3  blade 3 tip pos
+  54    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: blade3  blade 3 tip pos
+  55    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: global  blade 1 tip pos
+  56    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: global  blade 1 tip pos
+  57    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: global  blade 1 tip pos
+  58    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: hub1  blade 1 tip pos hub coo
+  59    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: hub1  blade 1 tip pos hub coo
+  60    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade1 E-nr:  18 Z-rel:1.00 coo: hub1  blade 1 tip pos hub coo
+  61    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: hub2  blade 2 tip pos hub coo
+  62    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: hub2  blade 2 tip pos hub coo
+  63    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade2 E-nr:  18 Z-rel:1.00 coo: hub2  blade 2 tip pos hub coo
+  64    1.0    0.0    0.00      1.0    m      State p State pos x  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: hub3  blade 3 tip pos hub coo
+  65    1.0    0.0    0.00      1.0    m      State p State pos y  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: hub3  blade 3 tip pos hub coo
+  66    1.0    0.0    0.00      1.0    m      State p State pos z  Mbdy:blade3 E-nr:  18 Z-rel:1.00 coo: hub3  blade 3 tip pos hub coo
+  67    1.0    0.0    0.00      1.0    rad/s  omega t State_rot omega tz Mbdy:shaft E-nr:   4 Z-rel:1.00 coo: shaft
diff --git a/wetb/flex/tests/test_flex_io.py b/wetb/flex/tests/test_flex_io.py
new file mode 100644
index 0000000000000000000000000000000000000000..85aff6126a61a23cf19457d96c8eb54473f68012
--- /dev/null
+++ b/wetb/flex/tests/test_flex_io.py
@@ -0,0 +1,27 @@
+'''
+Created on 11. apr. 2017
+
+@author: mmpe
+'''
+import os
+import unittest
+from wetb import flex
+
+
+tfp = os.path.join(os.path.dirname(__file__), 'test_files/')  # test file path
+class Test(unittest.TestCase):
+
+
+    def test_load(self):
+        time, data, info = flex.load(tfp+"test1/test.int")
+        self.assertEqual(data.shape, (800,7))
+        self.assertEqual(info['attribute_names'][1], "WSP_gl._")
+        self.assertEqual(info['attribute_units'][1], "m/s")
+        self.assertEqual(info['attribute_descriptions'][1], " Free wind speed Vy, gl. coo, of gl. pos 0.75, 0.00, -40.75")
+
+        self.assertAlmostEqual(data[0, 1], 12.037,3)
+
+
+if __name__ == "__main__":
+    #import sys;sys.argv = ['', 'Test.testName']
+    unittest.main()
\ No newline at end of file
diff --git a/wetb/flex/tests/test_sensor.py b/wetb/flex/tests/test_sensor.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a88479b1d1d014cdd89b48bf4f1f48b444c4a36
--- /dev/null
+++ b/wetb/flex/tests/test_sensor.py
@@ -0,0 +1,26 @@
+'''
+Created on 9. sep. 2016
+
+@author: mmpe
+'''
+import os
+import unittest
+from wetb.flex import read_sensor_info
+
+
+tfp = os.path.join(os.path.dirname(__file__), 'test_files/')  # test file path
+class Test(unittest.TestCase):
+
+
+    def test_sensor_load(self):
+        sensor_info = read_sensor_info(tfp + "test_sensor_info/sensor")
+        nr, name, unit, description, _, _ = sensor_info[17]
+        self.assertEqual(nr, 18)
+        self.assertEqual(name, "Mz coo: ")
+        self.assertEqual(unit, "kNm")
+        self.assertEqual(description, "MomentMz Mbdy:tower nodenr: 1 coo: tower tower base flange")
+
+
+if __name__ == "__main__":
+    #import sys;sys.argv = ['', 'Test.test_sensor_load']
+    unittest.main()