diff --git a/src/shared/drivers/canbus/CanProtocol/CanProtocolTypes.h b/src/shared/drivers/canbus/CanProtocol/CanProtocolTypes.h
index 5ba21104f759841ec4d1d5a4eb84fb166e33795b..946a32532fad1dbdc7fcdd32e3619ce96ba1702e 100644
--- a/src/shared/drivers/canbus/CanProtocol/CanProtocolTypes.h
+++ b/src/shared/drivers/canbus/CanProtocol/CanProtocolTypes.h
@@ -34,6 +34,20 @@
 namespace Boardcore
 {
 
+inline uint32_t floatToInt32(float val)
+{
+    uint32_t val2 = 0;
+    std::memcpy(&val2, &val, sizeof(float));
+    return val2;
+}
+
+inline float int32ToFloat(uint32_t val)
+{
+    float val2 = 0;
+    std::memcpy(&val2, &val, sizeof(uint32_t));
+    return val2;
+}
+
 struct CanPitotData : PitotData
 {
     uint8_t secondaryType = 0;
@@ -162,17 +176,121 @@ struct CanVoltageData : VoltageData
     }
 };
 
+struct DeviceStatus
+{
+    uint64_t timestamp = 0;
+    int16_t logNumber  = 0;
+    uint8_t state      = 0;
+
+    bool armed   = false;
+    bool hil     = false;
+    bool logGood = false;
+
+    static std::string header()
+    {
+        return "timestamp,state,logNumber,armed,hil,logGood\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << static_cast<int>(state) << "," << logNumber
+           << "," << (armed ? 1 : 0) << "," << (hil ? 1 : 0) << ","
+           << (logGood ? 1 : 0) << "\n";
+    }
+};
+
+struct CanDeviceStatus : DeviceStatus
+{
+    uint8_t secondaryType = 0;
+    uint8_t source        = 0;
+
+    static std::string header()
+    {
+        return "timestamp,state,logNumber,armed,hil,logGood,secondaryType,"
+               "source\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << static_cast<int>(state) << "," << logNumber
+           << "," << (armed ? 1 : 0) << "," << (hil ? 1 : 0) << ","
+           << (logGood ? 1 : 0) << static_cast<int>(secondaryType) << ","
+           << static_cast<int>(source) << "\n";
+    }
+};
+
+struct ServoCommand
+{
+    uint64_t timestamp   = 0;
+    float aperture       = 0;
+    uint16_t openingTime = 0;
+
+    static std::string header() { return "timestamp,aperture,openingTime\n"; }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << aperture << "," << openingTime << "\n";
+    }
+};
+
+struct CanServoCommand : ServoCommand
+{
+    uint8_t secondaryType = 0;
+    uint8_t source        = 0;
+
+    static std::string header()
+    {
+        return "timestamp,aperture,openingTime,secondaryType,source\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << aperture << "," << openingTime
+           << static_cast<int>(secondaryType) << "," << static_cast<int>(source)
+           << "\n";
+    }
+};
+
+struct ServoFeedback
+{
+    uint64_t timestamp = 0;
+    float aperture     = 0;
+    bool open          = false;
+
+    static std::string header() { return "timestamp,aperture,open\n"; }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << aperture << "," << (open ? 1 : 0) << "\n";
+    }
+};
+
+struct CanServoFeedback : ServoFeedback
+{
+    uint8_t secondaryType = 0;
+    uint8_t source        = 0;
+
+    static std::string header()
+    {
+        return "timestamp,aperture,open,secondaryType,source\n";
+    }
+
+    void print(std::ostream& os) const
+    {
+        os << timestamp << "," << aperture << "," << (open ? 1 : 0)
+           << static_cast<int>(secondaryType) << "," << static_cast<int>(source)
+           << "\n";
+    }
+};
+
 inline Canbus::CanMessage toCanMessage(const PitotData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t airspeed;
-    memcpy(&airspeed, &(data.airspeed), sizeof(airspeed));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.timestamp & ~0x3) << 30;
-    message.payload[0] |= airspeed;
+    message.payload[0] |= floatToInt32(data.airspeed);
 
     return message;
 }
@@ -181,13 +299,10 @@ inline Canbus::CanMessage toCanMessage(const PressureData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t pressure;
-    memcpy(&pressure, &(data.pressure), sizeof(pressure));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.pressureTimestamp & ~0x3) << 30;
-    message.payload[0] |= pressure;
+    message.payload[0] |= floatToInt32(data.pressure);
 
     return message;
 }
@@ -195,13 +310,10 @@ inline Canbus::CanMessage toCanMessage(const TemperatureData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t temperature;
-    memcpy(&temperature, &(data.temperature), sizeof(temperature));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.temperatureTimestamp & ~0x3) << 30;
-    message.payload[0] |= temperature;
+    message.payload[0] |= floatToInt32(data.temperature);
 
     return message;
 }
@@ -210,13 +322,10 @@ inline Canbus::CanMessage toCanMessage(const CurrentData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t current;
-    memcpy(&current, &(data.current), sizeof(current));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.currentTimestamp & ~0x3) << 30;
-    message.payload[0] |= current;
+    message.payload[0] |= floatToInt32(data.current);
 
     return message;
 }
@@ -244,13 +353,10 @@ inline Canbus::CanMessage toCanMessage(const BatteryVoltageSensorData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t voltage;
-    memcpy(&voltage, &(data.batVoltage), sizeof(voltage));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.voltageTimestamp & ~0x3) << 30;
-    message.payload[0] |= voltage;
+    message.payload[0] |= floatToInt32(data.batVoltage);
 
     return message;
 }
@@ -259,13 +365,52 @@ inline Canbus::CanMessage toCanMessage(const VoltageData& data)
 {
     Canbus::CanMessage message;
 
-    uint32_t voltage;
-    memcpy(&voltage, &(data.voltage), sizeof(voltage));
-
     message.id         = -1;
     message.length     = 1;
     message.payload[0] = (data.voltageTimestamp & ~0x3) << 30;
-    message.payload[0] |= voltage;
+    message.payload[0] |= floatToInt32(data.voltage);
+
+    return message;
+}
+
+inline Canbus::CanMessage toCanMessage(const DeviceStatus& data)
+{
+    Canbus::CanMessage message;
+
+    message.id         = -1;
+    message.length     = 1;
+    message.payload[0] = (data.timestamp & ~0x3) << 30;
+    message.payload[0] |= data.state;
+    message.payload[0] |= static_cast<uint16_t>(data.logNumber) << 8;
+    message.payload[0] |= (data.armed ? 1 : 0) << 24;
+    message.payload[0] |= (data.hil ? 1 : 0) << 25;
+    message.payload[0] |= (data.logGood ? 1 : 0) << 26;
+
+    return message;
+}
+
+inline Canbus::CanMessage toCanMessage(const ServoCommand& data)
+{
+    Canbus::CanMessage message;
+
+    message.id         = -1;
+    message.length     = 1;
+    message.payload[0] = (data.timestamp & ~0x3) << 30;
+    message.payload[0] |= static_cast<uint16_t>(data.aperture * 65535);
+    message.payload[0] |= data.openingTime << 16;
+
+    return message;
+}
+
+inline Canbus::CanMessage toCanMessage(const ServoFeedback& data)
+{
+    Canbus::CanMessage message;
+
+    message.id         = -1;
+    message.length     = 1;
+    message.payload[0] = (data.timestamp & ~0x3) << 30;
+    message.payload[0] |= static_cast<uint16_t>(data.aperture * 65535);
+    message.payload[0] |= (data.open ? 1 : 0) << 16;
 
     return message;
 }
@@ -274,10 +419,8 @@ inline CanPitotData pitotDataFromCanMessage(const Canbus::CanMessage& msg)
 {
     CanPitotData data;
 
-    uint32_t airspeed = msg.payload[0];
-    memcpy(&(data.airspeed), &airspeed, sizeof(data.airspeed));
-
     data.deltaP        = 0.0;  // put to 0 to avoid undefined behaviour
+    data.airspeed      = floatToInt32(msg.payload[0]);
     data.timestamp     = (msg.payload[0] >> 30) & ~0x3;
     data.secondaryType = msg.getSecondaryType();
     data.source        = msg.getSource();
@@ -289,10 +432,8 @@ inline CanPressureData pressureDataFromCanMessage(const Canbus::CanMessage& msg)
 {
     CanPressureData data;
 
-    uint32_t pressure = msg.payload[0];
-    memcpy(&(data.pressure), &pressure, sizeof(data.pressure));
-
     data.pressureTimestamp = (msg.payload[0] >> 30) & ~0x3;
+    data.pressure          = int32ToFloat(msg.payload[0]);
     data.secondaryType     = msg.getSecondaryType();
     data.source            = msg.getSource();
 
@@ -304,10 +445,8 @@ inline CanTemperatureData temperatureDataFromCanMessage(
 {
     CanTemperatureData data;
 
-    uint32_t temperature = msg.payload[0];
-    memcpy(&(data.temperature), &temperature, sizeof(data.temperature));
-
     data.temperatureTimestamp = (msg.payload[0] >> 30) & ~0x3;
+    data.temperature          = int32ToFloat(msg.payload[0]);
     data.secondaryType        = msg.getSecondaryType();
     data.source               = msg.getSource();
 
@@ -318,10 +457,8 @@ inline CanCurrentData currentDataFromCanMessage(const Canbus::CanMessage& msg)
 {
     CanCurrentData data;
 
-    uint32_t current = msg.payload[0];
-    memcpy(&(data.current), &current, sizeof(data.current));
-
     data.currentTimestamp = (msg.payload[0] >> 30) & ~0x3;
+    data.current          = int32ToFloat(msg.payload[0]);
     data.secondaryType    = msg.getSecondaryType();
     data.source           = msg.getSource();
 
@@ -347,10 +484,8 @@ inline CanBatteryVoltageSensorData batteryVoltageDataFromCanMessage(
 {
     CanBatteryVoltageSensorData data;
 
-    uint32_t voltage = msg.payload[0];
-    memcpy(&(data.batVoltage), &voltage, sizeof(data.batVoltage));
-
     data.voltageTimestamp = (msg.payload[0] >> 30) & ~0x3;
+    data.batVoltage       = int32ToFloat(msg.payload[0]);
     data.secondaryType    = msg.getSecondaryType();
     data.source           = msg.getSource();
 
@@ -361,14 +496,55 @@ inline CanVoltageData voltageDataFromCanMessage(const Canbus::CanMessage& msg)
 {
     CanVoltageData data;
 
-    uint32_t voltage = msg.payload[0];
-    memcpy(&(data.voltage), &voltage, sizeof(data.voltage));
-
     data.voltageTimestamp = (msg.payload[0] >> 30) & ~0x3;
+    data.voltage          = int32ToFloat(msg.payload[0]);
     data.secondaryType    = msg.getSecondaryType();
     data.source           = msg.getSource();
 
     return data;
 }
 
+inline CanDeviceStatus deviceStatusFromCanMessage(const Canbus::CanMessage& msg)
+{
+    CanDeviceStatus data;
+
+    data.timestamp     = (msg.payload[0] >> 30) & ~0x3;
+    data.state         = static_cast<uint8_t>(msg.payload[0]);
+    data.logNumber     = static_cast<int16_t>(msg.payload[0] >> 8);
+    data.armed         = ((msg.payload[0] >> 24) & 1) != 0;
+    data.hil           = ((msg.payload[0] >> 25) & 1) != 0;
+    data.logGood       = ((msg.payload[0] >> 26) & 1) != 0;
+    data.secondaryType = msg.getSecondaryType();
+    data.source        = msg.getSource();
+
+    return data;
+}
+
+inline CanServoCommand servoCommandFromCanMessage(const Canbus::CanMessage& msg)
+{
+    CanServoCommand data;
+
+    data.timestamp     = (msg.payload[0] >> 30) & ~0x3;
+    data.aperture      = static_cast<uint16_t>(msg.payload[0]) / 65535.f;
+    data.openingTime   = static_cast<uint16_t>(msg.payload[0] >> 16);
+    data.secondaryType = msg.getSecondaryType();
+    data.source        = msg.getSource();
+
+    return data;
+}
+
+inline CanServoFeedback servoFeedbackFromCanMessage(
+    const Canbus::CanMessage& msg)
+{
+    CanServoFeedback data;
+
+    data.timestamp     = (msg.payload[0] >> 30) & ~0x3;
+    data.aperture      = static_cast<uint16_t>(msg.payload[0]) / 65535.f;
+    data.open          = ((msg.payload[0] >> 16) & 1) != 0;
+    data.secondaryType = msg.getSecondaryType();
+    data.source        = msg.getSource();
+
+    return data;
+}
+
 }  // namespace Boardcore
diff --git a/src/shared/logger/LogTypes.h b/src/shared/logger/LogTypes.h
index d7b770c6ec423c5735aacde7330e266525c48ba7..804c29ff5c3e978ed786dc50adc7c410a4e83a6c 100644
--- a/src/shared/logger/LogTypes.h
+++ b/src/shared/logger/LogTypes.h
@@ -141,6 +141,9 @@ void registerTypes(Deserializer& ds)
     ds.registerType<HSCMRNN015PAData>();
     ds.registerType<SSCMRNN030PAData>();
     ds.registerType<PitotData>();
+    ds.registerType<DeviceStatus>();
+    ds.registerType<ServoCommand>();
+    ds.registerType<ServoFeedback>();
     ds.registerType<CanPitotData>();
     ds.registerType<CanPressureData>();
     ds.registerType<CanTemperatureData>();
@@ -148,6 +151,9 @@ void registerTypes(Deserializer& ds)
     ds.registerType<CanServoData>();
     ds.registerType<CanBatteryVoltageSensorData>();
     ds.registerType<CanVoltageData>();
+    ds.registerType<CanDeviceStatus>();
+    ds.registerType<CanServoCommand>();
+    ds.registerType<CanServoFeedback>();
 }
 
 }  // namespace LogTypes