diff --git a/cpp/dmi/hw.pb.cc b/cpp/dmi/hw.pb.cc
index 563ab4d..d25ab3d 100644
--- a/cpp/dmi/hw.pb.cc
+++ b/cpp/dmi/hw.pb.cc
@@ -689,67 +689,75 @@
   "NT_TYPE_CPU\020\n\022\032\n\026COMPONENT_TYPE_BATTERY\020"
   "\013\022\032\n\026COMPONENT_TYPE_STORAGE\020\014\022\031\n\025COMPONE"
   "NT_TYPE_MEMORY\020\r\022\036\n\032COMPONENT_TYPE_TRANS"
-  "CEIVER\020\016*\263\001\n\023ComponentAdminState\022\036\n\032COMP"
+  "CEIVER\020\016*\363\001\n\023ComponentAdminState\022\036\n\032COMP"
   "_ADMIN_STATE_UNDEFINED\020\000\022\034\n\030COMP_ADMIN_S"
   "TATE_UNKNOWN\020\001\022\033\n\027COMP_ADMIN_STATE_LOCKE"
   "D\020\002\022\"\n\036COMP_ADMIN_STATE_SHUTTING_DOWN\020\003\022"
-  "\035\n\031COMP_ADMIN_STATE_UNLOCKED\020\004*\250\001\n\022Compo"
-  "nentOperState\022\035\n\031COMP_OPER_STATE_UNDEFIN"
-  "ED\020\000\022\033\n\027COMP_OPER_STATE_UNKNOWN\020\001\022\034\n\030COM"
-  "P_OPER_STATE_DISABLED\020\002\022\033\n\027COMP_OPER_STA"
-  "TE_ENABLED\020\003\022\033\n\027COMP_OPER_STATE_TESTING\020"
-  "\004*\246\001\n\023ComponentUsageState\022\036\n\032COMP_USAGE_"
-  "STATE_UNDEFINED\020\000\022\034\n\030COMP_USAGE_STATE_UN"
-  "KNOWN\020\001\022\031\n\025COMP_USAGE_STATE_IDLE\020\002\022\033\n\027CO"
-  "MP_USAGE_STATE_ACTIVE\020\003\022\031\n\025COMP_USAGE_ST"
-  "ATE_BUSY\020\004*\217\002\n\023ComponentAlarmState\022\036\n\032CO"
-  "MP_ALARM_STATE_UNDEFINED\020\000\022\034\n\030COMP_ALARM"
-  "_STATE_UNKNOWN\020\001\022!\n\035COMP_ALARM_STATE_UND"
-  "ER_REPAIR\020\002\022\035\n\031COMP_ALARM_STATE_CRITICAL"
-  "\020\003\022\032\n\026COMP_ALARM_STATE_MAJOR\020\004\022\032\n\026COMP_A"
-  "LARM_STATE_MINOR\020\005\022\034\n\030COMP_ALARM_STATE_W"
-  "ARNING\020\006\022\"\n\036COMP_ALARM_STATE_INDETERMINA"
-  "TE\020\007*\274\001\n\025ComponentStandbyState\022 \n\034COMP_S"
-  "TANDBY_STATE_UNDEFINED\020\000\022\036\n\032COMP_STANDBY"
-  "_STATE_UNKNOWN\020\001\022\032\n\026COMP_STANDBY_STATE_H"
-  "OT\020\002\022\033\n\027COMP_STANDBY_STATE_COLD\020\003\022(\n$COM"
-  "P_STANDBY_STATE_PROVIDING_SERVICE\020\004*\235\003\n\r"
-  "DataValueType\022\030\n\024VALUE_TYPE_UNDEFINED\020\000\022"
-  "\024\n\020VALUE_TYPE_OTHER\020\001\022\026\n\022VALUE_TYPE_UNKN"
-  "OWN\020\002\022\027\n\023VALUE_TYPE_VOLTS_AC\020\003\022\027\n\023VALUE_"
-  "TYPE_VOLTS_DC\020\004\022\026\n\022VALUE_TYPE_AMPERES\020\005\022"
-  "\024\n\020VALUE_TYPE_WATTS\020\006\022\024\n\020VALUE_TYPE_HERT"
-  "Z\020\007\022\026\n\022VALUE_TYPE_CELSIUS\020\010\022\031\n\025VALUE_TYP"
-  "E_PERCENT_RH\020\t\022\022\n\016VALUE_TYPE_RPM\020\n\022\022\n\016VA"
-  "LUE_TYPE_CMM\020\013\022\032\n\026VALUE_TYPE_TRUTH_VALUE"
-  "\020\014\022\026\n\022VALUE_TYPE_PERCENT\020\r\022\025\n\021VALUE_TYPE"
-  "_METERS\020\016\022\024\n\020VALUE_TYPE_BYTES\020\017\022\022\n\016VALUE"
-  "_TYPE_DBM\020\020*\244\003\n\nValueScale\022\031\n\025VALUE_SCAL"
-  "E_UNDEFINED\020\000\022\025\n\021VALUE_SCALE_YOCTO\020\001\022\025\n\021"
-  "VALUE_SCALE_ZEPTO\020\002\022\024\n\020VALUE_SCALE_ATTO\020"
-  "\003\022\025\n\021VALUE_SCALE_FEMTO\020\004\022\024\n\020VALUE_SCALE_"
-  "PICO\020\005\022\024\n\020VALUE_SCALE_NANO\020\006\022\025\n\021VALUE_SC"
-  "ALE_MICRO\020\007\022\025\n\021VALUE_SCALE_MILLI\020\010\022\025\n\021VA"
-  "LUE_SCALE_UNITS\020\t\022\024\n\020VALUE_SCALE_KILO\020\n\022"
-  "\024\n\020VALUE_SCALE_MEGA\020\013\022\024\n\020VALUE_SCALE_GIG"
-  "A\020\014\022\024\n\020VALUE_SCALE_TERA\020\r\022\024\n\020VALUE_SCALE"
-  "_PETA\020\016\022\023\n\017VALUE_SCALE_EXA\020\017\022\025\n\021VALUE_SC"
-  "ALE_ZETTA\020\020\022\025\n\021VALUE_SCALE_YOTTA\020\021*\202\001\n\014S"
-  "ensorStatus\022\033\n\027SENSOR_STATUS_UNDEFINED\020\000"
-  "\022\024\n\020SENSOR_STATUS_OK\020\001\022\035\n\031SENSOR_STATUS_"
-  "UNAVAILABLE\020\002\022 \n\034SENSOR_STATUS_NONOPERAT"
-  "IONAL\020\003*\244\001\n\017TransceiverType\022\022\n\016TYPE_UNDE"
-  "FINED\020\000\022\014\n\010ETHERNET\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON"
-  "\020\003\022\n\n\006XGSPON\020\004\022\010\n\004CPON\020\005\022\013\n\007NG_PON2\020\006\022\010\n"
-  "\004EPON\020\007\022\025\n\021COMBO_GPON_XGSPON\020\010\022\026\n\021TYPE_N"
-  "OT_DETECTED\020\377\001B;Z9github.com/opencord/de"
-  "vice-management-interface/v3/go/dmib\006pro"
-  "to3"
+  "\035\n\031COMP_ADMIN_STATE_UNLOCKED\020\004\022\035\n\031COMP_A"
+  "DMIN_STATE_ISOLATED\020\006\022\037\n\033COMP_ADMIN_STAT"
+  "E_PROHIBITED\020\005*\303\003\n\022ComponentOperState\022\035\n"
+  "\031COMP_OPER_STATE_UNDEFINED\020\000\022\033\n\027COMP_OPE"
+  "R_STATE_UNKNOWN\020\001\022\034\n\030COMP_OPER_STATE_DIS"
+  "ABLED\020\002\022\033\n\027COMP_OPER_STATE_ENABLED\020\003\022\033\n\027"
+  "COMP_OPER_STATE_TESTING\020\004\022\032\n\026COMP_OPER_S"
+  "TATE_NORMAL\020\005\022\037\n\033COMP_OPER_STATE_CONFIGU"
+  "RING\020\006\022%\n!COMP_OPER_STATE_AUTOMATIC_LOAD"
+  "ING\020\007\022\032\n\026COMP_OPER_STATE_FAILED\020\010\022&\n\"COM"
+  "P_OPER_STATE_HIGH_TEMP_SHUTDOWN\020\t\022#\n\037COM"
+  "P_OPER_STATE_MANUAL_SHUTDOWN\020\n\022)\n%COMP_O"
+  "PER_STATE_POWER_SAVING_SHUTDOWN\020\013\022!\n\035COM"
+  "P_OPER_STATE_TYPE_MISMATCH\020\014*\246\001\n\023Compone"
+  "ntUsageState\022\036\n\032COMP_USAGE_STATE_UNDEFIN"
+  "ED\020\000\022\034\n\030COMP_USAGE_STATE_UNKNOWN\020\001\022\031\n\025CO"
+  "MP_USAGE_STATE_IDLE\020\002\022\033\n\027COMP_USAGE_STAT"
+  "E_ACTIVE\020\003\022\031\n\025COMP_USAGE_STATE_BUSY\020\004*\217\002"
+  "\n\023ComponentAlarmState\022\036\n\032COMP_ALARM_STAT"
+  "E_UNDEFINED\020\000\022\034\n\030COMP_ALARM_STATE_UNKNOW"
+  "N\020\001\022!\n\035COMP_ALARM_STATE_UNDER_REPAIR\020\002\022\035"
+  "\n\031COMP_ALARM_STATE_CRITICAL\020\003\022\032\n\026COMP_AL"
+  "ARM_STATE_MAJOR\020\004\022\032\n\026COMP_ALARM_STATE_MI"
+  "NOR\020\005\022\034\n\030COMP_ALARM_STATE_WARNING\020\006\022\"\n\036C"
+  "OMP_ALARM_STATE_INDETERMINATE\020\007*\274\001\n\025Comp"
+  "onentStandbyState\022 \n\034COMP_STANDBY_STATE_"
+  "UNDEFINED\020\000\022\036\n\032COMP_STANDBY_STATE_UNKNOW"
+  "N\020\001\022\032\n\026COMP_STANDBY_STATE_HOT\020\002\022\033\n\027COMP_"
+  "STANDBY_STATE_COLD\020\003\022(\n$COMP_STANDBY_STA"
+  "TE_PROVIDING_SERVICE\020\004*\235\003\n\rDataValueType"
+  "\022\030\n\024VALUE_TYPE_UNDEFINED\020\000\022\024\n\020VALUE_TYPE"
+  "_OTHER\020\001\022\026\n\022VALUE_TYPE_UNKNOWN\020\002\022\027\n\023VALU"
+  "E_TYPE_VOLTS_AC\020\003\022\027\n\023VALUE_TYPE_VOLTS_DC"
+  "\020\004\022\026\n\022VALUE_TYPE_AMPERES\020\005\022\024\n\020VALUE_TYPE"
+  "_WATTS\020\006\022\024\n\020VALUE_TYPE_HERTZ\020\007\022\026\n\022VALUE_"
+  "TYPE_CELSIUS\020\010\022\031\n\025VALUE_TYPE_PERCENT_RH\020"
+  "\t\022\022\n\016VALUE_TYPE_RPM\020\n\022\022\n\016VALUE_TYPE_CMM\020"
+  "\013\022\032\n\026VALUE_TYPE_TRUTH_VALUE\020\014\022\026\n\022VALUE_T"
+  "YPE_PERCENT\020\r\022\025\n\021VALUE_TYPE_METERS\020\016\022\024\n\020"
+  "VALUE_TYPE_BYTES\020\017\022\022\n\016VALUE_TYPE_DBM\020\020*\244"
+  "\003\n\nValueScale\022\031\n\025VALUE_SCALE_UNDEFINED\020\000"
+  "\022\025\n\021VALUE_SCALE_YOCTO\020\001\022\025\n\021VALUE_SCALE_Z"
+  "EPTO\020\002\022\024\n\020VALUE_SCALE_ATTO\020\003\022\025\n\021VALUE_SC"
+  "ALE_FEMTO\020\004\022\024\n\020VALUE_SCALE_PICO\020\005\022\024\n\020VAL"
+  "UE_SCALE_NANO\020\006\022\025\n\021VALUE_SCALE_MICRO\020\007\022\025"
+  "\n\021VALUE_SCALE_MILLI\020\010\022\025\n\021VALUE_SCALE_UNI"
+  "TS\020\t\022\024\n\020VALUE_SCALE_KILO\020\n\022\024\n\020VALUE_SCAL"
+  "E_MEGA\020\013\022\024\n\020VALUE_SCALE_GIGA\020\014\022\024\n\020VALUE_"
+  "SCALE_TERA\020\r\022\024\n\020VALUE_SCALE_PETA\020\016\022\023\n\017VA"
+  "LUE_SCALE_EXA\020\017\022\025\n\021VALUE_SCALE_ZETTA\020\020\022\025"
+  "\n\021VALUE_SCALE_YOTTA\020\021*\202\001\n\014SensorStatus\022\033"
+  "\n\027SENSOR_STATUS_UNDEFINED\020\000\022\024\n\020SENSOR_ST"
+  "ATUS_OK\020\001\022\035\n\031SENSOR_STATUS_UNAVAILABLE\020\002"
+  "\022 \n\034SENSOR_STATUS_NONOPERATIONAL\020\003*\244\001\n\017T"
+  "ransceiverType\022\022\n\016TYPE_UNDEFINED\020\000\022\014\n\010ET"
+  "HERNET\020\001\022\010\n\004GPON\020\002\022\t\n\005XGPON\020\003\022\n\n\006XGSPON\020"
+  "\004\022\010\n\004CPON\020\005\022\013\n\007NG_PON2\020\006\022\010\n\004EPON\020\007\022\025\n\021CO"
+  "MBO_GPON_XGSPON\020\010\022\026\n\021TYPE_NOT_DETECTED\020\377"
+  "\001B;Z9github.com/opencord/device-manageme"
+  "nt-interface/v3/go/dmib\006proto3"
   ;
 ::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_2eproto = {
   false, InitDefaults_dmi_2fhw_2eproto, 
   descriptor_table_protodef_dmi_2fhw_2eproto,
-  "dmi/hw.proto", &assign_descriptors_table_dmi_2fhw_2eproto, 6523,
+  "dmi/hw.proto", &assign_descriptors_table_dmi_2fhw_2eproto, 6870,
 };
 
 void AddDescriptors_dmi_2fhw_2eproto() {
@@ -976,6 +984,8 @@
     case 2:
     case 3:
     case 4:
+    case 5:
+    case 6:
       return true;
     default:
       return false;
@@ -993,6 +1003,14 @@
     case 2:
     case 3:
     case 4:
+    case 5:
+    case 6:
+    case 7:
+    case 8:
+    case 9:
+    case 10:
+    case 11:
+    case 12:
       return true;
     default:
       return false;
diff --git a/cpp/dmi/hw.pb.h b/cpp/dmi/hw.pb.h
index e32e1f0..e21c9a2 100644
--- a/cpp/dmi/hw.pb.h
+++ b/cpp/dmi/hw.pb.h
@@ -302,12 +302,14 @@
   COMP_ADMIN_STATE_LOCKED = 2,
   COMP_ADMIN_STATE_SHUTTING_DOWN = 3,
   COMP_ADMIN_STATE_UNLOCKED = 4,
+  COMP_ADMIN_STATE_ISOLATED = 6,
+  COMP_ADMIN_STATE_PROHIBITED = 5,
   ComponentAdminState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
   ComponentAdminState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 bool ComponentAdminState_IsValid(int value);
 const ComponentAdminState ComponentAdminState_MIN = COMP_ADMIN_STATE_UNDEFINED;
-const ComponentAdminState ComponentAdminState_MAX = COMP_ADMIN_STATE_UNLOCKED;
+const ComponentAdminState ComponentAdminState_MAX = COMP_ADMIN_STATE_ISOLATED;
 const int ComponentAdminState_ARRAYSIZE = ComponentAdminState_MAX + 1;
 
 const ::google::protobuf::EnumDescriptor* ComponentAdminState_descriptor();
@@ -326,12 +328,20 @@
   COMP_OPER_STATE_DISABLED = 2,
   COMP_OPER_STATE_ENABLED = 3,
   COMP_OPER_STATE_TESTING = 4,
+  COMP_OPER_STATE_NORMAL = 5,
+  COMP_OPER_STATE_CONFIGURING = 6,
+  COMP_OPER_STATE_AUTOMATIC_LOADING = 7,
+  COMP_OPER_STATE_FAILED = 8,
+  COMP_OPER_STATE_HIGH_TEMP_SHUTDOWN = 9,
+  COMP_OPER_STATE_MANUAL_SHUTDOWN = 10,
+  COMP_OPER_STATE_POWER_SAVING_SHUTDOWN = 11,
+  COMP_OPER_STATE_TYPE_MISMATCH = 12,
   ComponentOperState_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
   ComponentOperState_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 bool ComponentOperState_IsValid(int value);
 const ComponentOperState ComponentOperState_MIN = COMP_OPER_STATE_UNDEFINED;
-const ComponentOperState ComponentOperState_MAX = COMP_OPER_STATE_TESTING;
+const ComponentOperState ComponentOperState_MAX = COMP_OPER_STATE_TYPE_MISMATCH;
 const int ComponentOperState_ARRAYSIZE = ComponentOperState_MAX + 1;
 
 const ::google::protobuf::EnumDescriptor* ComponentOperState_descriptor();
diff --git a/cpp/dmi/hw_events_mgmt_service.pb.cc b/cpp/dmi/hw_events_mgmt_service.pb.cc
index 9166ef3..9a534e6 100644
--- a/cpp/dmi/hw_events_mgmt_service.pb.cc
+++ b/cpp/dmi/hw_events_mgmt_service.pb.cc
@@ -17,6 +17,11 @@
 #include <google/protobuf/port_def.inc>
 
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Uuid_dmi_2fhw_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_EventsCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
@@ -24,6 +29,7 @@
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<1> scc_info_WaterMarks_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_EventCfg_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<2> scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+extern PROTOBUF_INTERNAL_EXPORT_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto ::google::protobuf::internal::SCCInfo<5> scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
 extern PROTOBUF_INTERNAL_EXPORT_google_2fprotobuf_2ftimestamp_2eproto ::google::protobuf::internal::SCCInfo<0> scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto;
 namespace dmi {
 class ValueTypeDefaultTypeInternal {
@@ -73,6 +79,35 @@
  public:
   ::google::protobuf::internal::ExplicitlyConstructed<EventMetaData> _instance;
 } _EventMetaData_default_instance_;
+class AdminStateChangeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<AdminStateChange> _instance;
+} _AdminStateChange_default_instance_;
+class OperStateChangeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<OperStateChange> _instance;
+} _OperStateChange_default_instance_;
+class AlarmStateChangeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<AlarmStateChange> _instance;
+} _AlarmStateChange_default_instance_;
+class UsageStateChangeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<UsageStateChange> _instance;
+} _UsageStateChange_default_instance_;
+class StandbyStateChangeDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StandbyStateChange> _instance;
+} _StandbyStateChange_default_instance_;
+class StateChangeInfoDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<StateChangeInfo> _instance;
+  const ::dmi::AdminStateChange* admin_state_change_;
+  const ::dmi::OperStateChange* oper_state_change_;
+  const ::dmi::AlarmStateChange* alarm_state_change_;
+  const ::dmi::UsageStateChange* usage_state_change_;
+  const ::dmi::StandbyStateChange* standby_state_change_;
+} _StateChangeInfo_default_instance_;
 class EventDefaultTypeInternal {
  public:
   ::google::protobuf::internal::ExplicitlyConstructed<Event> _instance;
@@ -229,6 +264,95 @@
     {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
       &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
 
+static void InitDefaultsAdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_AdminStateChange_default_instance_;
+    new (ptr) ::dmi::AdminStateChange();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::AdminStateChange::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsOperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_OperStateChange_default_instance_;
+    new (ptr) ::dmi::OperStateChange();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::OperStateChange::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsOperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsAlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_AlarmStateChange_default_instance_;
+    new (ptr) ::dmi::AlarmStateChange();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::AlarmStateChange::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsAlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsUsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_UsageStateChange_default_instance_;
+    new (ptr) ::dmi::UsageStateChange();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::UsageStateChange::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsUsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsStandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StandbyStateChange_default_instance_;
+    new (ptr) ::dmi::StandbyStateChange();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StandbyStateChange::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsStandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {}};
+
+static void InitDefaultsStateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_StateChangeInfo_default_instance_;
+    new (ptr) ::dmi::StateChangeInfo();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::StateChangeInfo::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<5> scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 5, InitDefaultsStateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+      &scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+
 static void InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
 
@@ -240,11 +364,12 @@
   ::dmi::Event::InitAsDefaultInstance();
 }
 
-::google::protobuf::internal::SCCInfo<3> scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
-    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 3, InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
+::google::protobuf::internal::SCCInfo<4> scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 4, InitDefaultsEvent_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto}, {
       &scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
       &scc_info_Timestamp_google_2fprotobuf_2ftimestamp_2eproto.base,
-      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
+      &scc_info_ThresholdInformation_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,
+      &scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base,}};
 
 void InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
   ::google::protobuf::internal::InitSCC(&scc_info_ValueType_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
@@ -257,10 +382,16 @@
   ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationRequest_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_EventsConfigurationResponse_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_EventMetaData_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_Event_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[11];
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[17];
 const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[3];
 constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = nullptr;
 
@@ -347,6 +478,52 @@
   PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_uuid_),
   PROTOBUF_FIELD_OFFSET(::dmi::EventMetaData, component_name_),
   ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, old_),
+  PROTOBUF_FIELD_OFFSET(::dmi::AdminStateChange, new__),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, old_),
+  PROTOBUF_FIELD_OFFSET(::dmi::OperStateChange, new__),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, old_),
+  PROTOBUF_FIELD_OFFSET(::dmi::AlarmStateChange, new__),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, old_),
+  PROTOBUF_FIELD_OFFSET(::dmi::UsageStateChange, new__),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, old_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StandbyStateChange, new__),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, _internal_metadata_),
+  ~0u,  // no _extensions_
+  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, _oneof_case_[0]),
+  ~0u,  // no _weak_field_map_
+  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, admin_state_change_),
+  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, oper_state_change_),
+  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, alarm_state_change_),
+  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, usage_state_change_),
+  offsetof(::dmi::StateChangeInfoDefaultTypeInternal, standby_state_change_),
+  PROTOBUF_FIELD_OFFSET(::dmi::StateChangeInfo, state_change_),
+  ~0u,  // no _has_bits_
   PROTOBUF_FIELD_OFFSET(::dmi::Event, _internal_metadata_),
   ~0u,  // no _extensions_
   ~0u,  // no _oneof_case_
@@ -356,6 +533,7 @@
   PROTOBUF_FIELD_OFFSET(::dmi::Event, raised_ts_),
   PROTOBUF_FIELD_OFFSET(::dmi::Event, threshold_info_),
   PROTOBUF_FIELD_OFFSET(::dmi::Event, add_info_),
+  PROTOBUF_FIELD_OFFSET(::dmi::Event, state_change_info_),
 };
 static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
   { 0, -1, sizeof(::dmi::ValueType)},
@@ -368,7 +546,13 @@
   { 56, -1, sizeof(::dmi::EventsConfigurationRequest)},
   { 65, -1, sizeof(::dmi::EventsConfigurationResponse)},
   { 73, -1, sizeof(::dmi::EventMetaData)},
-  { 81, -1, sizeof(::dmi::Event)},
+  { 81, -1, sizeof(::dmi::AdminStateChange)},
+  { 88, -1, sizeof(::dmi::OperStateChange)},
+  { 95, -1, sizeof(::dmi::AlarmStateChange)},
+  { 102, -1, sizeof(::dmi::UsageStateChange)},
+  { 109, -1, sizeof(::dmi::StandbyStateChange)},
+  { 116, -1, sizeof(::dmi::StateChangeInfo)},
+  { 127, -1, sizeof(::dmi::Event)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -382,13 +566,19 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationRequest_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventsConfigurationResponse_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EventMetaData_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_AdminStateChange_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_OperStateChange_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_AlarmStateChange_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_UsageStateChange_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StandbyStateChange_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_StateChangeInfo_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Event_default_instance_),
 };
 
 ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
   {}, AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, "dmi/hw_events_mgmt_service.proto", schemas,
   file_default_instances, TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto::offsets,
-  file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 11, file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
+  file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 17, file_level_enum_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
 };
 
 const char descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[] =
@@ -428,85 +618,111 @@
   "_CONFIG\020\003\022\026\n\022DEVICE_UNREACHABLE\020\004\"j\n\rEve"
   "ntMetaData\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uu"
   "id\022!\n\016component_uuid\030\002 \001(\0132\t.dmi.Uuid\022\026\n"
-  "\016component_name\030\003 \001(\t\"\310\001\n\005Event\022*\n\016event"
-  "_metadata\030\001 \001(\0132\022.dmi.EventMetaData\022\037\n\010e"
-  "vent_id\030\002 \001(\0162\r.dmi.EventIds\022-\n\traised_t"
-  "s\030\003 \001(\0132\032.google.protobuf.Timestamp\0221\n\016t"
-  "hreshold_info\030\004 \001(\0132\031.dmi.ThresholdInfor"
-  "mation\022\020\n\010add_info\030\005 \001(\t*\342\022\n\010EventIds\022\030\n"
-  "\024EVENT_NAME_UNDEFINED\020\000\022\036\n\032EVENT_TRANSCE"
-  "IVER_PLUG_OUT\020d\022\035\n\031EVENT_TRANSCEIVER_PLU"
-  "G_IN\020e\022-\n)EVENT_TRANSCEIVER_VOLTAGE_ABOV"
-  "E_THRESHOLD\020f\022-\n)EVENT_TRANSCEIVER_VOLTA"
-  "GE_BELOW_THRESHOLD\020g\0221\n-EVENT_TRANSCEIVE"
-  "R_TEMPERATURE_ABOVE_THRESHOLD\020h\0221\n-EVENT"
-  "_TRANSCEIVER_TEMPERATURE_BELOW_THRESHOLD"
-  "\020i\022-\n)EVENT_TRANSCEIVER_CURRENT_ABOVE_TH"
-  "RESHOLD\020j\022-\n)EVENT_TRANSCEIVER_CURRENT_B"
-  "ELOW_THRESHOLD\020k\022.\n*EVENT_TRANSCEIVER_RX"
-  "_POWER_ABOVE_THRESHOLD\020l\022.\n*EVENT_TRANSC"
-  "EIVER_RX_POWER_BELOW_THRESHOLD\020m\022.\n*EVEN"
-  "T_TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD\020n"
-  "\022.\n*EVENT_TRANSCEIVER_TX_POWER_BELOW_THR"
-  "ESHOLD\020o\022\035\n\031EVENT_TRANSCEIVER_FAILURE\020p\022"
-  "7\n3EVENT_TRANSCEIVER_VOLTAGE_ABOVE_THRES"
-  "HOLD_RECOVERED\020q\0227\n3EVENT_TRANSCEIVER_VO"
-  "LTAGE_BELOW_THRESHOLD_RECOVERED\020r\022;\n7EVE"
-  "NT_TRANSCEIVER_TEMPERATURE_ABOVE_THRESHO"
-  "LD_RECOVERED\020s\022;\n7EVENT_TRANSCEIVER_TEMP"
-  "ERATURE_BELOW_THRESHOLD_RECOVERED\020t\0227\n3E"
-  "VENT_TRANSCEIVER_CURRENT_ABOVE_THRESHOLD"
-  "_RECOVERED\020u\0227\n3EVENT_TRANSCEIVER_CURREN"
-  "T_BELOW_THRESHOLD_RECOVERED\020v\0228\n4EVENT_T"
-  "RANSCEIVER_RX_POWER_ABOVE_THRESHOLD_RECO"
-  "VERED\020w\0228\n4EVENT_TRANSCEIVER_RX_POWER_BE"
-  "LOW_THRESHOLD_RECOVERED\020x\0228\n4EVENT_TRANS"
-  "CEIVER_TX_POWER_ABOVE_THRESHOLD_RECOVERE"
-  "D\020y\0228\n4EVENT_TRANSCEIVER_TX_POWER_BELOW_"
-  "THRESHOLD_RECOVERED\020z\022\'\n#EVENT_TRANSCEIV"
-  "ER_FAILURE_RECOVERED\020{\022\027\n\022EVENT_PSU_PLUG"
-  "_OUT\020\310\001\022\026\n\021EVENT_PSU_PLUG_IN\020\311\001\022\026\n\021EVENT"
-  "_PSU_FAILURE\020\312\001\022 \n\033EVENT_PSU_FAILURE_REC"
-  "OVERED\020\313\001\022\026\n\021EVENT_FAN_FAILURE\020\254\002\022\027\n\022EVE"
-  "NT_FAN_PLUG_OUT\020\255\002\022\026\n\021EVENT_FAN_PLUG_IN\020"
-  "\256\002\022 \n\033EVENT_FAN_FAILURE_RECOVERED\020\257\002\022)\n$"
-  "EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL\020\220\003\022"
-  "&\n!EVENT_CPU_TEMPERATURE_ABOVE_FATAL\020\221\003\022"
-  "3\n.EVENT_CPU_TEMPERATURE_ABOVE_CRITICAL_"
-  "RECOVERED\020\222\003\0220\n+EVENT_CPU_TEMPERATURE_AB"
-  "OVE_FATAL_RECOVERED\020\223\003\022$\n\037EVENT_CPU_USAG"
-  "E_ABOVE_THRESHOLD\020\224\003\022.\n)EVENT_CPU_USAGE_"
-  "ABOVE_THRESHOLD_RECOVERED\020\225\003\022\032\n\025EVENT_HW"
-  "_DEVICE_RESET\020\364\003\022/\n*EVENT_HW_DEVICE_TEMP"
-  "ERATURE_ABOVE_CRITICAL\020\365\003\022,\n\'EVENT_HW_DE"
-  "VICE_TEMPERATURE_ABOVE_FATAL\020\366\003\0229\n4EVENT"
-  "_HW_DEVICE_TEMPERATURE_ABOVE_CRITICAL_RE"
-  "COVERED\020\367\003\0226\n1EVENT_HW_DEVICE_TEMPERATUR"
-  "E_ABOVE_FATAL_RECOVERED\020\370\003\022\033\n\026EVENT_HW_D"
-  "EVICE_REBOOT\020\371\003\022\'\n\"EVENT_HW_TEMPERATURE_"
-  "SENSOR_FAILED\020\372\003\022,\n\'EVENT_HW_ALL_TEMPERA"
-  "TURE_SENSORS_FAILED\020\373\003\022(\n#EVENT_HW_DISK_"
-  "USAGE_ABOVE_THRESHOLD\020\374\003\0222\n-EVENT_HW_DIS"
-  "K_USAGE_ABOVE_THRESHOLD_RECOVERED\020\375\003\022*\n%"
-  "EVENT_HW_MEMORY_USAGE_ABOVE_THRESHOLD\020\376\003"
-  "\0224\n/EVENT_HW_MEMORY_USAGE_ABOVE_THRESHOL"
-  "D_RECOVERED\020\377\003\022\036\n\031EVENT_HW_NTP_SYNC_FAIL"
-  "URE\020\200\004\022(\n#EVENT_HW_NTP_SYNC_FAILURE_RECO"
-  "VERED\020\201\004\022\035\n\030EVENT_LINE_CARD_PLUG_OUT\020\330\004\022"
-  "\034\n\027EVENT_LINE_CARD_PLUG_IN\020\331\0042\355\001\n\035Native"
-  "EventsManagementService\0226\n\nListEvents\022\017."
-  "dmi.HardwareID\032\027.dmi.ListEventsResponse\022"
-  "^\n\031UpdateEventsConfiguration\022\037.dmi.Event"
-  "sConfigurationRequest\032 .dmi.EventsConfig"
-  "urationResponse\0224\n\014StreamEvents\022\026.google"
-  ".protobuf.Empty\032\n.dmi.Event0\001B;Z9github."
-  "com/opencord/device-management-interface"
-  "/v3/go/dmib\006proto3"
+  "\016component_name\030\003 \001(\t\"`\n\020AdminStateChang"
+  "e\022%\n\003old\030\001 \001(\0162\030.dmi.ComponentAdminState"
+  "\022%\n\003new\030\002 \001(\0162\030.dmi.ComponentAdminState\""
+  "]\n\017OperStateChange\022$\n\003old\030\001 \001(\0162\027.dmi.Co"
+  "mponentOperState\022$\n\003new\030\002 \001(\0162\027.dmi.Comp"
+  "onentOperState\"`\n\020AlarmStateChange\022%\n\003ol"
+  "d\030\001 \001(\0162\030.dmi.ComponentAlarmState\022%\n\003new"
+  "\030\002 \001(\0162\030.dmi.ComponentAlarmState\"`\n\020Usag"
+  "eStateChange\022%\n\003old\030\001 \001(\0162\030.dmi.Componen"
+  "tUsageState\022%\n\003new\030\002 \001(\0162\030.dmi.Component"
+  "UsageState\"f\n\022StandbyStateChange\022\'\n\003old\030"
+  "\001 \001(\0162\032.dmi.ComponentStandbyState\022\'\n\003new"
+  "\030\002 \001(\0162\032.dmi.ComponentStandbyState\"\254\002\n\017S"
+  "tateChangeInfo\0223\n\022admin_state_change\030\001 \001"
+  "(\0132\025.dmi.AdminStateChangeH\000\0221\n\021oper_stat"
+  "e_change\030\002 \001(\0132\024.dmi.OperStateChangeH\000\0223"
+  "\n\022alarm_state_change\030\003 \001(\0132\025.dmi.AlarmSt"
+  "ateChangeH\000\0223\n\022usage_state_change\030\004 \001(\0132"
+  "\025.dmi.UsageStateChangeH\000\0227\n\024standby_stat"
+  "e_change\030\005 \001(\0132\027.dmi.StandbyStateChangeH"
+  "\000B\016\n\014state_change\"\371\001\n\005Event\022*\n\016event_met"
+  "adata\030\001 \001(\0132\022.dmi.EventMetaData\022\037\n\010event"
+  "_id\030\002 \001(\0162\r.dmi.EventIds\022-\n\traised_ts\030\003 "
+  "\001(\0132\032.google.protobuf.Timestamp\0221\n\016thres"
+  "hold_info\030\004 \001(\0132\031.dmi.ThresholdInformati"
+  "on\022\020\n\010add_info\030\005 \001(\t\022/\n\021state_change_inf"
+  "o\030\006 \001(\0132\024.dmi.StateChangeInfo*\265\024\n\010EventI"
+  "ds\022\030\n\024EVENT_NAME_UNDEFINED\020\000\022\036\n\032EVENT_TR"
+  "ANSCEIVER_PLUG_OUT\020d\022\035\n\031EVENT_TRANSCEIVE"
+  "R_PLUG_IN\020e\022-\n)EVENT_TRANSCEIVER_VOLTAGE"
+  "_ABOVE_THRESHOLD\020f\022-\n)EVENT_TRANSCEIVER_"
+  "VOLTAGE_BELOW_THRESHOLD\020g\0221\n-EVENT_TRANS"
+  "CEIVER_TEMPERATURE_ABOVE_THRESHOLD\020h\0221\n-"
+  "EVENT_TRANSCEIVER_TEMPERATURE_BELOW_THRE"
+  "SHOLD\020i\022-\n)EVENT_TRANSCEIVER_CURRENT_ABO"
+  "VE_THRESHOLD\020j\022-\n)EVENT_TRANSCEIVER_CURR"
+  "ENT_BELOW_THRESHOLD\020k\022.\n*EVENT_TRANSCEIV"
+  "ER_RX_POWER_ABOVE_THRESHOLD\020l\022.\n*EVENT_T"
+  "RANSCEIVER_RX_POWER_BELOW_THRESHOLD\020m\022.\n"
+  "*EVENT_TRANSCEIVER_TX_POWER_ABOVE_THRESH"
+  "OLD\020n\022.\n*EVENT_TRANSCEIVER_TX_POWER_BELO"
+  "W_THRESHOLD\020o\022\035\n\031EVENT_TRANSCEIVER_FAILU"
+  "RE\020p\0227\n3EVENT_TRANSCEIVER_VOLTAGE_ABOVE_"
+  "THRESHOLD_RECOVERED\020q\0227\n3EVENT_TRANSCEIV"
+  "ER_VOLTAGE_BELOW_THRESHOLD_RECOVERED\020r\022;"
+  "\n7EVENT_TRANSCEIVER_TEMPERATURE_ABOVE_TH"
+  "RESHOLD_RECOVERED\020s\022;\n7EVENT_TRANSCEIVER"
+  "_TEMPERATURE_BELOW_THRESHOLD_RECOVERED\020t"
+  "\0227\n3EVENT_TRANSCEIVER_CURRENT_ABOVE_THRE"
+  "SHOLD_RECOVERED\020u\0227\n3EVENT_TRANSCEIVER_C"
+  "URRENT_BELOW_THRESHOLD_RECOVERED\020v\0228\n4EV"
+  "ENT_TRANSCEIVER_RX_POWER_ABOVE_THRESHOLD"
+  "_RECOVERED\020w\0228\n4EVENT_TRANSCEIVER_RX_POW"
+  "ER_BELOW_THRESHOLD_RECOVERED\020x\0228\n4EVENT_"
+  "TRANSCEIVER_TX_POWER_ABOVE_THRESHOLD_REC"
+  "OVERED\020y\0228\n4EVENT_TRANSCEIVER_TX_POWER_B"
+  "ELOW_THRESHOLD_RECOVERED\020z\022\'\n#EVENT_TRAN"
+  "SCEIVER_FAILURE_RECOVERED\020{\022\027\n\022EVENT_PSU"
+  "_PLUG_OUT\020\310\001\022\026\n\021EVENT_PSU_PLUG_IN\020\311\001\022\026\n\021"
+  "EVENT_PSU_FAILURE\020\312\001\022 \n\033EVENT_PSU_FAILUR"
+  "E_RECOVERED\020\313\001\022\026\n\021EVENT_FAN_FAILURE\020\254\002\022\027"
+  "\n\022EVENT_FAN_PLUG_OUT\020\255\002\022\026\n\021EVENT_FAN_PLU"
+  "G_IN\020\256\002\022 \n\033EVENT_FAN_FAILURE_RECOVERED\020\257"
+  "\002\022)\n$EVENT_CPU_TEMPERATURE_ABOVE_CRITICA"
+  "L\020\220\003\022&\n!EVENT_CPU_TEMPERATURE_ABOVE_FATA"
+  "L\020\221\003\0223\n.EVENT_CPU_TEMPERATURE_ABOVE_CRIT"
+  "ICAL_RECOVERED\020\222\003\0220\n+EVENT_CPU_TEMPERATU"
+  "RE_ABOVE_FATAL_RECOVERED\020\223\003\022$\n\037EVENT_CPU"
+  "_USAGE_ABOVE_THRESHOLD\020\224\003\022.\n)EVENT_CPU_U"
+  "SAGE_ABOVE_THRESHOLD_RECOVERED\020\225\003\022\032\n\025EVE"
+  "NT_HW_DEVICE_RESET\020\364\003\022/\n*EVENT_HW_DEVICE"
+  "_TEMPERATURE_ABOVE_CRITICAL\020\365\003\022,\n\'EVENT_"
+  "HW_DEVICE_TEMPERATURE_ABOVE_FATAL\020\366\003\0229\n4"
+  "EVENT_HW_DEVICE_TEMPERATURE_ABOVE_CRITIC"
+  "AL_RECOVERED\020\367\003\0226\n1EVENT_HW_DEVICE_TEMPE"
+  "RATURE_ABOVE_FATAL_RECOVERED\020\370\003\022\033\n\026EVENT"
+  "_HW_DEVICE_REBOOT\020\371\003\022\'\n\"EVENT_HW_TEMPERA"
+  "TURE_SENSOR_FAILED\020\372\003\022,\n\'EVENT_HW_ALL_TE"
+  "MPERATURE_SENSORS_FAILED\020\373\003\022(\n#EVENT_HW_"
+  "DISK_USAGE_ABOVE_THRESHOLD\020\374\003\0222\n-EVENT_H"
+  "W_DISK_USAGE_ABOVE_THRESHOLD_RECOVERED\020\375"
+  "\003\022*\n%EVENT_HW_MEMORY_USAGE_ABOVE_THRESHO"
+  "LD\020\376\003\0224\n/EVENT_HW_MEMORY_USAGE_ABOVE_THR"
+  "ESHOLD_RECOVERED\020\377\003\022\036\n\031EVENT_HW_NTP_SYNC"
+  "_FAILURE\020\200\004\022(\n#EVENT_HW_NTP_SYNC_FAILURE"
+  "_RECOVERED\020\201\004\022\035\n\030EVENT_LINE_CARD_PLUG_OU"
+  "T\020\330\004\022\034\n\027EVENT_LINE_CARD_PLUG_IN\020\331\004\022(\n#EV"
+  "ENT_COMPONENT_ADMIN_STATE_CHANGED\020\274\005\022\'\n\""
+  "EVENT_COMPONENT_OPER_STATE_CHANGED\020\275\005\022(\n"
+  "#EVENT_COMPONENT_ALARM_STATE_CHANGED\020\276\005\022"
+  "(\n#EVENT_COMPONENT_USAGE_STATE_CHANGED\020\277"
+  "\005\022*\n%EVENT_COMPONENT_STANDBY_STATE_CHANG"
+  "ED\020\300\0052\355\001\n\035NativeEventsManagementService\022"
+  "6\n\nListEvents\022\017.dmi.HardwareID\032\027.dmi.Lis"
+  "tEventsResponse\022^\n\031UpdateEventsConfigura"
+  "tion\022\037.dmi.EventsConfigurationRequest\032 ."
+  "dmi.EventsConfigurationResponse\0224\n\014Strea"
+  "mEvents\022\026.google.protobuf.Empty\032\n.dmi.Ev"
+  "ent0\001B;Z9github.com/opencord/device-mana"
+  "gement-interface/v3/go/dmib\006proto3"
   ;
 ::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto = {
   false, InitDefaults_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 
   descriptor_table_protodef_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto,
-  "dmi/hw_events_mgmt_service.proto", &assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 4378,
+  "dmi/hw_events_mgmt_service.proto", &assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto, 5434,
 };
 
 void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto() {
@@ -636,6 +852,11 @@
     case 513:
     case 600:
     case 601:
+    case 700:
+    case 701:
+    case 702:
+    case 703:
+    case 704:
       return true;
     default:
       return false;
@@ -4705,6 +4926,2220 @@
 
 // ===================================================================
 
+void AdminStateChange::InitAsDefaultInstance() {
+}
+class AdminStateChange::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int AdminStateChange::kOldFieldNumber;
+const int AdminStateChange::kNewFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+AdminStateChange::AdminStateChange()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.AdminStateChange)
+}
+AdminStateChange::AdminStateChange(const AdminStateChange& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&old_, &from.old_,
+    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
+    reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  // @@protoc_insertion_point(copy_constructor:dmi.AdminStateChange)
+}
+
+void AdminStateChange::SharedCtor() {
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+}
+
+AdminStateChange::~AdminStateChange() {
+  // @@protoc_insertion_point(destructor:dmi.AdminStateChange)
+  SharedDtor();
+}
+
+void AdminStateChange::SharedDtor() {
+}
+
+void AdminStateChange::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const AdminStateChange& AdminStateChange::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_AdminStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void AdminStateChange::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.AdminStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* AdminStateChange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<AdminStateChange*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ComponentAdminState old = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_old(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentAdminState new = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_new_(static_cast<::dmi::ComponentAdminState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool AdminStateChange::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.AdminStateChange)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ComponentAdminState old = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_old(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAdminState new = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_new_(static_cast< ::dmi::ComponentAdminState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.AdminStateChange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.AdminStateChange)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void AdminStateChange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.AdminStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAdminState old = 1;
+  if (this->old() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->old(), output);
+  }
+
+  // .dmi.ComponentAdminState new = 2;
+  if (this->new_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->new_(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.AdminStateChange)
+}
+
+::google::protobuf::uint8* AdminStateChange::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.AdminStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAdminState old = 1;
+  if (this->old() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->old(), target);
+  }
+
+  // .dmi.ComponentAdminState new = 2;
+  if (this->new_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->new_(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.AdminStateChange)
+  return target;
+}
+
+size_t AdminStateChange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.AdminStateChange)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAdminState old = 1;
+  if (this->old() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
+  }
+
+  // .dmi.ComponentAdminState new = 2;
+  if (this->new_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void AdminStateChange::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.AdminStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  const AdminStateChange* source =
+      ::google::protobuf::DynamicCastToGenerated<AdminStateChange>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.AdminStateChange)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.AdminStateChange)
+    MergeFrom(*source);
+  }
+}
+
+void AdminStateChange::MergeFrom(const AdminStateChange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.AdminStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.old() != 0) {
+    set_old(from.old());
+  }
+  if (from.new_() != 0) {
+    set_new_(from.new_());
+  }
+}
+
+void AdminStateChange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.AdminStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void AdminStateChange::CopyFrom(const AdminStateChange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.AdminStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool AdminStateChange::IsInitialized() const {
+  return true;
+}
+
+void AdminStateChange::Swap(AdminStateChange* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void AdminStateChange::InternalSwap(AdminStateChange* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(old_, other->old_);
+  swap(new__, other->new__);
+}
+
+::google::protobuf::Metadata AdminStateChange::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void OperStateChange::InitAsDefaultInstance() {
+}
+class OperStateChange::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int OperStateChange::kOldFieldNumber;
+const int OperStateChange::kNewFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+OperStateChange::OperStateChange()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.OperStateChange)
+}
+OperStateChange::OperStateChange(const OperStateChange& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&old_, &from.old_,
+    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
+    reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  // @@protoc_insertion_point(copy_constructor:dmi.OperStateChange)
+}
+
+void OperStateChange::SharedCtor() {
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+}
+
+OperStateChange::~OperStateChange() {
+  // @@protoc_insertion_point(destructor:dmi.OperStateChange)
+  SharedDtor();
+}
+
+void OperStateChange::SharedDtor() {
+}
+
+void OperStateChange::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const OperStateChange& OperStateChange::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_OperStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void OperStateChange::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.OperStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* OperStateChange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<OperStateChange*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ComponentOperState old = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_old(static_cast<::dmi::ComponentOperState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentOperState new = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_new_(static_cast<::dmi::ComponentOperState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool OperStateChange::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.OperStateChange)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ComponentOperState old = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_old(static_cast< ::dmi::ComponentOperState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentOperState new = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_new_(static_cast< ::dmi::ComponentOperState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.OperStateChange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.OperStateChange)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void OperStateChange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.OperStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentOperState old = 1;
+  if (this->old() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->old(), output);
+  }
+
+  // .dmi.ComponentOperState new = 2;
+  if (this->new_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->new_(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.OperStateChange)
+}
+
+::google::protobuf::uint8* OperStateChange::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.OperStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentOperState old = 1;
+  if (this->old() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->old(), target);
+  }
+
+  // .dmi.ComponentOperState new = 2;
+  if (this->new_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->new_(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.OperStateChange)
+  return target;
+}
+
+size_t OperStateChange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.OperStateChange)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ComponentOperState old = 1;
+  if (this->old() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
+  }
+
+  // .dmi.ComponentOperState new = 2;
+  if (this->new_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void OperStateChange::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.OperStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  const OperStateChange* source =
+      ::google::protobuf::DynamicCastToGenerated<OperStateChange>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.OperStateChange)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.OperStateChange)
+    MergeFrom(*source);
+  }
+}
+
+void OperStateChange::MergeFrom(const OperStateChange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.OperStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.old() != 0) {
+    set_old(from.old());
+  }
+  if (from.new_() != 0) {
+    set_new_(from.new_());
+  }
+}
+
+void OperStateChange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.OperStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void OperStateChange::CopyFrom(const OperStateChange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.OperStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool OperStateChange::IsInitialized() const {
+  return true;
+}
+
+void OperStateChange::Swap(OperStateChange* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void OperStateChange::InternalSwap(OperStateChange* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(old_, other->old_);
+  swap(new__, other->new__);
+}
+
+::google::protobuf::Metadata OperStateChange::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void AlarmStateChange::InitAsDefaultInstance() {
+}
+class AlarmStateChange::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int AlarmStateChange::kOldFieldNumber;
+const int AlarmStateChange::kNewFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+AlarmStateChange::AlarmStateChange()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.AlarmStateChange)
+}
+AlarmStateChange::AlarmStateChange(const AlarmStateChange& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&old_, &from.old_,
+    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
+    reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  // @@protoc_insertion_point(copy_constructor:dmi.AlarmStateChange)
+}
+
+void AlarmStateChange::SharedCtor() {
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+}
+
+AlarmStateChange::~AlarmStateChange() {
+  // @@protoc_insertion_point(destructor:dmi.AlarmStateChange)
+  SharedDtor();
+}
+
+void AlarmStateChange::SharedDtor() {
+}
+
+void AlarmStateChange::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const AlarmStateChange& AlarmStateChange::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_AlarmStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void AlarmStateChange::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.AlarmStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* AlarmStateChange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<AlarmStateChange*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ComponentAlarmState old = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_old(static_cast<::dmi::ComponentAlarmState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentAlarmState new = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_new_(static_cast<::dmi::ComponentAlarmState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool AlarmStateChange::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.AlarmStateChange)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ComponentAlarmState old = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_old(static_cast< ::dmi::ComponentAlarmState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentAlarmState new = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_new_(static_cast< ::dmi::ComponentAlarmState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.AlarmStateChange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.AlarmStateChange)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void AlarmStateChange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.AlarmStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAlarmState old = 1;
+  if (this->old() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->old(), output);
+  }
+
+  // .dmi.ComponentAlarmState new = 2;
+  if (this->new_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->new_(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.AlarmStateChange)
+}
+
+::google::protobuf::uint8* AlarmStateChange::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.AlarmStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAlarmState old = 1;
+  if (this->old() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->old(), target);
+  }
+
+  // .dmi.ComponentAlarmState new = 2;
+  if (this->new_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->new_(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.AlarmStateChange)
+  return target;
+}
+
+size_t AlarmStateChange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.AlarmStateChange)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ComponentAlarmState old = 1;
+  if (this->old() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
+  }
+
+  // .dmi.ComponentAlarmState new = 2;
+  if (this->new_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void AlarmStateChange::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.AlarmStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  const AlarmStateChange* source =
+      ::google::protobuf::DynamicCastToGenerated<AlarmStateChange>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.AlarmStateChange)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.AlarmStateChange)
+    MergeFrom(*source);
+  }
+}
+
+void AlarmStateChange::MergeFrom(const AlarmStateChange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.AlarmStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.old() != 0) {
+    set_old(from.old());
+  }
+  if (from.new_() != 0) {
+    set_new_(from.new_());
+  }
+}
+
+void AlarmStateChange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.AlarmStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void AlarmStateChange::CopyFrom(const AlarmStateChange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.AlarmStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool AlarmStateChange::IsInitialized() const {
+  return true;
+}
+
+void AlarmStateChange::Swap(AlarmStateChange* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void AlarmStateChange::InternalSwap(AlarmStateChange* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(old_, other->old_);
+  swap(new__, other->new__);
+}
+
+::google::protobuf::Metadata AlarmStateChange::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void UsageStateChange::InitAsDefaultInstance() {
+}
+class UsageStateChange::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int UsageStateChange::kOldFieldNumber;
+const int UsageStateChange::kNewFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+UsageStateChange::UsageStateChange()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.UsageStateChange)
+}
+UsageStateChange::UsageStateChange(const UsageStateChange& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&old_, &from.old_,
+    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
+    reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  // @@protoc_insertion_point(copy_constructor:dmi.UsageStateChange)
+}
+
+void UsageStateChange::SharedCtor() {
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+}
+
+UsageStateChange::~UsageStateChange() {
+  // @@protoc_insertion_point(destructor:dmi.UsageStateChange)
+  SharedDtor();
+}
+
+void UsageStateChange::SharedDtor() {
+}
+
+void UsageStateChange::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const UsageStateChange& UsageStateChange::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_UsageStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void UsageStateChange::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.UsageStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* UsageStateChange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<UsageStateChange*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ComponentUsageState old = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_old(static_cast<::dmi::ComponentUsageState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentUsageState new = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_new_(static_cast<::dmi::ComponentUsageState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool UsageStateChange::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.UsageStateChange)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ComponentUsageState old = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_old(static_cast< ::dmi::ComponentUsageState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentUsageState new = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_new_(static_cast< ::dmi::ComponentUsageState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.UsageStateChange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.UsageStateChange)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void UsageStateChange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.UsageStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentUsageState old = 1;
+  if (this->old() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->old(), output);
+  }
+
+  // .dmi.ComponentUsageState new = 2;
+  if (this->new_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->new_(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.UsageStateChange)
+}
+
+::google::protobuf::uint8* UsageStateChange::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.UsageStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentUsageState old = 1;
+  if (this->old() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->old(), target);
+  }
+
+  // .dmi.ComponentUsageState new = 2;
+  if (this->new_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->new_(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.UsageStateChange)
+  return target;
+}
+
+size_t UsageStateChange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.UsageStateChange)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ComponentUsageState old = 1;
+  if (this->old() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
+  }
+
+  // .dmi.ComponentUsageState new = 2;
+  if (this->new_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void UsageStateChange::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.UsageStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  const UsageStateChange* source =
+      ::google::protobuf::DynamicCastToGenerated<UsageStateChange>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.UsageStateChange)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.UsageStateChange)
+    MergeFrom(*source);
+  }
+}
+
+void UsageStateChange::MergeFrom(const UsageStateChange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.UsageStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.old() != 0) {
+    set_old(from.old());
+  }
+  if (from.new_() != 0) {
+    set_new_(from.new_());
+  }
+}
+
+void UsageStateChange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.UsageStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void UsageStateChange::CopyFrom(const UsageStateChange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.UsageStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool UsageStateChange::IsInitialized() const {
+  return true;
+}
+
+void UsageStateChange::Swap(UsageStateChange* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void UsageStateChange::InternalSwap(UsageStateChange* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(old_, other->old_);
+  swap(new__, other->new__);
+}
+
+::google::protobuf::Metadata UsageStateChange::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StandbyStateChange::InitAsDefaultInstance() {
+}
+class StandbyStateChange::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StandbyStateChange::kOldFieldNumber;
+const int StandbyStateChange::kNewFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StandbyStateChange::StandbyStateChange()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StandbyStateChange)
+}
+StandbyStateChange::StandbyStateChange(const StandbyStateChange& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::memcpy(&old_, &from.old_,
+    static_cast<size_t>(reinterpret_cast<char*>(&new__) -
+    reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  // @@protoc_insertion_point(copy_constructor:dmi.StandbyStateChange)
+}
+
+void StandbyStateChange::SharedCtor() {
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+}
+
+StandbyStateChange::~StandbyStateChange() {
+  // @@protoc_insertion_point(destructor:dmi.StandbyStateChange)
+  SharedDtor();
+}
+
+void StandbyStateChange::SharedDtor() {
+}
+
+void StandbyStateChange::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StandbyStateChange& StandbyStateChange::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StandbyStateChange_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StandbyStateChange::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StandbyStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  ::memset(&old_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&new__) -
+      reinterpret_cast<char*>(&old_)) + sizeof(new__));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StandbyStateChange::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StandbyStateChange*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.ComponentStandbyState old = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_old(static_cast<::dmi::ComponentStandbyState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ComponentStandbyState new = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_new_(static_cast<::dmi::ComponentStandbyState>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StandbyStateChange::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StandbyStateChange)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.ComponentStandbyState old = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_old(static_cast< ::dmi::ComponentStandbyState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ComponentStandbyState new = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_new_(static_cast< ::dmi::ComponentStandbyState >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StandbyStateChange)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StandbyStateChange)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StandbyStateChange::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StandbyStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentStandbyState old = 1;
+  if (this->old() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->old(), output);
+  }
+
+  // .dmi.ComponentStandbyState new = 2;
+  if (this->new_() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->new_(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StandbyStateChange)
+}
+
+::google::protobuf::uint8* StandbyStateChange::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StandbyStateChange)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.ComponentStandbyState old = 1;
+  if (this->old() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->old(), target);
+  }
+
+  // .dmi.ComponentStandbyState new = 2;
+  if (this->new_() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->new_(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StandbyStateChange)
+  return target;
+}
+
+size_t StandbyStateChange::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StandbyStateChange)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // .dmi.ComponentStandbyState old = 1;
+  if (this->old() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->old());
+  }
+
+  // .dmi.ComponentStandbyState new = 2;
+  if (this->new_() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->new_());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StandbyStateChange::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StandbyStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StandbyStateChange* source =
+      ::google::protobuf::DynamicCastToGenerated<StandbyStateChange>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StandbyStateChange)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StandbyStateChange)
+    MergeFrom(*source);
+  }
+}
+
+void StandbyStateChange::MergeFrom(const StandbyStateChange& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StandbyStateChange)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.old() != 0) {
+    set_old(from.old());
+  }
+  if (from.new_() != 0) {
+    set_new_(from.new_());
+  }
+}
+
+void StandbyStateChange::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StandbyStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StandbyStateChange::CopyFrom(const StandbyStateChange& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StandbyStateChange)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StandbyStateChange::IsInitialized() const {
+  return true;
+}
+
+void StandbyStateChange::Swap(StandbyStateChange* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StandbyStateChange::InternalSwap(StandbyStateChange* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(old_, other->old_);
+  swap(new__, other->new__);
+}
+
+::google::protobuf::Metadata StandbyStateChange::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void StateChangeInfo::InitAsDefaultInstance() {
+  ::dmi::_StateChangeInfo_default_instance_.admin_state_change_ = const_cast< ::dmi::AdminStateChange*>(
+      ::dmi::AdminStateChange::internal_default_instance());
+  ::dmi::_StateChangeInfo_default_instance_.oper_state_change_ = const_cast< ::dmi::OperStateChange*>(
+      ::dmi::OperStateChange::internal_default_instance());
+  ::dmi::_StateChangeInfo_default_instance_.alarm_state_change_ = const_cast< ::dmi::AlarmStateChange*>(
+      ::dmi::AlarmStateChange::internal_default_instance());
+  ::dmi::_StateChangeInfo_default_instance_.usage_state_change_ = const_cast< ::dmi::UsageStateChange*>(
+      ::dmi::UsageStateChange::internal_default_instance());
+  ::dmi::_StateChangeInfo_default_instance_.standby_state_change_ = const_cast< ::dmi::StandbyStateChange*>(
+      ::dmi::StandbyStateChange::internal_default_instance());
+}
+class StateChangeInfo::HasBitSetters {
+ public:
+  static const ::dmi::AdminStateChange& admin_state_change(const StateChangeInfo* msg);
+  static const ::dmi::OperStateChange& oper_state_change(const StateChangeInfo* msg);
+  static const ::dmi::AlarmStateChange& alarm_state_change(const StateChangeInfo* msg);
+  static const ::dmi::UsageStateChange& usage_state_change(const StateChangeInfo* msg);
+  static const ::dmi::StandbyStateChange& standby_state_change(const StateChangeInfo* msg);
+};
+
+const ::dmi::AdminStateChange&
+StateChangeInfo::HasBitSetters::admin_state_change(const StateChangeInfo* msg) {
+  return *msg->state_change_.admin_state_change_;
+}
+const ::dmi::OperStateChange&
+StateChangeInfo::HasBitSetters::oper_state_change(const StateChangeInfo* msg) {
+  return *msg->state_change_.oper_state_change_;
+}
+const ::dmi::AlarmStateChange&
+StateChangeInfo::HasBitSetters::alarm_state_change(const StateChangeInfo* msg) {
+  return *msg->state_change_.alarm_state_change_;
+}
+const ::dmi::UsageStateChange&
+StateChangeInfo::HasBitSetters::usage_state_change(const StateChangeInfo* msg) {
+  return *msg->state_change_.usage_state_change_;
+}
+const ::dmi::StandbyStateChange&
+StateChangeInfo::HasBitSetters::standby_state_change(const StateChangeInfo* msg) {
+  return *msg->state_change_.standby_state_change_;
+}
+void StateChangeInfo::set_allocated_admin_state_change(::dmi::AdminStateChange* admin_state_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_state_change();
+  if (admin_state_change) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      admin_state_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, admin_state_change, submessage_arena);
+    }
+    set_has_admin_state_change();
+    state_change_.admin_state_change_ = admin_state_change;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.admin_state_change)
+}
+void StateChangeInfo::set_allocated_oper_state_change(::dmi::OperStateChange* oper_state_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_state_change();
+  if (oper_state_change) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      oper_state_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, oper_state_change, submessage_arena);
+    }
+    set_has_oper_state_change();
+    state_change_.oper_state_change_ = oper_state_change;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.oper_state_change)
+}
+void StateChangeInfo::set_allocated_alarm_state_change(::dmi::AlarmStateChange* alarm_state_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_state_change();
+  if (alarm_state_change) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      alarm_state_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, alarm_state_change, submessage_arena);
+    }
+    set_has_alarm_state_change();
+    state_change_.alarm_state_change_ = alarm_state_change;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.alarm_state_change)
+}
+void StateChangeInfo::set_allocated_usage_state_change(::dmi::UsageStateChange* usage_state_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_state_change();
+  if (usage_state_change) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      usage_state_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, usage_state_change, submessage_arena);
+    }
+    set_has_usage_state_change();
+    state_change_.usage_state_change_ = usage_state_change;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.usage_state_change)
+}
+void StateChangeInfo::set_allocated_standby_state_change(::dmi::StandbyStateChange* standby_state_change) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  clear_state_change();
+  if (standby_state_change) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      standby_state_change = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, standby_state_change, submessage_arena);
+    }
+    set_has_standby_state_change();
+    state_change_.standby_state_change_ = standby_state_change;
+  }
+  // @@protoc_insertion_point(field_set_allocated:dmi.StateChangeInfo.standby_state_change)
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int StateChangeInfo::kAdminStateChangeFieldNumber;
+const int StateChangeInfo::kOperStateChangeFieldNumber;
+const int StateChangeInfo::kAlarmStateChangeFieldNumber;
+const int StateChangeInfo::kUsageStateChangeFieldNumber;
+const int StateChangeInfo::kStandbyStateChangeFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+StateChangeInfo::StateChangeInfo()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.StateChangeInfo)
+}
+StateChangeInfo::StateChangeInfo(const StateChangeInfo& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  clear_has_state_change();
+  switch (from.state_change_case()) {
+    case kAdminStateChange: {
+      mutable_admin_state_change()->::dmi::AdminStateChange::MergeFrom(from.admin_state_change());
+      break;
+    }
+    case kOperStateChange: {
+      mutable_oper_state_change()->::dmi::OperStateChange::MergeFrom(from.oper_state_change());
+      break;
+    }
+    case kAlarmStateChange: {
+      mutable_alarm_state_change()->::dmi::AlarmStateChange::MergeFrom(from.alarm_state_change());
+      break;
+    }
+    case kUsageStateChange: {
+      mutable_usage_state_change()->::dmi::UsageStateChange::MergeFrom(from.usage_state_change());
+      break;
+    }
+    case kStandbyStateChange: {
+      mutable_standby_state_change()->::dmi::StandbyStateChange::MergeFrom(from.standby_state_change());
+      break;
+    }
+    case STATE_CHANGE_NOT_SET: {
+      break;
+    }
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.StateChangeInfo)
+}
+
+void StateChangeInfo::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  clear_has_state_change();
+}
+
+StateChangeInfo::~StateChangeInfo() {
+  // @@protoc_insertion_point(destructor:dmi.StateChangeInfo)
+  SharedDtor();
+}
+
+void StateChangeInfo::SharedDtor() {
+  if (has_state_change()) {
+    clear_state_change();
+  }
+}
+
+void StateChangeInfo::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const StateChangeInfo& StateChangeInfo::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_StateChangeInfo_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void StateChangeInfo::clear_state_change() {
+// @@protoc_insertion_point(one_of_clear_start:dmi.StateChangeInfo)
+  switch (state_change_case()) {
+    case kAdminStateChange: {
+      delete state_change_.admin_state_change_;
+      break;
+    }
+    case kOperStateChange: {
+      delete state_change_.oper_state_change_;
+      break;
+    }
+    case kAlarmStateChange: {
+      delete state_change_.alarm_state_change_;
+      break;
+    }
+    case kUsageStateChange: {
+      delete state_change_.usage_state_change_;
+      break;
+    }
+    case kStandbyStateChange: {
+      delete state_change_.standby_state_change_;
+      break;
+    }
+    case STATE_CHANGE_NOT_SET: {
+      break;
+    }
+  }
+  _oneof_case_[0] = STATE_CHANGE_NOT_SET;
+}
+
+
+void StateChangeInfo::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.StateChangeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  clear_state_change();
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* StateChangeInfo::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<StateChangeInfo*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.AdminStateChange admin_state_change = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::AdminStateChange::_InternalParse;
+        object = msg->mutable_admin_state_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.OperStateChange oper_state_change = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::OperStateChange::_InternalParse;
+        object = msg->mutable_oper_state_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.AlarmStateChange alarm_state_change = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::AlarmStateChange::_InternalParse;
+        object = msg->mutable_alarm_state_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.UsageStateChange usage_state_change = 4;
+      case 4: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 34) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::UsageStateChange::_InternalParse;
+        object = msg->mutable_usage_state_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.StandbyStateChange standby_state_change = 5;
+      case 5: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 42) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::StandbyStateChange::_InternalParse;
+        object = msg->mutable_standby_state_change();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool StateChangeInfo::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.StateChangeInfo)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.AdminStateChange admin_state_change = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_admin_state_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.OperStateChange oper_state_change = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_oper_state_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.AlarmStateChange alarm_state_change = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_alarm_state_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.UsageStateChange usage_state_change = 4;
+      case 4: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (34 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_usage_state_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.StandbyStateChange standby_state_change = 5;
+      case 5: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (42 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_standby_state_change()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.StateChangeInfo)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.StateChangeInfo)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void StateChangeInfo::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.StateChangeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.AdminStateChange admin_state_change = 1;
+  if (has_admin_state_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::admin_state_change(this), output);
+  }
+
+  // .dmi.OperStateChange oper_state_change = 2;
+  if (has_oper_state_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::oper_state_change(this), output);
+  }
+
+  // .dmi.AlarmStateChange alarm_state_change = 3;
+  if (has_alarm_state_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      3, HasBitSetters::alarm_state_change(this), output);
+  }
+
+  // .dmi.UsageStateChange usage_state_change = 4;
+  if (has_usage_state_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      4, HasBitSetters::usage_state_change(this), output);
+  }
+
+  // .dmi.StandbyStateChange standby_state_change = 5;
+  if (has_standby_state_change()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      5, HasBitSetters::standby_state_change(this), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.StateChangeInfo)
+}
+
+::google::protobuf::uint8* StateChangeInfo::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.StateChangeInfo)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.AdminStateChange admin_state_change = 1;
+  if (has_admin_state_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::admin_state_change(this), target);
+  }
+
+  // .dmi.OperStateChange oper_state_change = 2;
+  if (has_oper_state_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::oper_state_change(this), target);
+  }
+
+  // .dmi.AlarmStateChange alarm_state_change = 3;
+  if (has_alarm_state_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        3, HasBitSetters::alarm_state_change(this), target);
+  }
+
+  // .dmi.UsageStateChange usage_state_change = 4;
+  if (has_usage_state_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        4, HasBitSetters::usage_state_change(this), target);
+  }
+
+  // .dmi.StandbyStateChange standby_state_change = 5;
+  if (has_standby_state_change()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        5, HasBitSetters::standby_state_change(this), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.StateChangeInfo)
+  return target;
+}
+
+size_t StateChangeInfo::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.StateChangeInfo)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  switch (state_change_case()) {
+    // .dmi.AdminStateChange admin_state_change = 1;
+    case kAdminStateChange: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *state_change_.admin_state_change_);
+      break;
+    }
+    // .dmi.OperStateChange oper_state_change = 2;
+    case kOperStateChange: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *state_change_.oper_state_change_);
+      break;
+    }
+    // .dmi.AlarmStateChange alarm_state_change = 3;
+    case kAlarmStateChange: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *state_change_.alarm_state_change_);
+      break;
+    }
+    // .dmi.UsageStateChange usage_state_change = 4;
+    case kUsageStateChange: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *state_change_.usage_state_change_);
+      break;
+    }
+    // .dmi.StandbyStateChange standby_state_change = 5;
+    case kStandbyStateChange: {
+      total_size += 1 +
+        ::google::protobuf::internal::WireFormatLite::MessageSize(
+          *state_change_.standby_state_change_);
+      break;
+    }
+    case STATE_CHANGE_NOT_SET: {
+      break;
+    }
+  }
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void StateChangeInfo::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.StateChangeInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  const StateChangeInfo* source =
+      ::google::protobuf::DynamicCastToGenerated<StateChangeInfo>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.StateChangeInfo)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.StateChangeInfo)
+    MergeFrom(*source);
+  }
+}
+
+void StateChangeInfo::MergeFrom(const StateChangeInfo& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.StateChangeInfo)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  switch (from.state_change_case()) {
+    case kAdminStateChange: {
+      mutable_admin_state_change()->::dmi::AdminStateChange::MergeFrom(from.admin_state_change());
+      break;
+    }
+    case kOperStateChange: {
+      mutable_oper_state_change()->::dmi::OperStateChange::MergeFrom(from.oper_state_change());
+      break;
+    }
+    case kAlarmStateChange: {
+      mutable_alarm_state_change()->::dmi::AlarmStateChange::MergeFrom(from.alarm_state_change());
+      break;
+    }
+    case kUsageStateChange: {
+      mutable_usage_state_change()->::dmi::UsageStateChange::MergeFrom(from.usage_state_change());
+      break;
+    }
+    case kStandbyStateChange: {
+      mutable_standby_state_change()->::dmi::StandbyStateChange::MergeFrom(from.standby_state_change());
+      break;
+    }
+    case STATE_CHANGE_NOT_SET: {
+      break;
+    }
+  }
+}
+
+void StateChangeInfo::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.StateChangeInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void StateChangeInfo::CopyFrom(const StateChangeInfo& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.StateChangeInfo)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool StateChangeInfo::IsInitialized() const {
+  return true;
+}
+
+void StateChangeInfo::Swap(StateChangeInfo* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void StateChangeInfo::InternalSwap(StateChangeInfo* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  swap(state_change_, other->state_change_);
+  swap(_oneof_case_[0], other->_oneof_case_[0]);
+}
+
+::google::protobuf::Metadata StateChangeInfo::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
 void Event::InitAsDefaultInstance() {
   ::dmi::_Event_default_instance_._instance.get_mutable()->event_metadata_ = const_cast< ::dmi::EventMetaData*>(
       ::dmi::EventMetaData::internal_default_instance());
@@ -4712,12 +7147,15 @@
       ::google::protobuf::Timestamp::internal_default_instance());
   ::dmi::_Event_default_instance_._instance.get_mutable()->threshold_info_ = const_cast< ::dmi::ThresholdInformation*>(
       ::dmi::ThresholdInformation::internal_default_instance());
+  ::dmi::_Event_default_instance_._instance.get_mutable()->state_change_info_ = const_cast< ::dmi::StateChangeInfo*>(
+      ::dmi::StateChangeInfo::internal_default_instance());
 }
 class Event::HasBitSetters {
  public:
   static const ::dmi::EventMetaData& event_metadata(const Event* msg);
   static const ::google::protobuf::Timestamp& raised_ts(const Event* msg);
   static const ::dmi::ThresholdInformation& threshold_info(const Event* msg);
+  static const ::dmi::StateChangeInfo& state_change_info(const Event* msg);
 };
 
 const ::dmi::EventMetaData&
@@ -4732,6 +7170,10 @@
 Event::HasBitSetters::threshold_info(const Event* msg) {
   return *msg->threshold_info_;
 }
+const ::dmi::StateChangeInfo&
+Event::HasBitSetters::state_change_info(const Event* msg) {
+  return *msg->state_change_info_;
+}
 void Event::clear_raised_ts() {
   if (GetArenaNoVirtual() == nullptr && raised_ts_ != nullptr) {
     delete raised_ts_;
@@ -4744,6 +7186,7 @@
 const int Event::kRaisedTsFieldNumber;
 const int Event::kThresholdInfoFieldNumber;
 const int Event::kAddInfoFieldNumber;
+const int Event::kStateChangeInfoFieldNumber;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 Event::Event()
@@ -4774,6 +7217,11 @@
   } else {
     threshold_info_ = nullptr;
   }
+  if (from.has_state_change_info()) {
+    state_change_info_ = new ::dmi::StateChangeInfo(*from.state_change_info_);
+  } else {
+    state_change_info_ = nullptr;
+  }
   event_id_ = from.event_id_;
   // @@protoc_insertion_point(copy_constructor:dmi.Event)
 }
@@ -4797,6 +7245,7 @@
   if (this != internal_default_instance()) delete event_metadata_;
   if (this != internal_default_instance()) delete raised_ts_;
   if (this != internal_default_instance()) delete threshold_info_;
+  if (this != internal_default_instance()) delete state_change_info_;
 }
 
 void Event::SetCachedSize(int size) const {
@@ -4827,6 +7276,10 @@
     delete threshold_info_;
   }
   threshold_info_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && state_change_info_ != nullptr) {
+    delete state_change_info_;
+  }
+  state_change_info_ = nullptr;
   event_id_ = 0;
   _internal_metadata_.Clear();
 }
@@ -4907,6 +7360,19 @@
         ptr += size;
         break;
       }
+      // .dmi.StateChangeInfo state_change_info = 6;
+      case 6: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 50) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::StateChangeInfo::_InternalParse;
+        object = msg->mutable_state_change_info();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
       default: {
       handle_unusual:
         if ((tag & 7) == 4 || tag == 0) {
@@ -5003,6 +7469,17 @@
         break;
       }
 
+      // .dmi.StateChangeInfo state_change_info = 6;
+      case 6: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (50 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_state_change_info()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
       default: {
       handle_unusual:
         if (tag == 0) {
@@ -5064,6 +7541,12 @@
       5, this->add_info(), output);
   }
 
+  // .dmi.StateChangeInfo state_change_info = 6;
+  if (this->has_state_change_info()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      6, HasBitSetters::state_change_info(this), output);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
         _internal_metadata_.unknown_fields(), output);
@@ -5115,6 +7598,13 @@
         5, this->add_info(), target);
   }
 
+  // .dmi.StateChangeInfo state_change_info = 6;
+  if (this->has_state_change_info()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        6, HasBitSetters::state_change_info(this), target);
+  }
+
   if (_internal_metadata_.have_unknown_fields()) {
     target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
         _internal_metadata_.unknown_fields(), target);
@@ -5164,6 +7654,13 @@
         *threshold_info_);
   }
 
+  // .dmi.StateChangeInfo state_change_info = 6;
+  if (this->has_state_change_info()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *state_change_info_);
+  }
+
   // .dmi.EventIds event_id = 2;
   if (this->event_id() != 0) {
     total_size += 1 +
@@ -5210,6 +7707,9 @@
   if (from.has_threshold_info()) {
     mutable_threshold_info()->::dmi::ThresholdInformation::MergeFrom(from.threshold_info());
   }
+  if (from.has_state_change_info()) {
+    mutable_state_change_info()->::dmi::StateChangeInfo::MergeFrom(from.state_change_info());
+  }
   if (from.event_id() != 0) {
     set_event_id(from.event_id());
   }
@@ -5245,6 +7745,7 @@
   swap(event_metadata_, other->event_metadata_);
   swap(raised_ts_, other->raised_ts_);
   swap(threshold_info_, other->threshold_info_);
+  swap(state_change_info_, other->state_change_info_);
   swap(event_id_, other->event_id_);
 }
 
@@ -5288,6 +7789,24 @@
 template<> PROTOBUF_NOINLINE ::dmi::EventMetaData* Arena::CreateMaybeMessage< ::dmi::EventMetaData >(Arena* arena) {
   return Arena::CreateInternal< ::dmi::EventMetaData >(arena);
 }
+template<> PROTOBUF_NOINLINE ::dmi::AdminStateChange* Arena::CreateMaybeMessage< ::dmi::AdminStateChange >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::AdminStateChange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::OperStateChange* Arena::CreateMaybeMessage< ::dmi::OperStateChange >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::OperStateChange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::AlarmStateChange* Arena::CreateMaybeMessage< ::dmi::AlarmStateChange >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::AlarmStateChange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::UsageStateChange* Arena::CreateMaybeMessage< ::dmi::UsageStateChange >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::UsageStateChange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StandbyStateChange* Arena::CreateMaybeMessage< ::dmi::StandbyStateChange >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StandbyStateChange >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::StateChangeInfo* Arena::CreateMaybeMessage< ::dmi::StateChangeInfo >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::StateChangeInfo >(arena);
+}
 template<> PROTOBUF_NOINLINE ::dmi::Event* Arena::CreateMaybeMessage< ::dmi::Event >(Arena* arena) {
   return Arena::CreateInternal< ::dmi::Event >(arena);
 }
diff --git a/cpp/dmi/hw_events_mgmt_service.pb.h b/cpp/dmi/hw_events_mgmt_service.pb.h
index 4c4dfe9..7e3e8bd 100644
--- a/cpp/dmi/hw_events_mgmt_service.pb.h
+++ b/cpp/dmi/hw_events_mgmt_service.pb.h
@@ -46,7 +46,7 @@
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
-  static const ::google::protobuf::internal::ParseTable schema[11]
+  static const ::google::protobuf::internal::ParseTable schema[17]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
@@ -54,6 +54,12 @@
 };
 void AddDescriptors_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto();
 namespace dmi {
+class AdminStateChange;
+class AdminStateChangeDefaultTypeInternal;
+extern AdminStateChangeDefaultTypeInternal _AdminStateChange_default_instance_;
+class AlarmStateChange;
+class AlarmStateChangeDefaultTypeInternal;
+extern AlarmStateChangeDefaultTypeInternal _AlarmStateChange_default_instance_;
 class Event;
 class EventDefaultTypeInternal;
 extern EventDefaultTypeInternal _Event_default_instance_;
@@ -75,12 +81,24 @@
 class ListEventsResponse;
 class ListEventsResponseDefaultTypeInternal;
 extern ListEventsResponseDefaultTypeInternal _ListEventsResponse_default_instance_;
+class OperStateChange;
+class OperStateChangeDefaultTypeInternal;
+extern OperStateChangeDefaultTypeInternal _OperStateChange_default_instance_;
+class StandbyStateChange;
+class StandbyStateChangeDefaultTypeInternal;
+extern StandbyStateChangeDefaultTypeInternal _StandbyStateChange_default_instance_;
+class StateChangeInfo;
+class StateChangeInfoDefaultTypeInternal;
+extern StateChangeInfoDefaultTypeInternal _StateChangeInfo_default_instance_;
 class ThresholdInformation;
 class ThresholdInformationDefaultTypeInternal;
 extern ThresholdInformationDefaultTypeInternal _ThresholdInformation_default_instance_;
 class Thresholds;
 class ThresholdsDefaultTypeInternal;
 extern ThresholdsDefaultTypeInternal _Thresholds_default_instance_;
+class UsageStateChange;
+class UsageStateChangeDefaultTypeInternal;
+extern UsageStateChangeDefaultTypeInternal _UsageStateChange_default_instance_;
 class ValueType;
 class ValueTypeDefaultTypeInternal;
 extern ValueTypeDefaultTypeInternal _ValueType_default_instance_;
@@ -90,6 +108,8 @@
 }  // namespace dmi
 namespace google {
 namespace protobuf {
+template<> ::dmi::AdminStateChange* Arena::CreateMaybeMessage<::dmi::AdminStateChange>(Arena*);
+template<> ::dmi::AlarmStateChange* Arena::CreateMaybeMessage<::dmi::AlarmStateChange>(Arena*);
 template<> ::dmi::Event* Arena::CreateMaybeMessage<::dmi::Event>(Arena*);
 template<> ::dmi::EventCfg* Arena::CreateMaybeMessage<::dmi::EventCfg>(Arena*);
 template<> ::dmi::EventMetaData* Arena::CreateMaybeMessage<::dmi::EventMetaData>(Arena*);
@@ -97,8 +117,12 @@
 template<> ::dmi::EventsConfigurationRequest* Arena::CreateMaybeMessage<::dmi::EventsConfigurationRequest>(Arena*);
 template<> ::dmi::EventsConfigurationResponse* Arena::CreateMaybeMessage<::dmi::EventsConfigurationResponse>(Arena*);
 template<> ::dmi::ListEventsResponse* Arena::CreateMaybeMessage<::dmi::ListEventsResponse>(Arena*);
+template<> ::dmi::OperStateChange* Arena::CreateMaybeMessage<::dmi::OperStateChange>(Arena*);
+template<> ::dmi::StandbyStateChange* Arena::CreateMaybeMessage<::dmi::StandbyStateChange>(Arena*);
+template<> ::dmi::StateChangeInfo* Arena::CreateMaybeMessage<::dmi::StateChangeInfo>(Arena*);
 template<> ::dmi::ThresholdInformation* Arena::CreateMaybeMessage<::dmi::ThresholdInformation>(Arena*);
 template<> ::dmi::Thresholds* Arena::CreateMaybeMessage<::dmi::Thresholds>(Arena*);
+template<> ::dmi::UsageStateChange* Arena::CreateMaybeMessage<::dmi::UsageStateChange>(Arena*);
 template<> ::dmi::ValueType* Arena::CreateMaybeMessage<::dmi::ValueType>(Arena*);
 template<> ::dmi::WaterMarks* Arena::CreateMaybeMessage<::dmi::WaterMarks>(Arena*);
 }  // namespace protobuf
@@ -208,12 +232,17 @@
   EVENT_HW_NTP_SYNC_FAILURE_RECOVERED = 513,
   EVENT_LINE_CARD_PLUG_OUT = 600,
   EVENT_LINE_CARD_PLUG_IN = 601,
+  EVENT_COMPONENT_ADMIN_STATE_CHANGED = 700,
+  EVENT_COMPONENT_OPER_STATE_CHANGED = 701,
+  EVENT_COMPONENT_ALARM_STATE_CHANGED = 702,
+  EVENT_COMPONENT_USAGE_STATE_CHANGED = 703,
+  EVENT_COMPONENT_STANDBY_STATE_CHANGED = 704,
   EventIds_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
   EventIds_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
 };
 bool EventIds_IsValid(int value);
 const EventIds EventIds_MIN = EVENT_NAME_UNDEFINED;
-const EventIds EventIds_MAX = EVENT_LINE_CARD_PLUG_IN;
+const EventIds EventIds_MAX = EVENT_COMPONENT_STANDBY_STATE_CHANGED;
 const int EventIds_ARRAYSIZE = EventIds_MAX + 1;
 
 const ::google::protobuf::EnumDescriptor* EventIds_descriptor();
@@ -1673,6 +1702,780 @@
 };
 // -------------------------------------------------------------------
 
+class AdminStateChange final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.AdminStateChange) */ {
+ public:
+  AdminStateChange();
+  virtual ~AdminStateChange();
+
+  AdminStateChange(const AdminStateChange& from);
+
+  inline AdminStateChange& operator=(const AdminStateChange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  AdminStateChange(AdminStateChange&& from) noexcept
+    : AdminStateChange() {
+    *this = ::std::move(from);
+  }
+
+  inline AdminStateChange& operator=(AdminStateChange&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const AdminStateChange& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const AdminStateChange* internal_default_instance() {
+    return reinterpret_cast<const AdminStateChange*>(
+               &_AdminStateChange_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    10;
+
+  void Swap(AdminStateChange* other);
+  friend void swap(AdminStateChange& a, AdminStateChange& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline AdminStateChange* New() const final {
+    return CreateMaybeMessage<AdminStateChange>(nullptr);
+  }
+
+  AdminStateChange* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<AdminStateChange>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const AdminStateChange& from);
+  void MergeFrom(const AdminStateChange& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(AdminStateChange* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ComponentAdminState old = 1;
+  void clear_old();
+  static const int kOldFieldNumber = 1;
+  ::dmi::ComponentAdminState old() const;
+  void set_old(::dmi::ComponentAdminState value);
+
+  // .dmi.ComponentAdminState new = 2;
+  void clear_new_();
+  static const int kNewFieldNumber = 2;
+  ::dmi::ComponentAdminState new_() const;
+  void set_new_(::dmi::ComponentAdminState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.AdminStateChange)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int old_;
+  int new__;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class OperStateChange final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.OperStateChange) */ {
+ public:
+  OperStateChange();
+  virtual ~OperStateChange();
+
+  OperStateChange(const OperStateChange& from);
+
+  inline OperStateChange& operator=(const OperStateChange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  OperStateChange(OperStateChange&& from) noexcept
+    : OperStateChange() {
+    *this = ::std::move(from);
+  }
+
+  inline OperStateChange& operator=(OperStateChange&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const OperStateChange& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const OperStateChange* internal_default_instance() {
+    return reinterpret_cast<const OperStateChange*>(
+               &_OperStateChange_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    11;
+
+  void Swap(OperStateChange* other);
+  friend void swap(OperStateChange& a, OperStateChange& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline OperStateChange* New() const final {
+    return CreateMaybeMessage<OperStateChange>(nullptr);
+  }
+
+  OperStateChange* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<OperStateChange>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const OperStateChange& from);
+  void MergeFrom(const OperStateChange& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(OperStateChange* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ComponentOperState old = 1;
+  void clear_old();
+  static const int kOldFieldNumber = 1;
+  ::dmi::ComponentOperState old() const;
+  void set_old(::dmi::ComponentOperState value);
+
+  // .dmi.ComponentOperState new = 2;
+  void clear_new_();
+  static const int kNewFieldNumber = 2;
+  ::dmi::ComponentOperState new_() const;
+  void set_new_(::dmi::ComponentOperState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.OperStateChange)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int old_;
+  int new__;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class AlarmStateChange final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.AlarmStateChange) */ {
+ public:
+  AlarmStateChange();
+  virtual ~AlarmStateChange();
+
+  AlarmStateChange(const AlarmStateChange& from);
+
+  inline AlarmStateChange& operator=(const AlarmStateChange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  AlarmStateChange(AlarmStateChange&& from) noexcept
+    : AlarmStateChange() {
+    *this = ::std::move(from);
+  }
+
+  inline AlarmStateChange& operator=(AlarmStateChange&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const AlarmStateChange& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const AlarmStateChange* internal_default_instance() {
+    return reinterpret_cast<const AlarmStateChange*>(
+               &_AlarmStateChange_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    12;
+
+  void Swap(AlarmStateChange* other);
+  friend void swap(AlarmStateChange& a, AlarmStateChange& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline AlarmStateChange* New() const final {
+    return CreateMaybeMessage<AlarmStateChange>(nullptr);
+  }
+
+  AlarmStateChange* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<AlarmStateChange>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const AlarmStateChange& from);
+  void MergeFrom(const AlarmStateChange& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(AlarmStateChange* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ComponentAlarmState old = 1;
+  void clear_old();
+  static const int kOldFieldNumber = 1;
+  ::dmi::ComponentAlarmState old() const;
+  void set_old(::dmi::ComponentAlarmState value);
+
+  // .dmi.ComponentAlarmState new = 2;
+  void clear_new_();
+  static const int kNewFieldNumber = 2;
+  ::dmi::ComponentAlarmState new_() const;
+  void set_new_(::dmi::ComponentAlarmState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.AlarmStateChange)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int old_;
+  int new__;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class UsageStateChange final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.UsageStateChange) */ {
+ public:
+  UsageStateChange();
+  virtual ~UsageStateChange();
+
+  UsageStateChange(const UsageStateChange& from);
+
+  inline UsageStateChange& operator=(const UsageStateChange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  UsageStateChange(UsageStateChange&& from) noexcept
+    : UsageStateChange() {
+    *this = ::std::move(from);
+  }
+
+  inline UsageStateChange& operator=(UsageStateChange&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const UsageStateChange& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const UsageStateChange* internal_default_instance() {
+    return reinterpret_cast<const UsageStateChange*>(
+               &_UsageStateChange_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    13;
+
+  void Swap(UsageStateChange* other);
+  friend void swap(UsageStateChange& a, UsageStateChange& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline UsageStateChange* New() const final {
+    return CreateMaybeMessage<UsageStateChange>(nullptr);
+  }
+
+  UsageStateChange* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<UsageStateChange>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const UsageStateChange& from);
+  void MergeFrom(const UsageStateChange& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(UsageStateChange* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ComponentUsageState old = 1;
+  void clear_old();
+  static const int kOldFieldNumber = 1;
+  ::dmi::ComponentUsageState old() const;
+  void set_old(::dmi::ComponentUsageState value);
+
+  // .dmi.ComponentUsageState new = 2;
+  void clear_new_();
+  static const int kNewFieldNumber = 2;
+  ::dmi::ComponentUsageState new_() const;
+  void set_new_(::dmi::ComponentUsageState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.UsageStateChange)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int old_;
+  int new__;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StandbyStateChange final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StandbyStateChange) */ {
+ public:
+  StandbyStateChange();
+  virtual ~StandbyStateChange();
+
+  StandbyStateChange(const StandbyStateChange& from);
+
+  inline StandbyStateChange& operator=(const StandbyStateChange& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StandbyStateChange(StandbyStateChange&& from) noexcept
+    : StandbyStateChange() {
+    *this = ::std::move(from);
+  }
+
+  inline StandbyStateChange& operator=(StandbyStateChange&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const StandbyStateChange& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StandbyStateChange* internal_default_instance() {
+    return reinterpret_cast<const StandbyStateChange*>(
+               &_StandbyStateChange_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    14;
+
+  void Swap(StandbyStateChange* other);
+  friend void swap(StandbyStateChange& a, StandbyStateChange& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StandbyStateChange* New() const final {
+    return CreateMaybeMessage<StandbyStateChange>(nullptr);
+  }
+
+  StandbyStateChange* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StandbyStateChange>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StandbyStateChange& from);
+  void MergeFrom(const StandbyStateChange& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(StandbyStateChange* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.ComponentStandbyState old = 1;
+  void clear_old();
+  static const int kOldFieldNumber = 1;
+  ::dmi::ComponentStandbyState old() const;
+  void set_old(::dmi::ComponentStandbyState value);
+
+  // .dmi.ComponentStandbyState new = 2;
+  void clear_new_();
+  static const int kNewFieldNumber = 2;
+  ::dmi::ComponentStandbyState new_() const;
+  void set_new_(::dmi::ComponentStandbyState value);
+
+  // @@protoc_insertion_point(class_scope:dmi.StandbyStateChange)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  int old_;
+  int new__;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class StateChangeInfo final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.StateChangeInfo) */ {
+ public:
+  StateChangeInfo();
+  virtual ~StateChangeInfo();
+
+  StateChangeInfo(const StateChangeInfo& from);
+
+  inline StateChangeInfo& operator=(const StateChangeInfo& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  StateChangeInfo(StateChangeInfo&& from) noexcept
+    : StateChangeInfo() {
+    *this = ::std::move(from);
+  }
+
+  inline StateChangeInfo& operator=(StateChangeInfo&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const StateChangeInfo& default_instance();
+
+  enum StateChangeCase {
+    kAdminStateChange = 1,
+    kOperStateChange = 2,
+    kAlarmStateChange = 3,
+    kUsageStateChange = 4,
+    kStandbyStateChange = 5,
+    STATE_CHANGE_NOT_SET = 0,
+  };
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const StateChangeInfo* internal_default_instance() {
+    return reinterpret_cast<const StateChangeInfo*>(
+               &_StateChangeInfo_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    15;
+
+  void Swap(StateChangeInfo* other);
+  friend void swap(StateChangeInfo& a, StateChangeInfo& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline StateChangeInfo* New() const final {
+    return CreateMaybeMessage<StateChangeInfo>(nullptr);
+  }
+
+  StateChangeInfo* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<StateChangeInfo>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const StateChangeInfo& from);
+  void MergeFrom(const StateChangeInfo& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(StateChangeInfo* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // .dmi.AdminStateChange admin_state_change = 1;
+  bool has_admin_state_change() const;
+  void clear_admin_state_change();
+  static const int kAdminStateChangeFieldNumber = 1;
+  const ::dmi::AdminStateChange& admin_state_change() const;
+  ::dmi::AdminStateChange* release_admin_state_change();
+  ::dmi::AdminStateChange* mutable_admin_state_change();
+  void set_allocated_admin_state_change(::dmi::AdminStateChange* admin_state_change);
+
+  // .dmi.OperStateChange oper_state_change = 2;
+  bool has_oper_state_change() const;
+  void clear_oper_state_change();
+  static const int kOperStateChangeFieldNumber = 2;
+  const ::dmi::OperStateChange& oper_state_change() const;
+  ::dmi::OperStateChange* release_oper_state_change();
+  ::dmi::OperStateChange* mutable_oper_state_change();
+  void set_allocated_oper_state_change(::dmi::OperStateChange* oper_state_change);
+
+  // .dmi.AlarmStateChange alarm_state_change = 3;
+  bool has_alarm_state_change() const;
+  void clear_alarm_state_change();
+  static const int kAlarmStateChangeFieldNumber = 3;
+  const ::dmi::AlarmStateChange& alarm_state_change() const;
+  ::dmi::AlarmStateChange* release_alarm_state_change();
+  ::dmi::AlarmStateChange* mutable_alarm_state_change();
+  void set_allocated_alarm_state_change(::dmi::AlarmStateChange* alarm_state_change);
+
+  // .dmi.UsageStateChange usage_state_change = 4;
+  bool has_usage_state_change() const;
+  void clear_usage_state_change();
+  static const int kUsageStateChangeFieldNumber = 4;
+  const ::dmi::UsageStateChange& usage_state_change() const;
+  ::dmi::UsageStateChange* release_usage_state_change();
+  ::dmi::UsageStateChange* mutable_usage_state_change();
+  void set_allocated_usage_state_change(::dmi::UsageStateChange* usage_state_change);
+
+  // .dmi.StandbyStateChange standby_state_change = 5;
+  bool has_standby_state_change() const;
+  void clear_standby_state_change();
+  static const int kStandbyStateChangeFieldNumber = 5;
+  const ::dmi::StandbyStateChange& standby_state_change() const;
+  ::dmi::StandbyStateChange* release_standby_state_change();
+  ::dmi::StandbyStateChange* mutable_standby_state_change();
+  void set_allocated_standby_state_change(::dmi::StandbyStateChange* standby_state_change);
+
+  void clear_state_change();
+  StateChangeCase state_change_case() const;
+  // @@protoc_insertion_point(class_scope:dmi.StateChangeInfo)
+ private:
+  class HasBitSetters;
+  void set_has_admin_state_change();
+  void set_has_oper_state_change();
+  void set_has_alarm_state_change();
+  void set_has_usage_state_change();
+  void set_has_standby_state_change();
+
+  inline bool has_state_change() const;
+  inline void clear_has_state_change();
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  union StateChangeUnion {
+    StateChangeUnion() {}
+    ::dmi::AdminStateChange* admin_state_change_;
+    ::dmi::OperStateChange* oper_state_change_;
+    ::dmi::AlarmStateChange* alarm_state_change_;
+    ::dmi::UsageStateChange* usage_state_change_;
+    ::dmi::StandbyStateChange* standby_state_change_;
+  } state_change_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  ::google::protobuf::uint32 _oneof_case_[1];
+
+  friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
 class Event final :
     public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.Event) */ {
  public:
@@ -1711,7 +2514,7 @@
                &_Event_default_instance_);
   }
   static constexpr int kIndexInFileMessages =
-    10;
+    16;
 
   void Swap(Event* other);
   friend void swap(Event& a, Event& b) {
@@ -1809,6 +2612,15 @@
   ::dmi::ThresholdInformation* mutable_threshold_info();
   void set_allocated_threshold_info(::dmi::ThresholdInformation* threshold_info);
 
+  // .dmi.StateChangeInfo state_change_info = 6;
+  bool has_state_change_info() const;
+  void clear_state_change_info();
+  static const int kStateChangeInfoFieldNumber = 6;
+  const ::dmi::StateChangeInfo& state_change_info() const;
+  ::dmi::StateChangeInfo* release_state_change_info();
+  ::dmi::StateChangeInfo* mutable_state_change_info();
+  void set_allocated_state_change_info(::dmi::StateChangeInfo* state_change_info);
+
   // .dmi.EventIds event_id = 2;
   void clear_event_id();
   static const int kEventIdFieldNumber = 2;
@@ -1824,6 +2636,7 @@
   ::dmi::EventMetaData* event_metadata_;
   ::google::protobuf::Timestamp* raised_ts_;
   ::dmi::ThresholdInformation* threshold_info_;
+  ::dmi::StateChangeInfo* state_change_info_;
   int event_id_;
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   friend struct ::TableStruct_dmi_2fhw_5fevents_5fmgmt_5fservice_2eproto;
@@ -2916,6 +3729,384 @@
 
 // -------------------------------------------------------------------
 
+// AdminStateChange
+
+// .dmi.ComponentAdminState old = 1;
+inline void AdminStateChange::clear_old() {
+  old_ = 0;
+}
+inline ::dmi::ComponentAdminState AdminStateChange::old() const {
+  // @@protoc_insertion_point(field_get:dmi.AdminStateChange.old)
+  return static_cast< ::dmi::ComponentAdminState >(old_);
+}
+inline void AdminStateChange::set_old(::dmi::ComponentAdminState value) {
+  
+  old_ = value;
+  // @@protoc_insertion_point(field_set:dmi.AdminStateChange.old)
+}
+
+// .dmi.ComponentAdminState new = 2;
+inline void AdminStateChange::clear_new_() {
+  new__ = 0;
+}
+inline ::dmi::ComponentAdminState AdminStateChange::new_() const {
+  // @@protoc_insertion_point(field_get:dmi.AdminStateChange.new)
+  return static_cast< ::dmi::ComponentAdminState >(new__);
+}
+inline void AdminStateChange::set_new_(::dmi::ComponentAdminState value) {
+  
+  new__ = value;
+  // @@protoc_insertion_point(field_set:dmi.AdminStateChange.new)
+}
+
+// -------------------------------------------------------------------
+
+// OperStateChange
+
+// .dmi.ComponentOperState old = 1;
+inline void OperStateChange::clear_old() {
+  old_ = 0;
+}
+inline ::dmi::ComponentOperState OperStateChange::old() const {
+  // @@protoc_insertion_point(field_get:dmi.OperStateChange.old)
+  return static_cast< ::dmi::ComponentOperState >(old_);
+}
+inline void OperStateChange::set_old(::dmi::ComponentOperState value) {
+  
+  old_ = value;
+  // @@protoc_insertion_point(field_set:dmi.OperStateChange.old)
+}
+
+// .dmi.ComponentOperState new = 2;
+inline void OperStateChange::clear_new_() {
+  new__ = 0;
+}
+inline ::dmi::ComponentOperState OperStateChange::new_() const {
+  // @@protoc_insertion_point(field_get:dmi.OperStateChange.new)
+  return static_cast< ::dmi::ComponentOperState >(new__);
+}
+inline void OperStateChange::set_new_(::dmi::ComponentOperState value) {
+  
+  new__ = value;
+  // @@protoc_insertion_point(field_set:dmi.OperStateChange.new)
+}
+
+// -------------------------------------------------------------------
+
+// AlarmStateChange
+
+// .dmi.ComponentAlarmState old = 1;
+inline void AlarmStateChange::clear_old() {
+  old_ = 0;
+}
+inline ::dmi::ComponentAlarmState AlarmStateChange::old() const {
+  // @@protoc_insertion_point(field_get:dmi.AlarmStateChange.old)
+  return static_cast< ::dmi::ComponentAlarmState >(old_);
+}
+inline void AlarmStateChange::set_old(::dmi::ComponentAlarmState value) {
+  
+  old_ = value;
+  // @@protoc_insertion_point(field_set:dmi.AlarmStateChange.old)
+}
+
+// .dmi.ComponentAlarmState new = 2;
+inline void AlarmStateChange::clear_new_() {
+  new__ = 0;
+}
+inline ::dmi::ComponentAlarmState AlarmStateChange::new_() const {
+  // @@protoc_insertion_point(field_get:dmi.AlarmStateChange.new)
+  return static_cast< ::dmi::ComponentAlarmState >(new__);
+}
+inline void AlarmStateChange::set_new_(::dmi::ComponentAlarmState value) {
+  
+  new__ = value;
+  // @@protoc_insertion_point(field_set:dmi.AlarmStateChange.new)
+}
+
+// -------------------------------------------------------------------
+
+// UsageStateChange
+
+// .dmi.ComponentUsageState old = 1;
+inline void UsageStateChange::clear_old() {
+  old_ = 0;
+}
+inline ::dmi::ComponentUsageState UsageStateChange::old() const {
+  // @@protoc_insertion_point(field_get:dmi.UsageStateChange.old)
+  return static_cast< ::dmi::ComponentUsageState >(old_);
+}
+inline void UsageStateChange::set_old(::dmi::ComponentUsageState value) {
+  
+  old_ = value;
+  // @@protoc_insertion_point(field_set:dmi.UsageStateChange.old)
+}
+
+// .dmi.ComponentUsageState new = 2;
+inline void UsageStateChange::clear_new_() {
+  new__ = 0;
+}
+inline ::dmi::ComponentUsageState UsageStateChange::new_() const {
+  // @@protoc_insertion_point(field_get:dmi.UsageStateChange.new)
+  return static_cast< ::dmi::ComponentUsageState >(new__);
+}
+inline void UsageStateChange::set_new_(::dmi::ComponentUsageState value) {
+  
+  new__ = value;
+  // @@protoc_insertion_point(field_set:dmi.UsageStateChange.new)
+}
+
+// -------------------------------------------------------------------
+
+// StandbyStateChange
+
+// .dmi.ComponentStandbyState old = 1;
+inline void StandbyStateChange::clear_old() {
+  old_ = 0;
+}
+inline ::dmi::ComponentStandbyState StandbyStateChange::old() const {
+  // @@protoc_insertion_point(field_get:dmi.StandbyStateChange.old)
+  return static_cast< ::dmi::ComponentStandbyState >(old_);
+}
+inline void StandbyStateChange::set_old(::dmi::ComponentStandbyState value) {
+  
+  old_ = value;
+  // @@protoc_insertion_point(field_set:dmi.StandbyStateChange.old)
+}
+
+// .dmi.ComponentStandbyState new = 2;
+inline void StandbyStateChange::clear_new_() {
+  new__ = 0;
+}
+inline ::dmi::ComponentStandbyState StandbyStateChange::new_() const {
+  // @@protoc_insertion_point(field_get:dmi.StandbyStateChange.new)
+  return static_cast< ::dmi::ComponentStandbyState >(new__);
+}
+inline void StandbyStateChange::set_new_(::dmi::ComponentStandbyState value) {
+  
+  new__ = value;
+  // @@protoc_insertion_point(field_set:dmi.StandbyStateChange.new)
+}
+
+// -------------------------------------------------------------------
+
+// StateChangeInfo
+
+// .dmi.AdminStateChange admin_state_change = 1;
+inline bool StateChangeInfo::has_admin_state_change() const {
+  return state_change_case() == kAdminStateChange;
+}
+inline void StateChangeInfo::set_has_admin_state_change() {
+  _oneof_case_[0] = kAdminStateChange;
+}
+inline void StateChangeInfo::clear_admin_state_change() {
+  if (has_admin_state_change()) {
+    delete state_change_.admin_state_change_;
+    clear_has_state_change();
+  }
+}
+inline ::dmi::AdminStateChange* StateChangeInfo::release_admin_state_change() {
+  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.admin_state_change)
+  if (has_admin_state_change()) {
+    clear_has_state_change();
+      ::dmi::AdminStateChange* temp = state_change_.admin_state_change_;
+    state_change_.admin_state_change_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::AdminStateChange& StateChangeInfo::admin_state_change() const {
+  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.admin_state_change)
+  return has_admin_state_change()
+      ? *state_change_.admin_state_change_
+      : *reinterpret_cast< ::dmi::AdminStateChange*>(&::dmi::_AdminStateChange_default_instance_);
+}
+inline ::dmi::AdminStateChange* StateChangeInfo::mutable_admin_state_change() {
+  if (!has_admin_state_change()) {
+    clear_state_change();
+    set_has_admin_state_change();
+    state_change_.admin_state_change_ = CreateMaybeMessage< ::dmi::AdminStateChange >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.admin_state_change)
+  return state_change_.admin_state_change_;
+}
+
+// .dmi.OperStateChange oper_state_change = 2;
+inline bool StateChangeInfo::has_oper_state_change() const {
+  return state_change_case() == kOperStateChange;
+}
+inline void StateChangeInfo::set_has_oper_state_change() {
+  _oneof_case_[0] = kOperStateChange;
+}
+inline void StateChangeInfo::clear_oper_state_change() {
+  if (has_oper_state_change()) {
+    delete state_change_.oper_state_change_;
+    clear_has_state_change();
+  }
+}
+inline ::dmi::OperStateChange* StateChangeInfo::release_oper_state_change() {
+  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.oper_state_change)
+  if (has_oper_state_change()) {
+    clear_has_state_change();
+      ::dmi::OperStateChange* temp = state_change_.oper_state_change_;
+    state_change_.oper_state_change_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::OperStateChange& StateChangeInfo::oper_state_change() const {
+  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.oper_state_change)
+  return has_oper_state_change()
+      ? *state_change_.oper_state_change_
+      : *reinterpret_cast< ::dmi::OperStateChange*>(&::dmi::_OperStateChange_default_instance_);
+}
+inline ::dmi::OperStateChange* StateChangeInfo::mutable_oper_state_change() {
+  if (!has_oper_state_change()) {
+    clear_state_change();
+    set_has_oper_state_change();
+    state_change_.oper_state_change_ = CreateMaybeMessage< ::dmi::OperStateChange >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.oper_state_change)
+  return state_change_.oper_state_change_;
+}
+
+// .dmi.AlarmStateChange alarm_state_change = 3;
+inline bool StateChangeInfo::has_alarm_state_change() const {
+  return state_change_case() == kAlarmStateChange;
+}
+inline void StateChangeInfo::set_has_alarm_state_change() {
+  _oneof_case_[0] = kAlarmStateChange;
+}
+inline void StateChangeInfo::clear_alarm_state_change() {
+  if (has_alarm_state_change()) {
+    delete state_change_.alarm_state_change_;
+    clear_has_state_change();
+  }
+}
+inline ::dmi::AlarmStateChange* StateChangeInfo::release_alarm_state_change() {
+  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.alarm_state_change)
+  if (has_alarm_state_change()) {
+    clear_has_state_change();
+      ::dmi::AlarmStateChange* temp = state_change_.alarm_state_change_;
+    state_change_.alarm_state_change_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::AlarmStateChange& StateChangeInfo::alarm_state_change() const {
+  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.alarm_state_change)
+  return has_alarm_state_change()
+      ? *state_change_.alarm_state_change_
+      : *reinterpret_cast< ::dmi::AlarmStateChange*>(&::dmi::_AlarmStateChange_default_instance_);
+}
+inline ::dmi::AlarmStateChange* StateChangeInfo::mutable_alarm_state_change() {
+  if (!has_alarm_state_change()) {
+    clear_state_change();
+    set_has_alarm_state_change();
+    state_change_.alarm_state_change_ = CreateMaybeMessage< ::dmi::AlarmStateChange >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.alarm_state_change)
+  return state_change_.alarm_state_change_;
+}
+
+// .dmi.UsageStateChange usage_state_change = 4;
+inline bool StateChangeInfo::has_usage_state_change() const {
+  return state_change_case() == kUsageStateChange;
+}
+inline void StateChangeInfo::set_has_usage_state_change() {
+  _oneof_case_[0] = kUsageStateChange;
+}
+inline void StateChangeInfo::clear_usage_state_change() {
+  if (has_usage_state_change()) {
+    delete state_change_.usage_state_change_;
+    clear_has_state_change();
+  }
+}
+inline ::dmi::UsageStateChange* StateChangeInfo::release_usage_state_change() {
+  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.usage_state_change)
+  if (has_usage_state_change()) {
+    clear_has_state_change();
+      ::dmi::UsageStateChange* temp = state_change_.usage_state_change_;
+    state_change_.usage_state_change_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::UsageStateChange& StateChangeInfo::usage_state_change() const {
+  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.usage_state_change)
+  return has_usage_state_change()
+      ? *state_change_.usage_state_change_
+      : *reinterpret_cast< ::dmi::UsageStateChange*>(&::dmi::_UsageStateChange_default_instance_);
+}
+inline ::dmi::UsageStateChange* StateChangeInfo::mutable_usage_state_change() {
+  if (!has_usage_state_change()) {
+    clear_state_change();
+    set_has_usage_state_change();
+    state_change_.usage_state_change_ = CreateMaybeMessage< ::dmi::UsageStateChange >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.usage_state_change)
+  return state_change_.usage_state_change_;
+}
+
+// .dmi.StandbyStateChange standby_state_change = 5;
+inline bool StateChangeInfo::has_standby_state_change() const {
+  return state_change_case() == kStandbyStateChange;
+}
+inline void StateChangeInfo::set_has_standby_state_change() {
+  _oneof_case_[0] = kStandbyStateChange;
+}
+inline void StateChangeInfo::clear_standby_state_change() {
+  if (has_standby_state_change()) {
+    delete state_change_.standby_state_change_;
+    clear_has_state_change();
+  }
+}
+inline ::dmi::StandbyStateChange* StateChangeInfo::release_standby_state_change() {
+  // @@protoc_insertion_point(field_release:dmi.StateChangeInfo.standby_state_change)
+  if (has_standby_state_change()) {
+    clear_has_state_change();
+      ::dmi::StandbyStateChange* temp = state_change_.standby_state_change_;
+    state_change_.standby_state_change_ = nullptr;
+    return temp;
+  } else {
+    return nullptr;
+  }
+}
+inline const ::dmi::StandbyStateChange& StateChangeInfo::standby_state_change() const {
+  // @@protoc_insertion_point(field_get:dmi.StateChangeInfo.standby_state_change)
+  return has_standby_state_change()
+      ? *state_change_.standby_state_change_
+      : *reinterpret_cast< ::dmi::StandbyStateChange*>(&::dmi::_StandbyStateChange_default_instance_);
+}
+inline ::dmi::StandbyStateChange* StateChangeInfo::mutable_standby_state_change() {
+  if (!has_standby_state_change()) {
+    clear_state_change();
+    set_has_standby_state_change();
+    state_change_.standby_state_change_ = CreateMaybeMessage< ::dmi::StandbyStateChange >(
+        GetArenaNoVirtual());
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.StateChangeInfo.standby_state_change)
+  return state_change_.standby_state_change_;
+}
+
+inline bool StateChangeInfo::has_state_change() const {
+  return state_change_case() != STATE_CHANGE_NOT_SET;
+}
+inline void StateChangeInfo::clear_has_state_change() {
+  _oneof_case_[0] = STATE_CHANGE_NOT_SET;
+}
+inline StateChangeInfo::StateChangeCase StateChangeInfo::state_change_case() const {
+  return StateChangeInfo::StateChangeCase(_oneof_case_[0]);
+}
+// -------------------------------------------------------------------
+
 // Event
 
 // .dmi.EventMetaData event_metadata = 1;
@@ -3133,6 +4324,57 @@
   // @@protoc_insertion_point(field_set_allocated:dmi.Event.add_info)
 }
 
+// .dmi.StateChangeInfo state_change_info = 6;
+inline bool Event::has_state_change_info() const {
+  return this != internal_default_instance() && state_change_info_ != nullptr;
+}
+inline void Event::clear_state_change_info() {
+  if (GetArenaNoVirtual() == nullptr && state_change_info_ != nullptr) {
+    delete state_change_info_;
+  }
+  state_change_info_ = nullptr;
+}
+inline const ::dmi::StateChangeInfo& Event::state_change_info() const {
+  const ::dmi::StateChangeInfo* p = state_change_info_;
+  // @@protoc_insertion_point(field_get:dmi.Event.state_change_info)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::StateChangeInfo*>(
+      &::dmi::_StateChangeInfo_default_instance_);
+}
+inline ::dmi::StateChangeInfo* Event::release_state_change_info() {
+  // @@protoc_insertion_point(field_release:dmi.Event.state_change_info)
+  
+  ::dmi::StateChangeInfo* temp = state_change_info_;
+  state_change_info_ = nullptr;
+  return temp;
+}
+inline ::dmi::StateChangeInfo* Event::mutable_state_change_info() {
+  
+  if (state_change_info_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::StateChangeInfo>(GetArenaNoVirtual());
+    state_change_info_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.Event.state_change_info)
+  return state_change_info_;
+}
+inline void Event::set_allocated_state_change_info(::dmi::StateChangeInfo* state_change_info) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete state_change_info_;
+  }
+  if (state_change_info) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      state_change_info = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, state_change_info, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  state_change_info_ = state_change_info;
+  // @@protoc_insertion_point(field_set_allocated:dmi.Event.state_change_info)
+}
+
 #ifdef __GNUC__
   #pragma GCC diagnostic pop
 #endif  // __GNUC__
@@ -3156,6 +4398,18 @@
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 
diff --git a/cpp/dmi/hw_management_service.grpc.pb.cc b/cpp/dmi/hw_management_service.grpc.pb.cc
index ef057ff..19f6be0 100644
--- a/cpp/dmi/hw_management_service.grpc.pb.cc
+++ b/cpp/dmi/hw_management_service.grpc.pb.cc
@@ -39,6 +39,9 @@
   "/dmi.NativeHWManagementService/RebootDevice",
   "/dmi.NativeHWManagementService/SetDmLogLevel",
   "/dmi.NativeHWManagementService/GetDmLogLevel",
+  "/dmi.NativeHWManagementService/DisableHWComponent",
+  "/dmi.NativeHWManagementService/ResetHWComponent",
+  "/dmi.NativeHWManagementService/EnableHWComponent",
 };
 
 std::unique_ptr< NativeHWManagementService::Stub> NativeHWManagementService::NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options) {
@@ -65,6 +68,9 @@
   , rpcmethod_RebootDevice_(NativeHWManagementService_method_names[14], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
   , rpcmethod_SetDmLogLevel_(NativeHWManagementService_method_names[15], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
   , rpcmethod_GetDmLogLevel_(NativeHWManagementService_method_names[16], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_DisableHWComponent_(NativeHWManagementService_method_names[17], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_ResetHWComponent_(NativeHWManagementService_method_names[18], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
+  , rpcmethod_EnableHWComponent_(NativeHWManagementService_method_names[19], ::grpc::internal::RpcMethod::NORMAL_RPC, channel)
   {}
 
 ::grpc::ClientReader< ::dmi::StartManagingDeviceResponse>* NativeHWManagementService::Stub::StartManagingDeviceRaw(::grpc::ClientContext* context, const ::dmi::ModifiableComponent& request) {
@@ -507,6 +513,90 @@
   return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::GetDmLogLevelResponse>::Create(channel_.get(), cq, rpcmethod_GetDmLogLevel_, context, request, false);
 }
 
+::grpc::Status NativeHWManagementService::Stub::DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::dmi::DisableHWComponentResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_DisableHWComponent_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DisableHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_DisableHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DisableHWComponent_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_DisableHWComponent_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>* NativeHWManagementService::Stub::AsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::DisableHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_DisableHWComponent_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>* NativeHWManagementService::Stub::PrepareAsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::DisableHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_DisableHWComponent_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::dmi::ResetHWComponentResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_ResetHWComponent_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ResetHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_ResetHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ResetHWComponent_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_ResetHWComponent_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>* NativeHWManagementService::Stub::AsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ResetHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_ResetHWComponent_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>* NativeHWManagementService::Stub::PrepareAsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::ResetHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_ResetHWComponent_, context, request, false);
+}
+
+::grpc::Status NativeHWManagementService::Stub::EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::dmi::EnableHWComponentResponse* response) {
+  return ::grpc::internal::BlockingUnaryCall(channel_.get(), rpcmethod_EnableHWComponent_, context, request, response);
+}
+
+void NativeHWManagementService::Stub::experimental_async::EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_EnableHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)> f) {
+  ::grpc_impl::internal::CallbackUnaryCall(stub_->channel_.get(), stub_->rpcmethod_EnableHWComponent_, context, request, response, std::move(f));
+}
+
+void NativeHWManagementService::Stub::experimental_async::EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_EnableHWComponent_, context, request, response, reactor);
+}
+
+void NativeHWManagementService::Stub::experimental_async::EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) {
+  ::grpc_impl::internal::ClientCallbackUnaryFactory::Create(stub_->channel_.get(), stub_->rpcmethod_EnableHWComponent_, context, request, response, reactor);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>* NativeHWManagementService::Stub::AsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::EnableHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_EnableHWComponent_, context, request, true);
+}
+
+::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>* NativeHWManagementService::Stub::PrepareAsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+  return ::grpc_impl::internal::ClientAsyncResponseReaderFactory< ::dmi::EnableHWComponentResponse>::Create(channel_.get(), cq, rpcmethod_EnableHWComponent_, context, request, false);
+}
+
 NativeHWManagementService::Service::Service() {
   AddMethod(new ::grpc::internal::RpcServiceMethod(
       NativeHWManagementService_method_names[0],
@@ -678,6 +768,36 @@
              ::dmi::GetDmLogLevelResponse* resp) {
                return service->GetDmLogLevel(ctx, req, resp);
              }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[17],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::DisableHWComponentRequest* req,
+             ::dmi::DisableHWComponentResponse* resp) {
+               return service->DisableHWComponent(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[18],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::ResetHWComponentRequest* req,
+             ::dmi::ResetHWComponentResponse* resp) {
+               return service->ResetHWComponent(ctx, req, resp);
+             }, this)));
+  AddMethod(new ::grpc::internal::RpcServiceMethod(
+      NativeHWManagementService_method_names[19],
+      ::grpc::internal::RpcMethod::NORMAL_RPC,
+      new ::grpc::internal::RpcMethodHandler< NativeHWManagementService::Service, ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>(
+          [](NativeHWManagementService::Service* service,
+             ::grpc_impl::ServerContext* ctx,
+             const ::dmi::EnableHWComponentRequest* req,
+             ::dmi::EnableHWComponentResponse* resp) {
+               return service->EnableHWComponent(ctx, req, resp);
+             }, this)));
 }
 
 NativeHWManagementService::Service::~Service() {
@@ -802,6 +922,27 @@
   return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
 }
 
+::grpc::Status NativeHWManagementService::Service::DisableHWComponent(::grpc::ServerContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::ResetHWComponent(::grpc::ServerContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
+::grpc::Status NativeHWManagementService::Service::EnableHWComponent(::grpc::ServerContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response) {
+  (void) context;
+  (void) request;
+  (void) response;
+  return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+}
+
 
 }  // namespace dmi
 
diff --git a/cpp/dmi/hw_management_service.grpc.pb.h b/cpp/dmi/hw_management_service.grpc.pb.h
index 938264c..1d24ff5 100644
--- a/cpp/dmi/hw_management_service.grpc.pb.h
+++ b/cpp/dmi/hw_management_service.grpc.pb.h
@@ -193,6 +193,30 @@
     std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetDmLogLevelResponse>> PrepareAsyncGetDmLogLevel(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
       return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetDmLogLevelResponse>>(PrepareAsyncGetDmLogLevelRaw(context, request, cq));
     }
+    // Disables a hardware component on a device.
+    virtual ::grpc::Status DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::dmi::DisableHWComponentResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>> AsyncDisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>>(AsyncDisableHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>> PrepareAsyncDisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>>(PrepareAsyncDisableHWComponentRaw(context, request, cq));
+    }
+    // Resets a hardware component on a device.
+    virtual ::grpc::Status ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::dmi::ResetHWComponentResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>> AsyncResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>>(AsyncResetHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>> PrepareAsyncResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>>(PrepareAsyncResetHWComponentRaw(context, request, cq));
+    }
+    // Enables a hardware component on a device.
+    virtual ::grpc::Status EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::dmi::EnableHWComponentResponse* response) = 0;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>> AsyncEnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>>(AsyncEnableHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>> PrepareAsyncEnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>>(PrepareAsyncEnableHWComponentRaw(context, request, cq));
+    }
     class experimental_async_interface {
      public:
       virtual ~experimental_async_interface() {}
@@ -411,6 +435,45 @@
       #else
       virtual void GetDmLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetDmLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
       #endif
+      // Disables a hardware component on a device.
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Resets a hardware component on a device.
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      // Enables a hardware component on a device.
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)>) = 0;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) = 0;
+      #else
+      virtual void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) = 0;
+      #endif
     };
     #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
     typedef class experimental_async_interface async_interface;
@@ -457,6 +520,12 @@
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::SetDmLogLevelResponse>* PrepareAsyncSetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetDmLogLevelResponse>* AsyncGetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
     virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::GetDmLogLevelResponse>* PrepareAsyncGetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>* AsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::DisableHWComponentResponse>* PrepareAsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>* AsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::ResetHWComponentResponse>* PrepareAsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>* AsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
+    virtual ::grpc::ClientAsyncResponseReaderInterface< ::dmi::EnableHWComponentResponse>* PrepareAsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) = 0;
   };
   class Stub final : public StubInterface {
    public:
@@ -586,6 +655,27 @@
     std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetDmLogLevelResponse>> PrepareAsyncGetDmLogLevel(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) {
       return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::GetDmLogLevelResponse>>(PrepareAsyncGetDmLogLevelRaw(context, request, cq));
     }
+    ::grpc::Status DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::dmi::DisableHWComponentResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>> AsyncDisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>>(AsyncDisableHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>> PrepareAsyncDisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>>(PrepareAsyncDisableHWComponentRaw(context, request, cq));
+    }
+    ::grpc::Status ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::dmi::ResetHWComponentResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>> AsyncResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>>(AsyncResetHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>> PrepareAsyncResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>>(PrepareAsyncResetHWComponentRaw(context, request, cq));
+    }
+    ::grpc::Status EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::dmi::EnableHWComponentResponse* response) override;
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>> AsyncEnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>>(AsyncEnableHWComponentRaw(context, request, cq));
+    }
+    std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>> PrepareAsyncEnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) {
+      return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>>(PrepareAsyncEnableHWComponentRaw(context, request, cq));
+    }
     class experimental_async final :
       public StubInterface::experimental_async_interface {
      public:
@@ -772,6 +862,42 @@
       #else
       void GetDmLogLevel(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::GetDmLogLevelResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
       #endif
+      void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void DisableHWComponent(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void DisableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::DisableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ResetHWComponent(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void ResetHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::ResetHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, std::function<void(::grpc::Status)>) override;
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void EnableHWComponent(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
+      #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, ::grpc::ClientUnaryReactor* reactor) override;
+      #else
+      void EnableHWComponent(::grpc::ClientContext* context, const ::grpc::ByteBuffer* request, ::dmi::EnableHWComponentResponse* response, ::grpc::experimental::ClientUnaryReactor* reactor) override;
+      #endif
      private:
       friend class Stub;
       explicit experimental_async(Stub* stub): stub_(stub) { }
@@ -820,6 +946,12 @@
     ::grpc::ClientAsyncResponseReader< ::dmi::SetDmLogLevelResponse>* PrepareAsyncSetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::SetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
     ::grpc::ClientAsyncResponseReader< ::dmi::GetDmLogLevelResponse>* AsyncGetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
     ::grpc::ClientAsyncResponseReader< ::dmi::GetDmLogLevelResponse>* PrepareAsyncGetDmLogLevelRaw(::grpc::ClientContext* context, const ::dmi::GetDmLogLevelRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>* AsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::DisableHWComponentResponse>* PrepareAsyncDisableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::DisableHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>* AsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::ResetHWComponentResponse>* PrepareAsyncResetHWComponentRaw(::grpc::ClientContext* context, const ::dmi::ResetHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>* AsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
+    ::grpc::ClientAsyncResponseReader< ::dmi::EnableHWComponentResponse>* PrepareAsyncEnableHWComponentRaw(::grpc::ClientContext* context, const ::dmi::EnableHWComponentRequest& request, ::grpc::CompletionQueue* cq) override;
     const ::grpc::internal::RpcMethod rpcmethod_StartManagingDevice_;
     const ::grpc::internal::RpcMethod rpcmethod_StopManagingDevice_;
     const ::grpc::internal::RpcMethod rpcmethod_GetManagedDevices_;
@@ -837,6 +969,9 @@
     const ::grpc::internal::RpcMethod rpcmethod_RebootDevice_;
     const ::grpc::internal::RpcMethod rpcmethod_SetDmLogLevel_;
     const ::grpc::internal::RpcMethod rpcmethod_GetDmLogLevel_;
+    const ::grpc::internal::RpcMethod rpcmethod_DisableHWComponent_;
+    const ::grpc::internal::RpcMethod rpcmethod_ResetHWComponent_;
+    const ::grpc::internal::RpcMethod rpcmethod_EnableHWComponent_;
   };
   static std::unique_ptr<Stub> NewStub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, const ::grpc::StubOptions& options = ::grpc::StubOptions());
 
@@ -893,6 +1028,12 @@
     virtual ::grpc::Status SetDmLogLevel(::grpc::ServerContext* context, const ::dmi::SetDmLogLevelRequest* request, ::dmi::SetDmLogLevelResponse* response);
     // Gets the log level at which the Device Manager is running
     virtual ::grpc::Status GetDmLogLevel(::grpc::ServerContext* context, const ::dmi::GetDmLogLevelRequest* request, ::dmi::GetDmLogLevelResponse* response);
+    // Disables a hardware component on a device.
+    virtual ::grpc::Status DisableHWComponent(::grpc::ServerContext* context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response);
+    // Resets a hardware component on a device.
+    virtual ::grpc::Status ResetHWComponent(::grpc::ServerContext* context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response);
+    // Enables a hardware component on a device.
+    virtual ::grpc::Status EnableHWComponent(::grpc::ServerContext* context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response);
   };
   template <class BaseClass>
   class WithAsyncMethod_StartManagingDevice : public BaseClass {
@@ -1234,7 +1375,67 @@
       ::grpc::Service::RequestAsyncUnary(16, context, request, response, new_call_cq, notification_cq, tag);
     }
   };
-  typedef WithAsyncMethod_StartManagingDevice<WithAsyncMethod_StopManagingDevice<WithAsyncMethod_GetManagedDevices<WithAsyncMethod_GetPhysicalInventory<WithAsyncMethod_GetHWComponentInfo<WithAsyncMethod_SetHWComponentInfo<WithAsyncMethod_SetLoggingEndpoint<WithAsyncMethod_GetLoggingEndpoint<WithAsyncMethod_SetMsgBusEndpoint<WithAsyncMethod_GetMsgBusEndpoint<WithAsyncMethod_GetLoggableEntities<WithAsyncMethod_SetLogLevel<WithAsyncMethod_GetLogLevel<WithAsyncMethod_HeartbeatCheck<WithAsyncMethod_RebootDevice<WithAsyncMethod_SetDmLogLevel<WithAsyncMethod_GetDmLogLevel<Service > > > > > > > > > > > > > > > > > AsyncService;
+  template <class BaseClass>
+  class WithAsyncMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_DisableHWComponent() {
+      ::grpc::Service::MarkMethodAsync(17);
+    }
+    ~WithAsyncMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestDisableHWComponent(::grpc::ServerContext* context, ::dmi::DisableHWComponentRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::DisableHWComponentResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_ResetHWComponent() {
+      ::grpc::Service::MarkMethodAsync(18);
+    }
+    ~WithAsyncMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestResetHWComponent(::grpc::ServerContext* context, ::dmi::ResetHWComponentRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::ResetHWComponentResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithAsyncMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithAsyncMethod_EnableHWComponent() {
+      ::grpc::Service::MarkMethodAsync(19);
+    }
+    ~WithAsyncMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestEnableHWComponent(::grpc::ServerContext* context, ::dmi::EnableHWComponentRequest* request, ::grpc::ServerAsyncResponseWriter< ::dmi::EnableHWComponentResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  typedef WithAsyncMethod_StartManagingDevice<WithAsyncMethod_StopManagingDevice<WithAsyncMethod_GetManagedDevices<WithAsyncMethod_GetPhysicalInventory<WithAsyncMethod_GetHWComponentInfo<WithAsyncMethod_SetHWComponentInfo<WithAsyncMethod_SetLoggingEndpoint<WithAsyncMethod_GetLoggingEndpoint<WithAsyncMethod_SetMsgBusEndpoint<WithAsyncMethod_GetMsgBusEndpoint<WithAsyncMethod_GetLoggableEntities<WithAsyncMethod_SetLogLevel<WithAsyncMethod_GetLogLevel<WithAsyncMethod_HeartbeatCheck<WithAsyncMethod_RebootDevice<WithAsyncMethod_SetDmLogLevel<WithAsyncMethod_GetDmLogLevel<WithAsyncMethod_DisableHWComponent<WithAsyncMethod_ResetHWComponent<WithAsyncMethod_EnableHWComponent<Service > > > > > > > > > > > > > > > > > > > > AsyncService;
   template <class BaseClass>
   class ExperimentalWithCallbackMethod_StartManagingDevice : public BaseClass {
    private:
@@ -2007,11 +2208,152 @@
     #endif
       { return nullptr; }
   };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_DisableHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(17,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::DisableHWComponentRequest* request, ::dmi::DisableHWComponentResponse* response) { return this->DisableHWComponent(context, request, response); }));}
+    void SetMessageAllocatorFor_DisableHWComponent(
+        ::grpc::experimental::MessageAllocator< ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(17);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(17);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* DisableHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* DisableHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_ResetHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(18,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::ResetHWComponentRequest* request, ::dmi::ResetHWComponentResponse* response) { return this->ResetHWComponent(context, request, response); }));}
+    void SetMessageAllocatorFor_ResetHWComponent(
+        ::grpc::experimental::MessageAllocator< ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(18);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(18);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ResetHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ResetHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithCallbackMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithCallbackMethod_EnableHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodCallback(19,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::dmi::EnableHWComponentRequest* request, ::dmi::EnableHWComponentResponse* response) { return this->EnableHWComponent(context, request, response); }));}
+    void SetMessageAllocatorFor_EnableHWComponent(
+        ::grpc::experimental::MessageAllocator< ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>* allocator) {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(19);
+    #else
+      ::grpc::internal::MethodHandler* const handler = ::grpc::Service::experimental().GetHandler(19);
+    #endif
+      static_cast<::grpc_impl::internal::CallbackUnaryHandler< ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>*>(handler)
+              ->SetMessageAllocator(allocator);
+    }
+    ~ExperimentalWithCallbackMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* EnableHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* EnableHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/)
+    #endif
+      { return nullptr; }
+  };
   #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
-  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<ExperimentalWithCallbackMethod_HeartbeatCheck<ExperimentalWithCallbackMethod_RebootDevice<ExperimentalWithCallbackMethod_SetDmLogLevel<ExperimentalWithCallbackMethod_GetDmLogLevel<Service > > > > > > > > > > > > > > > > > CallbackService;
+  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<ExperimentalWithCallbackMethod_HeartbeatCheck<ExperimentalWithCallbackMethod_RebootDevice<ExperimentalWithCallbackMethod_SetDmLogLevel<ExperimentalWithCallbackMethod_GetDmLogLevel<ExperimentalWithCallbackMethod_DisableHWComponent<ExperimentalWithCallbackMethod_ResetHWComponent<ExperimentalWithCallbackMethod_EnableHWComponent<Service > > > > > > > > > > > > > > > > > > > > CallbackService;
   #endif
 
-  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<ExperimentalWithCallbackMethod_HeartbeatCheck<ExperimentalWithCallbackMethod_RebootDevice<ExperimentalWithCallbackMethod_SetDmLogLevel<ExperimentalWithCallbackMethod_GetDmLogLevel<Service > > > > > > > > > > > > > > > > > ExperimentalCallbackService;
+  typedef ExperimentalWithCallbackMethod_StartManagingDevice<ExperimentalWithCallbackMethod_StopManagingDevice<ExperimentalWithCallbackMethod_GetManagedDevices<ExperimentalWithCallbackMethod_GetPhysicalInventory<ExperimentalWithCallbackMethod_GetHWComponentInfo<ExperimentalWithCallbackMethod_SetHWComponentInfo<ExperimentalWithCallbackMethod_SetLoggingEndpoint<ExperimentalWithCallbackMethod_GetLoggingEndpoint<ExperimentalWithCallbackMethod_SetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetMsgBusEndpoint<ExperimentalWithCallbackMethod_GetLoggableEntities<ExperimentalWithCallbackMethod_SetLogLevel<ExperimentalWithCallbackMethod_GetLogLevel<ExperimentalWithCallbackMethod_HeartbeatCheck<ExperimentalWithCallbackMethod_RebootDevice<ExperimentalWithCallbackMethod_SetDmLogLevel<ExperimentalWithCallbackMethod_GetDmLogLevel<ExperimentalWithCallbackMethod_DisableHWComponent<ExperimentalWithCallbackMethod_ResetHWComponent<ExperimentalWithCallbackMethod_EnableHWComponent<Service > > > > > > > > > > > > > > > > > > > > ExperimentalCallbackService;
   template <class BaseClass>
   class WithGenericMethod_StartManagingDevice : public BaseClass {
    private:
@@ -2302,6 +2644,57 @@
     }
   };
   template <class BaseClass>
+  class WithGenericMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_DisableHWComponent() {
+      ::grpc::Service::MarkMethodGeneric(17);
+    }
+    ~WithGenericMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_ResetHWComponent() {
+      ::grpc::Service::MarkMethodGeneric(18);
+    }
+    ~WithGenericMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
+  class WithGenericMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithGenericMethod_EnableHWComponent() {
+      ::grpc::Service::MarkMethodGeneric(19);
+    }
+    ~WithGenericMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+  };
+  template <class BaseClass>
   class WithRawMethod_StartManagingDevice : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -2642,6 +3035,66 @@
     }
   };
   template <class BaseClass>
+  class WithRawMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_DisableHWComponent() {
+      ::grpc::Service::MarkMethodRaw(17);
+    }
+    ~WithRawMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestDisableHWComponent(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_ResetHWComponent() {
+      ::grpc::Service::MarkMethodRaw(18);
+    }
+    ~WithRawMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestResetHWComponent(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
+  class WithRawMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithRawMethod_EnableHWComponent() {
+      ::grpc::Service::MarkMethodRaw(19);
+    }
+    ~WithRawMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    void RequestEnableHWComponent(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) {
+      ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag);
+    }
+  };
+  template <class BaseClass>
   class ExperimentalWithRawCallbackMethod_StartManagingDevice : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -3288,6 +3741,120 @@
       { return nullptr; }
   };
   template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_DisableHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(17,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->DisableHWComponent(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* DisableHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* DisableHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_ResetHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(18,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ResetHWComponent(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* ResetHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* ResetHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
+  class ExperimentalWithRawCallbackMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    ExperimentalWithRawCallbackMethod_EnableHWComponent() {
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+      ::grpc::Service::
+    #else
+      ::grpc::Service::experimental().
+    #endif
+        MarkMethodRawCallback(19,
+          new ::grpc_impl::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>(
+            [this](
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+                   ::grpc::CallbackServerContext*
+    #else
+                   ::grpc::experimental::CallbackServerContext*
+    #endif
+                     context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->EnableHWComponent(context, request, response); }));
+    }
+    ~ExperimentalWithRawCallbackMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable synchronous version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    #ifdef GRPC_CALLBACK_API_NONEXPERIMENTAL
+    virtual ::grpc::ServerUnaryReactor* EnableHWComponent(
+      ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #else
+    virtual ::grpc::experimental::ServerUnaryReactor* EnableHWComponent(
+      ::grpc::experimental::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/)
+    #endif
+      { return nullptr; }
+  };
+  template <class BaseClass>
   class WithStreamedUnaryMethod_StopManagingDevice : public BaseClass {
    private:
     void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
@@ -3665,7 +4232,88 @@
     // replace default version of method with streamed unary
     virtual ::grpc::Status StreamedGetDmLogLevel(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::GetDmLogLevelRequest,::dmi::GetDmLogLevelResponse>* server_unary_streamer) = 0;
   };
-  typedef WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<WithStreamedUnaryMethod_HeartbeatCheck<WithStreamedUnaryMethod_RebootDevice<WithStreamedUnaryMethod_SetDmLogLevel<WithStreamedUnaryMethod_GetDmLogLevel<Service > > > > > > > > > > > > > > StreamedUnaryService;
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_DisableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_DisableHWComponent() {
+      ::grpc::Service::MarkMethodStreamed(17,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::DisableHWComponentRequest, ::dmi::DisableHWComponentResponse>* streamer) {
+                       return this->StreamedDisableHWComponent(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_DisableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status DisableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::DisableHWComponentRequest* /*request*/, ::dmi::DisableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedDisableHWComponent(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::DisableHWComponentRequest,::dmi::DisableHWComponentResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_ResetHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_ResetHWComponent() {
+      ::grpc::Service::MarkMethodStreamed(18,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::ResetHWComponentRequest, ::dmi::ResetHWComponentResponse>* streamer) {
+                       return this->StreamedResetHWComponent(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_ResetHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status ResetHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::ResetHWComponentRequest* /*request*/, ::dmi::ResetHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedResetHWComponent(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::ResetHWComponentRequest,::dmi::ResetHWComponentResponse>* server_unary_streamer) = 0;
+  };
+  template <class BaseClass>
+  class WithStreamedUnaryMethod_EnableHWComponent : public BaseClass {
+   private:
+    void BaseClassMustBeDerivedFromService(const Service* /*service*/) {}
+   public:
+    WithStreamedUnaryMethod_EnableHWComponent() {
+      ::grpc::Service::MarkMethodStreamed(19,
+        new ::grpc::internal::StreamedUnaryHandler<
+          ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>(
+            [this](::grpc_impl::ServerContext* context,
+                   ::grpc_impl::ServerUnaryStreamer<
+                     ::dmi::EnableHWComponentRequest, ::dmi::EnableHWComponentResponse>* streamer) {
+                       return this->StreamedEnableHWComponent(context,
+                         streamer);
+                  }));
+    }
+    ~WithStreamedUnaryMethod_EnableHWComponent() override {
+      BaseClassMustBeDerivedFromService(this);
+    }
+    // disable regular version of this method
+    ::grpc::Status EnableHWComponent(::grpc::ServerContext* /*context*/, const ::dmi::EnableHWComponentRequest* /*request*/, ::dmi::EnableHWComponentResponse* /*response*/) override {
+      abort();
+      return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, "");
+    }
+    // replace default version of method with streamed unary
+    virtual ::grpc::Status StreamedEnableHWComponent(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::dmi::EnableHWComponentRequest,::dmi::EnableHWComponentResponse>* server_unary_streamer) = 0;
+  };
+  typedef WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<WithStreamedUnaryMethod_HeartbeatCheck<WithStreamedUnaryMethod_RebootDevice<WithStreamedUnaryMethod_SetDmLogLevel<WithStreamedUnaryMethod_GetDmLogLevel<WithStreamedUnaryMethod_DisableHWComponent<WithStreamedUnaryMethod_ResetHWComponent<WithStreamedUnaryMethod_EnableHWComponent<Service > > > > > > > > > > > > > > > > > StreamedUnaryService;
   template <class BaseClass>
   class WithSplitStreamingMethod_StartManagingDevice : public BaseClass {
    private:
@@ -3748,7 +4396,7 @@
     virtual ::grpc::Status StreamedGetHWComponentInfo(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::dmi::HWComponentInfoGetRequest,::dmi::HWComponentInfoGetResponse>* server_split_streamer) = 0;
   };
   typedef WithSplitStreamingMethod_StartManagingDevice<WithSplitStreamingMethod_GetPhysicalInventory<WithSplitStreamingMethod_GetHWComponentInfo<Service > > > SplitStreamedService;
-  typedef WithSplitStreamingMethod_StartManagingDevice<WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithSplitStreamingMethod_GetPhysicalInventory<WithSplitStreamingMethod_GetHWComponentInfo<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<WithStreamedUnaryMethod_HeartbeatCheck<WithStreamedUnaryMethod_RebootDevice<WithStreamedUnaryMethod_SetDmLogLevel<WithStreamedUnaryMethod_GetDmLogLevel<Service > > > > > > > > > > > > > > > > > StreamedService;
+  typedef WithSplitStreamingMethod_StartManagingDevice<WithStreamedUnaryMethod_StopManagingDevice<WithStreamedUnaryMethod_GetManagedDevices<WithSplitStreamingMethod_GetPhysicalInventory<WithSplitStreamingMethod_GetHWComponentInfo<WithStreamedUnaryMethod_SetHWComponentInfo<WithStreamedUnaryMethod_SetLoggingEndpoint<WithStreamedUnaryMethod_GetLoggingEndpoint<WithStreamedUnaryMethod_SetMsgBusEndpoint<WithStreamedUnaryMethod_GetMsgBusEndpoint<WithStreamedUnaryMethod_GetLoggableEntities<WithStreamedUnaryMethod_SetLogLevel<WithStreamedUnaryMethod_GetLogLevel<WithStreamedUnaryMethod_HeartbeatCheck<WithStreamedUnaryMethod_RebootDevice<WithStreamedUnaryMethod_SetDmLogLevel<WithStreamedUnaryMethod_GetDmLogLevel<WithStreamedUnaryMethod_DisableHWComponent<WithStreamedUnaryMethod_ResetHWComponent<WithStreamedUnaryMethod_EnableHWComponent<Service > > > > > > > > > > > > > > > > > > > > StreamedService;
 };
 
 }  // namespace dmi
diff --git a/cpp/dmi/hw_management_service.pb.cc b/cpp/dmi/hw_management_service.pb.cc
index 850ac0e..cdad77a 100644
--- a/cpp/dmi/hw_management_service.pb.cc
+++ b/cpp/dmi/hw_management_service.pb.cc
@@ -139,6 +139,30 @@
  public:
   ::google::protobuf::internal::ExplicitlyConstructed<RebootDeviceResponse> _instance;
 } _RebootDeviceResponse_default_instance_;
+class DisableHWComponentRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<DisableHWComponentRequest> _instance;
+} _DisableHWComponentRequest_default_instance_;
+class DisableHWComponentResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<DisableHWComponentResponse> _instance;
+} _DisableHWComponentResponse_default_instance_;
+class ResetHWComponentRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ResetHWComponentRequest> _instance;
+} _ResetHWComponentRequest_default_instance_;
+class ResetHWComponentResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<ResetHWComponentResponse> _instance;
+} _ResetHWComponentResponse_default_instance_;
+class EnableHWComponentRequestDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EnableHWComponentRequest> _instance;
+} _EnableHWComponentRequest_default_instance_;
+class EnableHWComponentResponseDefaultTypeInternal {
+ public:
+  ::google::protobuf::internal::ExplicitlyConstructed<EnableHWComponentResponse> _instance;
+} _EnableHWComponentResponse_default_instance_;
 }  // namespace dmi
 static void InitDefaultsPhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
   GOOGLE_PROTOBUF_VERIFY_VERSION;
@@ -565,6 +589,93 @@
 ::google::protobuf::internal::SCCInfo<0> scc_info_RebootDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
     {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsRebootDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
 
+static void InitDefaultsDisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_DisableHWComponentRequest_default_instance_;
+    new (ptr) ::dmi::DisableHWComponentRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::DisableHWComponentRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_DisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsDisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsDisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_DisableHWComponentResponse_default_instance_;
+    new (ptr) ::dmi::DisableHWComponentResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::DisableHWComponentResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_DisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsDisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ResetHWComponentRequest_default_instance_;
+    new (ptr) ::dmi::ResetHWComponentRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ResetHWComponentRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_ResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_ResetHWComponentResponse_default_instance_;
+    new (ptr) ::dmi::ResetHWComponentResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::ResetHWComponentResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_ResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
+static void InitDefaultsEnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EnableHWComponentRequest_default_instance_;
+    new (ptr) ::dmi::EnableHWComponentRequest();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EnableHWComponentRequest::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<1> scc_info_EnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 1, InitDefaultsEnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto}, {
+      &scc_info_Uuid_dmi_2fhw_2eproto.base,}};
+
+static void InitDefaultsEnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto() {
+  GOOGLE_PROTOBUF_VERIFY_VERSION;
+
+  {
+    void* ptr = &::dmi::_EnableHWComponentResponse_default_instance_;
+    new (ptr) ::dmi::EnableHWComponentResponse();
+    ::google::protobuf::internal::OnShutdownDestroyMessage(ptr);
+  }
+  ::dmi::EnableHWComponentResponse::InitAsDefaultInstance();
+}
+
+::google::protobuf::internal::SCCInfo<0> scc_info_EnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto =
+    {{ATOMIC_VAR_INIT(::google::protobuf::internal::SCCInfoBase::kUninitialized), 0, InitDefaultsEnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto}, {}};
+
 void InitDefaults_dmi_2fhw_5fmanagement_5fservice_2eproto() {
   ::google::protobuf::internal::InitSCC(&scc_info_PhysicalInventoryRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_PhysicalInventoryResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
@@ -595,10 +706,16 @@
   ::google::protobuf::internal::InitSCC(&scc_info_Heartbeat_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_RebootDeviceRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
   ::google::protobuf::internal::InitSCC(&scc_info_RebootDeviceResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_DisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_ResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  ::google::protobuf::internal::InitSCC(&scc_info_EnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
 }
 
-::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[29];
-const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[14];
+::google::protobuf::Metadata file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[35];
+const ::google::protobuf::EnumDescriptor* file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[17];
 constexpr ::google::protobuf::ServiceDescriptor const** file_level_service_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto = nullptr;
 
 const ::google::protobuf::uint32 TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto::offsets[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
@@ -824,6 +941,54 @@
   PROTOBUF_FIELD_OFFSET(::dmi::RebootDeviceResponse, status_),
   PROTOBUF_FIELD_OFFSET(::dmi::RebootDeviceResponse, reason_),
   PROTOBUF_FIELD_OFFSET(::dmi::RebootDeviceResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentRequest, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentRequest, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::DisableHWComponentResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentRequest, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentRequest, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::ResetHWComponentResponse, reason_detail_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentRequest, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentRequest, device_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentRequest, component_uuid_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentRequest, component_name_),
+  ~0u,  // no _has_bits_
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentResponse, _internal_metadata_),
+  ~0u,  // no _extensions_
+  ~0u,  // no _oneof_case_
+  ~0u,  // no _weak_field_map_
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentResponse, status_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentResponse, reason_),
+  PROTOBUF_FIELD_OFFSET(::dmi::EnableHWComponentResponse, reason_detail_),
 };
 static const ::google::protobuf::internal::MigrationSchema schemas[] PROTOBUF_SECTION_VARIABLE(protodesc_cold) = {
   { 0, -1, sizeof(::dmi::PhysicalInventoryRequest)},
@@ -855,6 +1020,12 @@
   { 202, -1, sizeof(::dmi::Heartbeat)},
   { 208, -1, sizeof(::dmi::RebootDeviceRequest)},
   { 214, -1, sizeof(::dmi::RebootDeviceResponse)},
+  { 222, -1, sizeof(::dmi::DisableHWComponentRequest)},
+  { 230, -1, sizeof(::dmi::DisableHWComponentResponse)},
+  { 238, -1, sizeof(::dmi::ResetHWComponentRequest)},
+  { 246, -1, sizeof(::dmi::ResetHWComponentResponse)},
+  { 254, -1, sizeof(::dmi::EnableHWComponentRequest)},
+  { 262, -1, sizeof(::dmi::EnableHWComponentResponse)},
 };
 
 static ::google::protobuf::Message const * const file_default_instances[] = {
@@ -887,12 +1058,18 @@
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_Heartbeat_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_RebootDeviceRequest_default_instance_),
   reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_RebootDeviceResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_DisableHWComponentRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_DisableHWComponentResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ResetHWComponentRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_ResetHWComponentResponse_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EnableHWComponentRequest_default_instance_),
+  reinterpret_cast<const ::google::protobuf::Message*>(&::dmi::_EnableHWComponentResponse_default_instance_),
 };
 
 ::google::protobuf::internal::AssignDescriptorsTable assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto = {
   {}, AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto, "dmi/hw_management_service.proto", schemas,
   file_default_instances, TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto::offsets,
-  file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto, 29, file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto,
+  file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto, 35, file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto, file_level_service_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto,
 };
 
 const char descriptor_table_protodef_dmi_2fhw_5fmanagement_5fservice_2eproto[] =
@@ -1020,47 +1197,85 @@
   "ail\030\005 \001(\t\"y\n\006Reason\022\024\n\020UNDEFINED_REASON\020"
   "\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\022\n\016INTERNAL_ERROR\020"
   "\002\022\026\n\022DEVICE_UNREACHABLE\020\003\022\031\n\025DEVICE_IN_W"
-  "RONG_STATE\020\0042\276\n\n\031NativeHWManagementServi"
-  "ce\022S\n\023StartManagingDevice\022\030.dmi.Modifiab"
-  "leComponent\032 .dmi.StartManagingDeviceRes"
-  "ponse0\001\022U\n\022StopManagingDevice\022\036.dmi.Stop"
-  "ManagingDeviceRequest\032\037.dmi.StopManaging"
-  "DeviceResponse\022H\n\021GetManagedDevices\022\026.go"
-  "ogle.protobuf.Empty\032\033.dmi.ManagedDevices"
-  "Response\022W\n\024GetPhysicalInventory\022\035.dmi.P"
-  "hysicalInventoryRequest\032\036.dmi.PhysicalIn"
-  "ventoryResponse0\001\022W\n\022GetHWComponentInfo\022"
-  "\036.dmi.HWComponentInfoGetRequest\032\037.dmi.HW"
-  "ComponentInfoGetResponse0\001\022U\n\022SetHWCompo"
-  "nentInfo\022\036.dmi.HWComponentInfoSetRequest"
-  "\032\037.dmi.HWComponentInfoSetResponse\022T\n\022Set"
-  "LoggingEndpoint\022\036.dmi.SetLoggingEndpoint"
-  "Request\032\036.dmi.SetRemoteEndpointResponse\022"
-  "F\n\022GetLoggingEndpoint\022\017.dmi.HardwareID\032\037"
-  ".dmi.GetLoggingEndpointResponse\022R\n\021SetMs"
-  "gBusEndpoint\022\035.dmi.SetMsgBusEndpointRequ"
-  "est\032\036.dmi.SetRemoteEndpointResponse\022K\n\021G"
-  "etMsgBusEndpoint\022\026.google.protobuf.Empty"
-  "\032\036.dmi.GetMsgBusEndpointResponse\022P\n\023GetL"
-  "oggableEntities\022\037.dmi.GetLoggableEntitie"
-  "sRequest\032\030.dmi.GetLogLevelResponse\022@\n\013Se"
-  "tLogLevel\022\027.dmi.SetLogLevelRequest\032\030.dmi"
-  ".SetLogLevelResponse\022@\n\013GetLogLevel\022\027.dm"
-  "i.GetLogLevelRequest\032\030.dmi.GetLogLevelRe"
-  "sponse\0228\n\016HeartbeatCheck\022\026.google.protob"
-  "uf.Empty\032\016.dmi.Heartbeat\022C\n\014RebootDevice"
-  "\022\030.dmi.RebootDeviceRequest\032\031.dmi.RebootD"
-  "eviceResponse\022F\n\rSetDmLogLevel\022\031.dmi.Set"
-  "DmLogLevelRequest\032\032.dmi.SetDmLogLevelRes"
-  "ponse\022F\n\rGetDmLogLevel\022\031.dmi.GetDmLogLev"
-  "elRequest\032\032.dmi.GetDmLogLevelResponseB;Z"
-  "9github.com/opencord/device-management-i"
-  "nterface/v3/go/dmib\006proto3"
+  "RONG_STATE\020\004\"v\n\031DisableHWComponentReques"
+  "t\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\022!\n\016com"
+  "ponent_uuid\030\002 \001(\0132\t.dmi.Uuid\022\026\n\016componen"
+  "t_name\030\003 \001(\t\"\255\002\n\032DisableHWComponentRespo"
+  "nse\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\0226\n\006reas"
+  "on\030\002 \001(\0162&.dmi.DisableHWComponentRespons"
+  "e.Reason\022\025\n\rreason_detail\030\003 \001(\t\"\242\001\n\006Reas"
+  "on\022\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN_DEVI"
+  "CE\020\001\022\025\n\021UNKNOWN_COMPONENT\020\002\022\022\n\016INTERNAL_"
+  "ERROR\020\003\022\026\n\022DEVICE_UNREACHABLE\020\004\022\027\n\023DISAB"
+  "LE_UNSUPPORTED\020\005\022\022\n\016INVALID_PARAMS\020\006\"t\n\027"
+  "ResetHWComponentRequest\022\036\n\013device_uuid\030\001"
+  " \001(\0132\t.dmi.Uuid\022!\n\016component_uuid\030\002 \001(\0132"
+  "\t.dmi.Uuid\022\026\n\016component_name\030\003 \001(\t\"\247\002\n\030R"
+  "esetHWComponentResponse\022\033\n\006status\030\001 \001(\0162"
+  "\013.dmi.Status\0224\n\006reason\030\002 \001(\0162$.dmi.Reset"
+  "HWComponentResponse.Reason\022\025\n\rreason_det"
+  "ail\030\003 \001(\t\"\240\001\n\006Reason\022\024\n\020UNDEFINED_REASON"
+  "\020\000\022\022\n\016UNKNOWN_DEVICE\020\001\022\025\n\021UNKNOWN_COMPON"
+  "ENT\020\002\022\022\n\016INTERNAL_ERROR\020\003\022\026\n\022DEVICE_UNRE"
+  "ACHABLE\020\004\022\025\n\021RESET_UNSUPPORTED\020\005\022\022\n\016INVA"
+  "LID_PARAMS\020\006\"u\n\030EnableHWComponentRequest"
+  "\022\036\n\013device_uuid\030\001 \001(\0132\t.dmi.Uuid\022!\n\016comp"
+  "onent_uuid\030\002 \001(\0132\t.dmi.Uuid\022\026\n\016component"
+  "_name\030\003 \001(\t\"\252\002\n\031EnableHWComponentRespons"
+  "e\022\033\n\006status\030\001 \001(\0162\013.dmi.Status\0225\n\006reason"
+  "\030\002 \001(\0162%.dmi.EnableHWComponentResponse.R"
+  "eason\022\025\n\rreason_detail\030\003 \001(\t\"\241\001\n\006Reason\022"
+  "\024\n\020UNDEFINED_REASON\020\000\022\022\n\016UNKNOWN_DEVICE\020"
+  "\001\022\025\n\021UNKNOWN_COMPONENT\020\002\022\022\n\016INTERNAL_ERR"
+  "OR\020\003\022\026\n\022DEVICE_UNREACHABLE\020\004\022\026\n\022ENABLE_U"
+  "NSUPPORTED\020\005\022\022\n\016INVALID_PARAMS\020\0062\272\014\n\031Nat"
+  "iveHWManagementService\022S\n\023StartManagingD"
+  "evice\022\030.dmi.ModifiableComponent\032 .dmi.St"
+  "artManagingDeviceResponse0\001\022U\n\022StopManag"
+  "ingDevice\022\036.dmi.StopManagingDeviceReques"
+  "t\032\037.dmi.StopManagingDeviceResponse\022H\n\021Ge"
+  "tManagedDevices\022\026.google.protobuf.Empty\032"
+  "\033.dmi.ManagedDevicesResponse\022W\n\024GetPhysi"
+  "calInventory\022\035.dmi.PhysicalInventoryRequ"
+  "est\032\036.dmi.PhysicalInventoryResponse0\001\022W\n"
+  "\022GetHWComponentInfo\022\036.dmi.HWComponentInf"
+  "oGetRequest\032\037.dmi.HWComponentInfoGetResp"
+  "onse0\001\022U\n\022SetHWComponentInfo\022\036.dmi.HWCom"
+  "ponentInfoSetRequest\032\037.dmi.HWComponentIn"
+  "foSetResponse\022T\n\022SetLoggingEndpoint\022\036.dm"
+  "i.SetLoggingEndpointRequest\032\036.dmi.SetRem"
+  "oteEndpointResponse\022F\n\022GetLoggingEndpoin"
+  "t\022\017.dmi.HardwareID\032\037.dmi.GetLoggingEndpo"
+  "intResponse\022R\n\021SetMsgBusEndpoint\022\035.dmi.S"
+  "etMsgBusEndpointRequest\032\036.dmi.SetRemoteE"
+  "ndpointResponse\022K\n\021GetMsgBusEndpoint\022\026.g"
+  "oogle.protobuf.Empty\032\036.dmi.GetMsgBusEndp"
+  "ointResponse\022P\n\023GetLoggableEntities\022\037.dm"
+  "i.GetLoggableEntitiesRequest\032\030.dmi.GetLo"
+  "gLevelResponse\022@\n\013SetLogLevel\022\027.dmi.SetL"
+  "ogLevelRequest\032\030.dmi.SetLogLevelResponse"
+  "\022@\n\013GetLogLevel\022\027.dmi.GetLogLevelRequest"
+  "\032\030.dmi.GetLogLevelResponse\0228\n\016HeartbeatC"
+  "heck\022\026.google.protobuf.Empty\032\016.dmi.Heart"
+  "beat\022C\n\014RebootDevice\022\030.dmi.RebootDeviceR"
+  "equest\032\031.dmi.RebootDeviceResponse\022F\n\rSet"
+  "DmLogLevel\022\031.dmi.SetDmLogLevelRequest\032\032."
+  "dmi.SetDmLogLevelResponse\022F\n\rGetDmLogLev"
+  "el\022\031.dmi.GetDmLogLevelRequest\032\032.dmi.GetD"
+  "mLogLevelResponse\022U\n\022DisableHWComponent\022"
+  "\036.dmi.DisableHWComponentRequest\032\037.dmi.Di"
+  "sableHWComponentResponse\022O\n\020ResetHWCompo"
+  "nent\022\034.dmi.ResetHWComponentRequest\032\035.dmi"
+  ".ResetHWComponentResponse\022R\n\021EnableHWCom"
+  "ponent\022\035.dmi.EnableHWComponentRequest\032\036."
+  "dmi.EnableHWComponentResponseB;Z9github."
+  "com/opencord/device-management-interface"
+  "/v3/go/dmib\006proto3"
   ;
 ::google::protobuf::internal::DescriptorTable descriptor_table_dmi_2fhw_5fmanagement_5fservice_2eproto = {
   false, InitDefaults_dmi_2fhw_5fmanagement_5fservice_2eproto, 
   descriptor_table_protodef_dmi_2fhw_5fmanagement_5fservice_2eproto,
-  "dmi/hw_management_service.proto", &assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto, 6386,
+  "dmi/hw_management_service.proto", &assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto, 7898,
 };
 
 void AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto() {
@@ -1438,6 +1653,99 @@
 const RebootDeviceResponse_Reason RebootDeviceResponse::Reason_MAX;
 const int RebootDeviceResponse::Reason_ARRAYSIZE;
 #endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* DisableHWComponentResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[14];
+}
+bool DisableHWComponentResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::UNDEFINED_REASON;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::UNKNOWN_DEVICE;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::UNKNOWN_COMPONENT;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::INTERNAL_ERROR;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::DEVICE_UNREACHABLE;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::DISABLE_UNSUPPORTED;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::INVALID_PARAMS;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::Reason_MIN;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse::Reason_MAX;
+const int DisableHWComponentResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* ResetHWComponentResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[15];
+}
+bool ResetHWComponentResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::UNDEFINED_REASON;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::UNKNOWN_DEVICE;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::UNKNOWN_COMPONENT;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::INTERNAL_ERROR;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::DEVICE_UNREACHABLE;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::RESET_UNSUPPORTED;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::INVALID_PARAMS;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::Reason_MIN;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse::Reason_MAX;
+const int ResetHWComponentResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+const ::google::protobuf::EnumDescriptor* EnableHWComponentResponse_Reason_descriptor() {
+  ::google::protobuf::internal::AssignDescriptors(&assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return file_level_enum_descriptors_dmi_2fhw_5fmanagement_5fservice_2eproto[16];
+}
+bool EnableHWComponentResponse_Reason_IsValid(int value) {
+  switch (value) {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+      return true;
+    default:
+      return false;
+  }
+}
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::UNDEFINED_REASON;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::UNKNOWN_DEVICE;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::UNKNOWN_COMPONENT;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::INTERNAL_ERROR;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::DEVICE_UNREACHABLE;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::ENABLE_UNSUPPORTED;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::INVALID_PARAMS;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::Reason_MIN;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse::Reason_MAX;
+const int EnableHWComponentResponse::Reason_ARRAYSIZE;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
 
 // ===================================================================
 
@@ -12681,6 +12989,2526 @@
 }
 
 
+// ===================================================================
+
+void DisableHWComponentRequest::InitAsDefaultInstance() {
+  ::dmi::_DisableHWComponentRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_DisableHWComponentRequest_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class DisableHWComponentRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const DisableHWComponentRequest* msg);
+  static const ::dmi::Uuid& component_uuid(const DisableHWComponentRequest* msg);
+};
+
+const ::dmi::Uuid&
+DisableHWComponentRequest::HasBitSetters::device_uuid(const DisableHWComponentRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+DisableHWComponentRequest::HasBitSetters::component_uuid(const DisableHWComponentRequest* msg) {
+  return *msg->component_uuid_;
+}
+void DisableHWComponentRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void DisableHWComponentRequest::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int DisableHWComponentRequest::kDeviceUuidFieldNumber;
+const int DisableHWComponentRequest::kComponentUuidFieldNumber;
+const int DisableHWComponentRequest::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+DisableHWComponentRequest::DisableHWComponentRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.DisableHWComponentRequest)
+}
+DisableHWComponentRequest::DisableHWComponentRequest(const DisableHWComponentRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.DisableHWComponentRequest)
+}
+
+void DisableHWComponentRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_DisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+DisableHWComponentRequest::~DisableHWComponentRequest() {
+  // @@protoc_insertion_point(destructor:dmi.DisableHWComponentRequest)
+  SharedDtor();
+}
+
+void DisableHWComponentRequest::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void DisableHWComponentRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const DisableHWComponentRequest& DisableHWComponentRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_DisableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void DisableHWComponentRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.DisableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DisableHWComponentRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DisableHWComponentRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.DisableHWComponentRequest.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool DisableHWComponentRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.DisableHWComponentRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.DisableHWComponentRequest.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.DisableHWComponentRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.DisableHWComponentRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void DisableHWComponentRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.DisableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.DisableHWComponentRequest.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.DisableHWComponentRequest)
+}
+
+::google::protobuf::uint8* DisableHWComponentRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.DisableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.DisableHWComponentRequest.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.DisableHWComponentRequest)
+  return target;
+}
+
+size_t DisableHWComponentRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.DisableHWComponentRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void DisableHWComponentRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.DisableHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const DisableHWComponentRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<DisableHWComponentRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.DisableHWComponentRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.DisableHWComponentRequest)
+    MergeFrom(*source);
+  }
+}
+
+void DisableHWComponentRequest::MergeFrom(const DisableHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.DisableHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void DisableHWComponentRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.DisableHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void DisableHWComponentRequest::CopyFrom(const DisableHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.DisableHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool DisableHWComponentRequest::IsInitialized() const {
+  return true;
+}
+
+void DisableHWComponentRequest::Swap(DisableHWComponentRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void DisableHWComponentRequest::InternalSwap(DisableHWComponentRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata DisableHWComponentRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void DisableHWComponentResponse::InitAsDefaultInstance() {
+}
+class DisableHWComponentResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int DisableHWComponentResponse::kStatusFieldNumber;
+const int DisableHWComponentResponse::kReasonFieldNumber;
+const int DisableHWComponentResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+DisableHWComponentResponse::DisableHWComponentResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.DisableHWComponentResponse)
+}
+DisableHWComponentResponse::DisableHWComponentResponse(const DisableHWComponentResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.DisableHWComponentResponse)
+}
+
+void DisableHWComponentResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_DisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+DisableHWComponentResponse::~DisableHWComponentResponse() {
+  // @@protoc_insertion_point(destructor:dmi.DisableHWComponentResponse)
+  SharedDtor();
+}
+
+void DisableHWComponentResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void DisableHWComponentResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const DisableHWComponentResponse& DisableHWComponentResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_DisableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void DisableHWComponentResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.DisableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* DisableHWComponentResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<DisableHWComponentResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.DisableHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::DisableHWComponentResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.DisableHWComponentResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool DisableHWComponentResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.DisableHWComponentResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.DisableHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::DisableHWComponentResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.DisableHWComponentResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.DisableHWComponentResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.DisableHWComponentResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void DisableHWComponentResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.DisableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.DisableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.DisableHWComponentResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.DisableHWComponentResponse)
+}
+
+::google::protobuf::uint8* DisableHWComponentResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.DisableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.DisableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.DisableHWComponentResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.DisableHWComponentResponse)
+  return target;
+}
+
+size_t DisableHWComponentResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.DisableHWComponentResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.DisableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void DisableHWComponentResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.DisableHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const DisableHWComponentResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<DisableHWComponentResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.DisableHWComponentResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.DisableHWComponentResponse)
+    MergeFrom(*source);
+  }
+}
+
+void DisableHWComponentResponse::MergeFrom(const DisableHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.DisableHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void DisableHWComponentResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.DisableHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void DisableHWComponentResponse::CopyFrom(const DisableHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.DisableHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool DisableHWComponentResponse::IsInitialized() const {
+  return true;
+}
+
+void DisableHWComponentResponse::Swap(DisableHWComponentResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void DisableHWComponentResponse::InternalSwap(DisableHWComponentResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata DisableHWComponentResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ResetHWComponentRequest::InitAsDefaultInstance() {
+  ::dmi::_ResetHWComponentRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_ResetHWComponentRequest_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class ResetHWComponentRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const ResetHWComponentRequest* msg);
+  static const ::dmi::Uuid& component_uuid(const ResetHWComponentRequest* msg);
+};
+
+const ::dmi::Uuid&
+ResetHWComponentRequest::HasBitSetters::device_uuid(const ResetHWComponentRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+ResetHWComponentRequest::HasBitSetters::component_uuid(const ResetHWComponentRequest* msg) {
+  return *msg->component_uuid_;
+}
+void ResetHWComponentRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void ResetHWComponentRequest::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ResetHWComponentRequest::kDeviceUuidFieldNumber;
+const int ResetHWComponentRequest::kComponentUuidFieldNumber;
+const int ResetHWComponentRequest::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ResetHWComponentRequest::ResetHWComponentRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ResetHWComponentRequest)
+}
+ResetHWComponentRequest::ResetHWComponentRequest(const ResetHWComponentRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.ResetHWComponentRequest)
+}
+
+void ResetHWComponentRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+ResetHWComponentRequest::~ResetHWComponentRequest() {
+  // @@protoc_insertion_point(destructor:dmi.ResetHWComponentRequest)
+  SharedDtor();
+}
+
+void ResetHWComponentRequest::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void ResetHWComponentRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ResetHWComponentRequest& ResetHWComponentRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ResetHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ResetHWComponentRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ResetHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ResetHWComponentRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ResetHWComponentRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ResetHWComponentRequest.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ResetHWComponentRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ResetHWComponentRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ResetHWComponentRequest.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ResetHWComponentRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ResetHWComponentRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ResetHWComponentRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ResetHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ResetHWComponentRequest.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ResetHWComponentRequest)
+}
+
+::google::protobuf::uint8* ResetHWComponentRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ResetHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ResetHWComponentRequest.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ResetHWComponentRequest)
+  return target;
+}
+
+size_t ResetHWComponentRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ResetHWComponentRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ResetHWComponentRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ResetHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ResetHWComponentRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<ResetHWComponentRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ResetHWComponentRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ResetHWComponentRequest)
+    MergeFrom(*source);
+  }
+}
+
+void ResetHWComponentRequest::MergeFrom(const ResetHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ResetHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void ResetHWComponentRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ResetHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ResetHWComponentRequest::CopyFrom(const ResetHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ResetHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ResetHWComponentRequest::IsInitialized() const {
+  return true;
+}
+
+void ResetHWComponentRequest::Swap(ResetHWComponentRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ResetHWComponentRequest::InternalSwap(ResetHWComponentRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata ResetHWComponentRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void ResetHWComponentResponse::InitAsDefaultInstance() {
+}
+class ResetHWComponentResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int ResetHWComponentResponse::kStatusFieldNumber;
+const int ResetHWComponentResponse::kReasonFieldNumber;
+const int ResetHWComponentResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+ResetHWComponentResponse::ResetHWComponentResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.ResetHWComponentResponse)
+}
+ResetHWComponentResponse::ResetHWComponentResponse(const ResetHWComponentResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.ResetHWComponentResponse)
+}
+
+void ResetHWComponentResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_ResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+ResetHWComponentResponse::~ResetHWComponentResponse() {
+  // @@protoc_insertion_point(destructor:dmi.ResetHWComponentResponse)
+  SharedDtor();
+}
+
+void ResetHWComponentResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void ResetHWComponentResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const ResetHWComponentResponse& ResetHWComponentResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_ResetHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void ResetHWComponentResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.ResetHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* ResetHWComponentResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<ResetHWComponentResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.ResetHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::ResetHWComponentResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.ResetHWComponentResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool ResetHWComponentResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.ResetHWComponentResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.ResetHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::ResetHWComponentResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.ResetHWComponentResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.ResetHWComponentResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.ResetHWComponentResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void ResetHWComponentResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.ResetHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.ResetHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ResetHWComponentResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.ResetHWComponentResponse)
+}
+
+::google::protobuf::uint8* ResetHWComponentResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.ResetHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.ResetHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.ResetHWComponentResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.ResetHWComponentResponse)
+  return target;
+}
+
+size_t ResetHWComponentResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.ResetHWComponentResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.ResetHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void ResetHWComponentResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.ResetHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const ResetHWComponentResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<ResetHWComponentResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.ResetHWComponentResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.ResetHWComponentResponse)
+    MergeFrom(*source);
+  }
+}
+
+void ResetHWComponentResponse::MergeFrom(const ResetHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.ResetHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void ResetHWComponentResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.ResetHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void ResetHWComponentResponse::CopyFrom(const ResetHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.ResetHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool ResetHWComponentResponse::IsInitialized() const {
+  return true;
+}
+
+void ResetHWComponentResponse::Swap(ResetHWComponentResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void ResetHWComponentResponse::InternalSwap(ResetHWComponentResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata ResetHWComponentResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EnableHWComponentRequest::InitAsDefaultInstance() {
+  ::dmi::_EnableHWComponentRequest_default_instance_._instance.get_mutable()->device_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+  ::dmi::_EnableHWComponentRequest_default_instance_._instance.get_mutable()->component_uuid_ = const_cast< ::dmi::Uuid*>(
+      ::dmi::Uuid::internal_default_instance());
+}
+class EnableHWComponentRequest::HasBitSetters {
+ public:
+  static const ::dmi::Uuid& device_uuid(const EnableHWComponentRequest* msg);
+  static const ::dmi::Uuid& component_uuid(const EnableHWComponentRequest* msg);
+};
+
+const ::dmi::Uuid&
+EnableHWComponentRequest::HasBitSetters::device_uuid(const EnableHWComponentRequest* msg) {
+  return *msg->device_uuid_;
+}
+const ::dmi::Uuid&
+EnableHWComponentRequest::HasBitSetters::component_uuid(const EnableHWComponentRequest* msg) {
+  return *msg->component_uuid_;
+}
+void EnableHWComponentRequest::clear_device_uuid() {
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+}
+void EnableHWComponentRequest::clear_component_uuid() {
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+}
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EnableHWComponentRequest::kDeviceUuidFieldNumber;
+const int EnableHWComponentRequest::kComponentUuidFieldNumber;
+const int EnableHWComponentRequest::kComponentNameFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EnableHWComponentRequest::EnableHWComponentRequest()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EnableHWComponentRequest)
+}
+EnableHWComponentRequest::EnableHWComponentRequest(const EnableHWComponentRequest& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.component_name().size() > 0) {
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    device_uuid_ = new ::dmi::Uuid(*from.device_uuid_);
+  } else {
+    device_uuid_ = nullptr;
+  }
+  if (from.has_component_uuid()) {
+    component_uuid_ = new ::dmi::Uuid(*from.component_uuid_);
+  } else {
+    component_uuid_ = nullptr;
+  }
+  // @@protoc_insertion_point(copy_constructor:dmi.EnableHWComponentRequest)
+}
+
+void EnableHWComponentRequest::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  component_name_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&device_uuid_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&component_uuid_) -
+      reinterpret_cast<char*>(&device_uuid_)) + sizeof(component_uuid_));
+}
+
+EnableHWComponentRequest::~EnableHWComponentRequest() {
+  // @@protoc_insertion_point(destructor:dmi.EnableHWComponentRequest)
+  SharedDtor();
+}
+
+void EnableHWComponentRequest::SharedDtor() {
+  component_name_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (this != internal_default_instance()) delete device_uuid_;
+  if (this != internal_default_instance()) delete component_uuid_;
+}
+
+void EnableHWComponentRequest::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EnableHWComponentRequest& EnableHWComponentRequest::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnableHWComponentRequest_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EnableHWComponentRequest::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EnableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (GetArenaNoVirtual() == nullptr && device_uuid_ != nullptr) {
+    delete device_uuid_;
+  }
+  device_uuid_ = nullptr;
+  if (GetArenaNoVirtual() == nullptr && component_uuid_ != nullptr) {
+    delete component_uuid_;
+  }
+  component_uuid_ = nullptr;
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnableHWComponentRequest::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnableHWComponentRequest*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 10) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_device_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 18) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        parser_till_end = ::dmi::Uuid::_InternalParse;
+        object = msg->mutable_component_uuid();
+        if (size > end - ptr) goto len_delim_till_end;
+        ptr += size;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ctx->ParseExactRange(
+            {parser_till_end, object}, ptr - size, ptr));
+        break;
+      }
+      // string component_name = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.EnableHWComponentRequest.component_name");
+        object = msg->mutable_component_name();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EnableHWComponentRequest::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EnableHWComponentRequest)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Uuid device_uuid = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (10 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_device_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.Uuid component_uuid = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (18 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadMessage(
+               input, mutable_component_uuid()));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string component_name = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_component_name()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->component_name().data(), static_cast<int>(this->component_name().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.EnableHWComponentRequest.component_name"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EnableHWComponentRequest)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EnableHWComponentRequest)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EnableHWComponentRequest::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EnableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      1, HasBitSetters::device_uuid(this), output);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
+      2, HasBitSetters::component_uuid(this), output);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EnableHWComponentRequest.component_name");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->component_name(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EnableHWComponentRequest)
+}
+
+::google::protobuf::uint8* EnableHWComponentRequest::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EnableHWComponentRequest)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        1, HasBitSetters::device_uuid(this), target);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    target = ::google::protobuf::internal::WireFormatLite::
+      InternalWriteMessageToArray(
+        2, HasBitSetters::component_uuid(this), target);
+  }
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->component_name().data(), static_cast<int>(this->component_name().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EnableHWComponentRequest.component_name");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->component_name(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EnableHWComponentRequest)
+  return target;
+}
+
+size_t EnableHWComponentRequest::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EnableHWComponentRequest)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string component_name = 3;
+  if (this->component_name().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->component_name());
+  }
+
+  // .dmi.Uuid device_uuid = 1;
+  if (this->has_device_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *device_uuid_);
+  }
+
+  // .dmi.Uuid component_uuid = 2;
+  if (this->has_component_uuid()) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::MessageSize(
+        *component_uuid_);
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EnableHWComponentRequest::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EnableHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EnableHWComponentRequest* source =
+      ::google::protobuf::DynamicCastToGenerated<EnableHWComponentRequest>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EnableHWComponentRequest)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EnableHWComponentRequest)
+    MergeFrom(*source);
+  }
+}
+
+void EnableHWComponentRequest::MergeFrom(const EnableHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EnableHWComponentRequest)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.component_name().size() > 0) {
+
+    component_name_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.component_name_);
+  }
+  if (from.has_device_uuid()) {
+    mutable_device_uuid()->::dmi::Uuid::MergeFrom(from.device_uuid());
+  }
+  if (from.has_component_uuid()) {
+    mutable_component_uuid()->::dmi::Uuid::MergeFrom(from.component_uuid());
+  }
+}
+
+void EnableHWComponentRequest::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EnableHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnableHWComponentRequest::CopyFrom(const EnableHWComponentRequest& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EnableHWComponentRequest)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnableHWComponentRequest::IsInitialized() const {
+  return true;
+}
+
+void EnableHWComponentRequest::Swap(EnableHWComponentRequest* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EnableHWComponentRequest::InternalSwap(EnableHWComponentRequest* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  component_name_.Swap(&other->component_name_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(device_uuid_, other->device_uuid_);
+  swap(component_uuid_, other->component_uuid_);
+}
+
+::google::protobuf::Metadata EnableHWComponentRequest::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
+// ===================================================================
+
+void EnableHWComponentResponse::InitAsDefaultInstance() {
+}
+class EnableHWComponentResponse::HasBitSetters {
+ public:
+};
+
+#if !defined(_MSC_VER) || _MSC_VER >= 1900
+const int EnableHWComponentResponse::kStatusFieldNumber;
+const int EnableHWComponentResponse::kReasonFieldNumber;
+const int EnableHWComponentResponse::kReasonDetailFieldNumber;
+#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
+
+EnableHWComponentResponse::EnableHWComponentResponse()
+  : ::google::protobuf::Message(), _internal_metadata_(nullptr) {
+  SharedCtor();
+  // @@protoc_insertion_point(constructor:dmi.EnableHWComponentResponse)
+}
+EnableHWComponentResponse::EnableHWComponentResponse(const EnableHWComponentResponse& from)
+  : ::google::protobuf::Message(),
+      _internal_metadata_(nullptr) {
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  if (from.reason_detail().size() > 0) {
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  ::memcpy(&status_, &from.status_,
+    static_cast<size_t>(reinterpret_cast<char*>(&reason_) -
+    reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  // @@protoc_insertion_point(copy_constructor:dmi.EnableHWComponentResponse)
+}
+
+void EnableHWComponentResponse::SharedCtor() {
+  ::google::protobuf::internal::InitSCC(
+      &scc_info_EnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  reason_detail_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+}
+
+EnableHWComponentResponse::~EnableHWComponentResponse() {
+  // @@protoc_insertion_point(destructor:dmi.EnableHWComponentResponse)
+  SharedDtor();
+}
+
+void EnableHWComponentResponse::SharedDtor() {
+  reason_detail_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+
+void EnableHWComponentResponse::SetCachedSize(int size) const {
+  _cached_size_.Set(size);
+}
+const EnableHWComponentResponse& EnableHWComponentResponse::default_instance() {
+  ::google::protobuf::internal::InitSCC(&::scc_info_EnableHWComponentResponse_dmi_2fhw_5fmanagement_5fservice_2eproto.base);
+  return *internal_default_instance();
+}
+
+
+void EnableHWComponentResponse::Clear() {
+// @@protoc_insertion_point(message_clear_start:dmi.EnableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+  ::memset(&status_, 0, static_cast<size_t>(
+      reinterpret_cast<char*>(&reason_) -
+      reinterpret_cast<char*>(&status_)) + sizeof(reason_));
+  _internal_metadata_.Clear();
+}
+
+#if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+const char* EnableHWComponentResponse::_InternalParse(const char* begin, const char* end, void* object,
+                  ::google::protobuf::internal::ParseContext* ctx) {
+  auto msg = static_cast<EnableHWComponentResponse*>(object);
+  ::google::protobuf::int32 size; (void)size;
+  int depth; (void)depth;
+  ::google::protobuf::uint32 tag;
+  ::google::protobuf::internal::ParseFunc parser_till_end; (void)parser_till_end;
+  auto ptr = begin;
+  while (ptr < end) {
+    ptr = ::google::protobuf::io::Parse32(ptr, &tag);
+    GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+    switch (tag >> 3) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 8) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_status(static_cast<::dmi::Status>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // .dmi.EnableHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 16) goto handle_unusual;
+        ::google::protobuf::uint64 val = ::google::protobuf::internal::ReadVarint(&ptr);
+        msg->set_reason(static_cast<::dmi::EnableHWComponentResponse_Reason>(val));
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        break;
+      }
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast<::google::protobuf::uint8>(tag) != 26) goto handle_unusual;
+        ptr = ::google::protobuf::io::ReadSize(ptr, &size);
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
+        ctx->extra_parse_data().SetFieldName("dmi.EnableHWComponentResponse.reason_detail");
+        object = msg->mutable_reason_detail();
+        if (size > end - ptr + ::google::protobuf::internal::ParseContext::kSlopBytes) {
+          parser_till_end = ::google::protobuf::internal::GreedyStringParserUTF8;
+          goto string_till_end;
+        }
+        GOOGLE_PROTOBUF_PARSER_ASSERT(::google::protobuf::internal::StringCheckUTF8(ptr, size, ctx));
+        ::google::protobuf::internal::InlineGreedyStringParser(object, ptr, size, ctx);
+        ptr += size;
+        break;
+      }
+      default: {
+      handle_unusual:
+        if ((tag & 7) == 4 || tag == 0) {
+          ctx->EndGroup(tag);
+          return ptr;
+        }
+        auto res = UnknownFieldParse(tag, {_InternalParse, msg},
+          ptr, end, msg->_internal_metadata_.mutable_unknown_fields(), ctx);
+        ptr = res.first;
+        GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
+        if (res.second) return ptr;
+      }
+    }  // switch
+  }  // while
+  return ptr;
+string_till_end:
+  static_cast<::std::string*>(object)->clear();
+  static_cast<::std::string*>(object)->reserve(size);
+  goto len_delim_till_end;
+len_delim_till_end:
+  return ctx->StoreAndTailCall(ptr, end, {_InternalParse, msg},
+                               {parser_till_end, object}, size);
+}
+#else  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+bool EnableHWComponentResponse::MergePartialFromCodedStream(
+    ::google::protobuf::io::CodedInputStream* input) {
+#define DO_(EXPRESSION) if (!PROTOBUF_PREDICT_TRUE(EXPRESSION)) goto failure
+  ::google::protobuf::uint32 tag;
+  // @@protoc_insertion_point(parse_start:dmi.EnableHWComponentResponse)
+  for (;;) {
+    ::std::pair<::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u);
+    tag = p.first;
+    if (!p.second) goto handle_unusual;
+    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
+      // .dmi.Status status = 1;
+      case 1: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (8 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_status(static_cast< ::dmi::Status >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // .dmi.EnableHWComponentResponse.Reason reason = 2;
+      case 2: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (16 & 0xFF)) {
+          int value = 0;
+          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
+                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
+                 input, &value)));
+          set_reason(static_cast< ::dmi::EnableHWComponentResponse_Reason >(value));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      // string reason_detail = 3;
+      case 3: {
+        if (static_cast< ::google::protobuf::uint8>(tag) == (26 & 0xFF)) {
+          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
+                input, this->mutable_reason_detail()));
+          DO_(::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+            this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+            ::google::protobuf::internal::WireFormatLite::PARSE,
+            "dmi.EnableHWComponentResponse.reason_detail"));
+        } else {
+          goto handle_unusual;
+        }
+        break;
+      }
+
+      default: {
+      handle_unusual:
+        if (tag == 0) {
+          goto success;
+        }
+        DO_(::google::protobuf::internal::WireFormat::SkipField(
+              input, tag, _internal_metadata_.mutable_unknown_fields()));
+        break;
+      }
+    }
+  }
+success:
+  // @@protoc_insertion_point(parse_success:dmi.EnableHWComponentResponse)
+  return true;
+failure:
+  // @@protoc_insertion_point(parse_failure:dmi.EnableHWComponentResponse)
+  return false;
+#undef DO_
+}
+#endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+
+void EnableHWComponentResponse::SerializeWithCachedSizes(
+    ::google::protobuf::io::CodedOutputStream* output) const {
+  // @@protoc_insertion_point(serialize_start:dmi.EnableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      1, this->status(), output);
+  }
+
+  // .dmi.EnableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    ::google::protobuf::internal::WireFormatLite::WriteEnum(
+      2, this->reason(), output);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EnableHWComponentResponse.reason_detail");
+    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
+      3, this->reason_detail(), output);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
+        _internal_metadata_.unknown_fields(), output);
+  }
+  // @@protoc_insertion_point(serialize_end:dmi.EnableHWComponentResponse)
+}
+
+::google::protobuf::uint8* EnableHWComponentResponse::InternalSerializeWithCachedSizesToArray(
+    ::google::protobuf::uint8* target) const {
+  // @@protoc_insertion_point(serialize_to_array_start:dmi.EnableHWComponentResponse)
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      1, this->status(), target);
+  }
+
+  // .dmi.EnableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
+      2, this->reason(), target);
+  }
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    ::google::protobuf::internal::WireFormatLite::VerifyUtf8String(
+      this->reason_detail().data(), static_cast<int>(this->reason_detail().length()),
+      ::google::protobuf::internal::WireFormatLite::SERIALIZE,
+      "dmi.EnableHWComponentResponse.reason_detail");
+    target =
+      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
+        3, this->reason_detail(), target);
+  }
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
+        _internal_metadata_.unknown_fields(), target);
+  }
+  // @@protoc_insertion_point(serialize_to_array_end:dmi.EnableHWComponentResponse)
+  return target;
+}
+
+size_t EnableHWComponentResponse::ByteSizeLong() const {
+// @@protoc_insertion_point(message_byte_size_start:dmi.EnableHWComponentResponse)
+  size_t total_size = 0;
+
+  if (_internal_metadata_.have_unknown_fields()) {
+    total_size +=
+      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
+        _internal_metadata_.unknown_fields());
+  }
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  // Prevent compiler warnings about cached_has_bits being unused
+  (void) cached_has_bits;
+
+  // string reason_detail = 3;
+  if (this->reason_detail().size() > 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::StringSize(
+        this->reason_detail());
+  }
+
+  // .dmi.Status status = 1;
+  if (this->status() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
+  }
+
+  // .dmi.EnableHWComponentResponse.Reason reason = 2;
+  if (this->reason() != 0) {
+    total_size += 1 +
+      ::google::protobuf::internal::WireFormatLite::EnumSize(this->reason());
+  }
+
+  int cached_size = ::google::protobuf::internal::ToCachedSize(total_size);
+  SetCachedSize(cached_size);
+  return total_size;
+}
+
+void EnableHWComponentResponse::MergeFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_merge_from_start:dmi.EnableHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  const EnableHWComponentResponse* source =
+      ::google::protobuf::DynamicCastToGenerated<EnableHWComponentResponse>(
+          &from);
+  if (source == nullptr) {
+  // @@protoc_insertion_point(generalized_merge_from_cast_fail:dmi.EnableHWComponentResponse)
+    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
+  } else {
+  // @@protoc_insertion_point(generalized_merge_from_cast_success:dmi.EnableHWComponentResponse)
+    MergeFrom(*source);
+  }
+}
+
+void EnableHWComponentResponse::MergeFrom(const EnableHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_merge_from_start:dmi.EnableHWComponentResponse)
+  GOOGLE_DCHECK_NE(&from, this);
+  _internal_metadata_.MergeFrom(from._internal_metadata_);
+  ::google::protobuf::uint32 cached_has_bits = 0;
+  (void) cached_has_bits;
+
+  if (from.reason_detail().size() > 0) {
+
+    reason_detail_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.reason_detail_);
+  }
+  if (from.status() != 0) {
+    set_status(from.status());
+  }
+  if (from.reason() != 0) {
+    set_reason(from.reason());
+  }
+}
+
+void EnableHWComponentResponse::CopyFrom(const ::google::protobuf::Message& from) {
+// @@protoc_insertion_point(generalized_copy_from_start:dmi.EnableHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+void EnableHWComponentResponse::CopyFrom(const EnableHWComponentResponse& from) {
+// @@protoc_insertion_point(class_specific_copy_from_start:dmi.EnableHWComponentResponse)
+  if (&from == this) return;
+  Clear();
+  MergeFrom(from);
+}
+
+bool EnableHWComponentResponse::IsInitialized() const {
+  return true;
+}
+
+void EnableHWComponentResponse::Swap(EnableHWComponentResponse* other) {
+  if (other == this) return;
+  InternalSwap(other);
+}
+void EnableHWComponentResponse::InternalSwap(EnableHWComponentResponse* other) {
+  using std::swap;
+  _internal_metadata_.Swap(&other->_internal_metadata_);
+  reason_detail_.Swap(&other->reason_detail_, &::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+    GetArenaNoVirtual());
+  swap(status_, other->status_);
+  swap(reason_, other->reason_);
+}
+
+::google::protobuf::Metadata EnableHWComponentResponse::GetMetadata() const {
+  ::google::protobuf::internal::AssignDescriptors(&::assign_descriptors_table_dmi_2fhw_5fmanagement_5fservice_2eproto);
+  return ::file_level_metadata_dmi_2fhw_5fmanagement_5fservice_2eproto[kIndexInFileMessages];
+}
+
+
 // @@protoc_insertion_point(namespace_scope)
 }  // namespace dmi
 namespace google {
@@ -12772,6 +15600,24 @@
 template<> PROTOBUF_NOINLINE ::dmi::RebootDeviceResponse* Arena::CreateMaybeMessage< ::dmi::RebootDeviceResponse >(Arena* arena) {
   return Arena::CreateInternal< ::dmi::RebootDeviceResponse >(arena);
 }
+template<> PROTOBUF_NOINLINE ::dmi::DisableHWComponentRequest* Arena::CreateMaybeMessage< ::dmi::DisableHWComponentRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::DisableHWComponentRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::DisableHWComponentResponse* Arena::CreateMaybeMessage< ::dmi::DisableHWComponentResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::DisableHWComponentResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ResetHWComponentRequest* Arena::CreateMaybeMessage< ::dmi::ResetHWComponentRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ResetHWComponentRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::ResetHWComponentResponse* Arena::CreateMaybeMessage< ::dmi::ResetHWComponentResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::ResetHWComponentResponse >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EnableHWComponentRequest* Arena::CreateMaybeMessage< ::dmi::EnableHWComponentRequest >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EnableHWComponentRequest >(arena);
+}
+template<> PROTOBUF_NOINLINE ::dmi::EnableHWComponentResponse* Arena::CreateMaybeMessage< ::dmi::EnableHWComponentResponse >(Arena* arena) {
+  return Arena::CreateInternal< ::dmi::EnableHWComponentResponse >(arena);
+}
 }  // namespace protobuf
 }  // namespace google
 
diff --git a/cpp/dmi/hw_management_service.pb.h b/cpp/dmi/hw_management_service.pb.h
index 7f502f3..fbaa2de 100644
--- a/cpp/dmi/hw_management_service.pb.h
+++ b/cpp/dmi/hw_management_service.pb.h
@@ -45,7 +45,7 @@
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::AuxillaryParseTableField aux[]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
-  static const ::google::protobuf::internal::ParseTable schema[29]
+  static const ::google::protobuf::internal::ParseTable schema[35]
     PROTOBUF_SECTION_VARIABLE(protodesc_cold);
   static const ::google::protobuf::internal::FieldMetadata field_metadata[];
   static const ::google::protobuf::internal::SerializationTable serialization_table[];
@@ -53,6 +53,18 @@
 };
 void AddDescriptors_dmi_2fhw_5fmanagement_5fservice_2eproto();
 namespace dmi {
+class DisableHWComponentRequest;
+class DisableHWComponentRequestDefaultTypeInternal;
+extern DisableHWComponentRequestDefaultTypeInternal _DisableHWComponentRequest_default_instance_;
+class DisableHWComponentResponse;
+class DisableHWComponentResponseDefaultTypeInternal;
+extern DisableHWComponentResponseDefaultTypeInternal _DisableHWComponentResponse_default_instance_;
+class EnableHWComponentRequest;
+class EnableHWComponentRequestDefaultTypeInternal;
+extern EnableHWComponentRequestDefaultTypeInternal _EnableHWComponentRequest_default_instance_;
+class EnableHWComponentResponse;
+class EnableHWComponentResponseDefaultTypeInternal;
+extern EnableHWComponentResponseDefaultTypeInternal _EnableHWComponentResponse_default_instance_;
 class EntitiesLogLevel;
 class EntitiesLogLevelDefaultTypeInternal;
 extern EntitiesLogLevelDefaultTypeInternal _EntitiesLogLevel_default_instance_;
@@ -110,6 +122,12 @@
 class RebootDeviceResponse;
 class RebootDeviceResponseDefaultTypeInternal;
 extern RebootDeviceResponseDefaultTypeInternal _RebootDeviceResponse_default_instance_;
+class ResetHWComponentRequest;
+class ResetHWComponentRequestDefaultTypeInternal;
+extern ResetHWComponentRequestDefaultTypeInternal _ResetHWComponentRequest_default_instance_;
+class ResetHWComponentResponse;
+class ResetHWComponentResponseDefaultTypeInternal;
+extern ResetHWComponentResponseDefaultTypeInternal _ResetHWComponentResponse_default_instance_;
 class SetDmLogLevelRequest;
 class SetDmLogLevelRequestDefaultTypeInternal;
 extern SetDmLogLevelRequestDefaultTypeInternal _SetDmLogLevelRequest_default_instance_;
@@ -143,6 +161,10 @@
 }  // namespace dmi
 namespace google {
 namespace protobuf {
+template<> ::dmi::DisableHWComponentRequest* Arena::CreateMaybeMessage<::dmi::DisableHWComponentRequest>(Arena*);
+template<> ::dmi::DisableHWComponentResponse* Arena::CreateMaybeMessage<::dmi::DisableHWComponentResponse>(Arena*);
+template<> ::dmi::EnableHWComponentRequest* Arena::CreateMaybeMessage<::dmi::EnableHWComponentRequest>(Arena*);
+template<> ::dmi::EnableHWComponentResponse* Arena::CreateMaybeMessage<::dmi::EnableHWComponentResponse>(Arena*);
 template<> ::dmi::EntitiesLogLevel* Arena::CreateMaybeMessage<::dmi::EntitiesLogLevel>(Arena*);
 template<> ::dmi::GetDmLogLevelRequest* Arena::CreateMaybeMessage<::dmi::GetDmLogLevelRequest>(Arena*);
 template<> ::dmi::GetDmLogLevelResponse* Arena::CreateMaybeMessage<::dmi::GetDmLogLevelResponse>(Arena*);
@@ -162,6 +184,8 @@
 template<> ::dmi::PhysicalInventoryResponse* Arena::CreateMaybeMessage<::dmi::PhysicalInventoryResponse>(Arena*);
 template<> ::dmi::RebootDeviceRequest* Arena::CreateMaybeMessage<::dmi::RebootDeviceRequest>(Arena*);
 template<> ::dmi::RebootDeviceResponse* Arena::CreateMaybeMessage<::dmi::RebootDeviceResponse>(Arena*);
+template<> ::dmi::ResetHWComponentRequest* Arena::CreateMaybeMessage<::dmi::ResetHWComponentRequest>(Arena*);
+template<> ::dmi::ResetHWComponentResponse* Arena::CreateMaybeMessage<::dmi::ResetHWComponentResponse>(Arena*);
 template<> ::dmi::SetDmLogLevelRequest* Arena::CreateMaybeMessage<::dmi::SetDmLogLevelRequest>(Arena*);
 template<> ::dmi::SetDmLogLevelResponse* Arena::CreateMaybeMessage<::dmi::SetDmLogLevelResponse>(Arena*);
 template<> ::dmi::SetLogLevelRequest* Arena::CreateMaybeMessage<::dmi::SetLogLevelRequest>(Arena*);
@@ -504,6 +528,84 @@
   return ::google::protobuf::internal::ParseNamedEnum<RebootDeviceResponse_Reason>(
     RebootDeviceResponse_Reason_descriptor(), name, value);
 }
+enum DisableHWComponentResponse_Reason {
+  DisableHWComponentResponse_Reason_UNDEFINED_REASON = 0,
+  DisableHWComponentResponse_Reason_UNKNOWN_DEVICE = 1,
+  DisableHWComponentResponse_Reason_UNKNOWN_COMPONENT = 2,
+  DisableHWComponentResponse_Reason_INTERNAL_ERROR = 3,
+  DisableHWComponentResponse_Reason_DEVICE_UNREACHABLE = 4,
+  DisableHWComponentResponse_Reason_DISABLE_UNSUPPORTED = 5,
+  DisableHWComponentResponse_Reason_INVALID_PARAMS = 6,
+  DisableHWComponentResponse_Reason_DisableHWComponentResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  DisableHWComponentResponse_Reason_DisableHWComponentResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool DisableHWComponentResponse_Reason_IsValid(int value);
+const DisableHWComponentResponse_Reason DisableHWComponentResponse_Reason_Reason_MIN = DisableHWComponentResponse_Reason_UNDEFINED_REASON;
+const DisableHWComponentResponse_Reason DisableHWComponentResponse_Reason_Reason_MAX = DisableHWComponentResponse_Reason_INVALID_PARAMS;
+const int DisableHWComponentResponse_Reason_Reason_ARRAYSIZE = DisableHWComponentResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* DisableHWComponentResponse_Reason_descriptor();
+inline const ::std::string& DisableHWComponentResponse_Reason_Name(DisableHWComponentResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    DisableHWComponentResponse_Reason_descriptor(), value);
+}
+inline bool DisableHWComponentResponse_Reason_Parse(
+    const ::std::string& name, DisableHWComponentResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<DisableHWComponentResponse_Reason>(
+    DisableHWComponentResponse_Reason_descriptor(), name, value);
+}
+enum ResetHWComponentResponse_Reason {
+  ResetHWComponentResponse_Reason_UNDEFINED_REASON = 0,
+  ResetHWComponentResponse_Reason_UNKNOWN_DEVICE = 1,
+  ResetHWComponentResponse_Reason_UNKNOWN_COMPONENT = 2,
+  ResetHWComponentResponse_Reason_INTERNAL_ERROR = 3,
+  ResetHWComponentResponse_Reason_DEVICE_UNREACHABLE = 4,
+  ResetHWComponentResponse_Reason_RESET_UNSUPPORTED = 5,
+  ResetHWComponentResponse_Reason_INVALID_PARAMS = 6,
+  ResetHWComponentResponse_Reason_ResetHWComponentResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  ResetHWComponentResponse_Reason_ResetHWComponentResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool ResetHWComponentResponse_Reason_IsValid(int value);
+const ResetHWComponentResponse_Reason ResetHWComponentResponse_Reason_Reason_MIN = ResetHWComponentResponse_Reason_UNDEFINED_REASON;
+const ResetHWComponentResponse_Reason ResetHWComponentResponse_Reason_Reason_MAX = ResetHWComponentResponse_Reason_INVALID_PARAMS;
+const int ResetHWComponentResponse_Reason_Reason_ARRAYSIZE = ResetHWComponentResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* ResetHWComponentResponse_Reason_descriptor();
+inline const ::std::string& ResetHWComponentResponse_Reason_Name(ResetHWComponentResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    ResetHWComponentResponse_Reason_descriptor(), value);
+}
+inline bool ResetHWComponentResponse_Reason_Parse(
+    const ::std::string& name, ResetHWComponentResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<ResetHWComponentResponse_Reason>(
+    ResetHWComponentResponse_Reason_descriptor(), name, value);
+}
+enum EnableHWComponentResponse_Reason {
+  EnableHWComponentResponse_Reason_UNDEFINED_REASON = 0,
+  EnableHWComponentResponse_Reason_UNKNOWN_DEVICE = 1,
+  EnableHWComponentResponse_Reason_UNKNOWN_COMPONENT = 2,
+  EnableHWComponentResponse_Reason_INTERNAL_ERROR = 3,
+  EnableHWComponentResponse_Reason_DEVICE_UNREACHABLE = 4,
+  EnableHWComponentResponse_Reason_ENABLE_UNSUPPORTED = 5,
+  EnableHWComponentResponse_Reason_INVALID_PARAMS = 6,
+  EnableHWComponentResponse_Reason_EnableHWComponentResponse_Reason_INT_MIN_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::min(),
+  EnableHWComponentResponse_Reason_EnableHWComponentResponse_Reason_INT_MAX_SENTINEL_DO_NOT_USE_ = std::numeric_limits<::google::protobuf::int32>::max()
+};
+bool EnableHWComponentResponse_Reason_IsValid(int value);
+const EnableHWComponentResponse_Reason EnableHWComponentResponse_Reason_Reason_MIN = EnableHWComponentResponse_Reason_UNDEFINED_REASON;
+const EnableHWComponentResponse_Reason EnableHWComponentResponse_Reason_Reason_MAX = EnableHWComponentResponse_Reason_INVALID_PARAMS;
+const int EnableHWComponentResponse_Reason_Reason_ARRAYSIZE = EnableHWComponentResponse_Reason_Reason_MAX + 1;
+
+const ::google::protobuf::EnumDescriptor* EnableHWComponentResponse_Reason_descriptor();
+inline const ::std::string& EnableHWComponentResponse_Reason_Name(EnableHWComponentResponse_Reason value) {
+  return ::google::protobuf::internal::NameOfEnum(
+    EnableHWComponentResponse_Reason_descriptor(), value);
+}
+inline bool EnableHWComponentResponse_Reason_Parse(
+    const ::std::string& name, EnableHWComponentResponse_Reason* value) {
+  return ::google::protobuf::internal::ParseNamedEnum<EnableHWComponentResponse_Reason>(
+    EnableHWComponentResponse_Reason_descriptor(), name, value);
+}
 // ===================================================================
 
 class PhysicalInventoryRequest final :
@@ -4800,6 +4902,936 @@
   mutable ::google::protobuf::internal::CachedSize _cached_size_;
   friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
 };
+// -------------------------------------------------------------------
+
+class DisableHWComponentRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.DisableHWComponentRequest) */ {
+ public:
+  DisableHWComponentRequest();
+  virtual ~DisableHWComponentRequest();
+
+  DisableHWComponentRequest(const DisableHWComponentRequest& from);
+
+  inline DisableHWComponentRequest& operator=(const DisableHWComponentRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  DisableHWComponentRequest(DisableHWComponentRequest&& from) noexcept
+    : DisableHWComponentRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline DisableHWComponentRequest& operator=(DisableHWComponentRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const DisableHWComponentRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const DisableHWComponentRequest* internal_default_instance() {
+    return reinterpret_cast<const DisableHWComponentRequest*>(
+               &_DisableHWComponentRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    29;
+
+  void Swap(DisableHWComponentRequest* other);
+  friend void swap(DisableHWComponentRequest& a, DisableHWComponentRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline DisableHWComponentRequest* New() const final {
+    return CreateMaybeMessage<DisableHWComponentRequest>(nullptr);
+  }
+
+  DisableHWComponentRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<DisableHWComponentRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const DisableHWComponentRequest& from);
+  void MergeFrom(const DisableHWComponentRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(DisableHWComponentRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.DisableHWComponentRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class DisableHWComponentResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.DisableHWComponentResponse) */ {
+ public:
+  DisableHWComponentResponse();
+  virtual ~DisableHWComponentResponse();
+
+  DisableHWComponentResponse(const DisableHWComponentResponse& from);
+
+  inline DisableHWComponentResponse& operator=(const DisableHWComponentResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  DisableHWComponentResponse(DisableHWComponentResponse&& from) noexcept
+    : DisableHWComponentResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline DisableHWComponentResponse& operator=(DisableHWComponentResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const DisableHWComponentResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const DisableHWComponentResponse* internal_default_instance() {
+    return reinterpret_cast<const DisableHWComponentResponse*>(
+               &_DisableHWComponentResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    30;
+
+  void Swap(DisableHWComponentResponse* other);
+  friend void swap(DisableHWComponentResponse& a, DisableHWComponentResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline DisableHWComponentResponse* New() const final {
+    return CreateMaybeMessage<DisableHWComponentResponse>(nullptr);
+  }
+
+  DisableHWComponentResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<DisableHWComponentResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const DisableHWComponentResponse& from);
+  void MergeFrom(const DisableHWComponentResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(DisableHWComponentResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef DisableHWComponentResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    DisableHWComponentResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    DisableHWComponentResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    DisableHWComponentResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INTERNAL_ERROR =
+    DisableHWComponentResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    DisableHWComponentResponse_Reason_DEVICE_UNREACHABLE;
+  static const Reason DISABLE_UNSUPPORTED =
+    DisableHWComponentResponse_Reason_DISABLE_UNSUPPORTED;
+  static const Reason INVALID_PARAMS =
+    DisableHWComponentResponse_Reason_INVALID_PARAMS;
+  static inline bool Reason_IsValid(int value) {
+    return DisableHWComponentResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    DisableHWComponentResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    DisableHWComponentResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    DisableHWComponentResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return DisableHWComponentResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return DisableHWComponentResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return DisableHWComponentResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.DisableHWComponentResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::DisableHWComponentResponse_Reason reason() const;
+  void set_reason(::dmi::DisableHWComponentResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.DisableHWComponentResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ResetHWComponentRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ResetHWComponentRequest) */ {
+ public:
+  ResetHWComponentRequest();
+  virtual ~ResetHWComponentRequest();
+
+  ResetHWComponentRequest(const ResetHWComponentRequest& from);
+
+  inline ResetHWComponentRequest& operator=(const ResetHWComponentRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ResetHWComponentRequest(ResetHWComponentRequest&& from) noexcept
+    : ResetHWComponentRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline ResetHWComponentRequest& operator=(ResetHWComponentRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ResetHWComponentRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ResetHWComponentRequest* internal_default_instance() {
+    return reinterpret_cast<const ResetHWComponentRequest*>(
+               &_ResetHWComponentRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    31;
+
+  void Swap(ResetHWComponentRequest* other);
+  friend void swap(ResetHWComponentRequest& a, ResetHWComponentRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ResetHWComponentRequest* New() const final {
+    return CreateMaybeMessage<ResetHWComponentRequest>(nullptr);
+  }
+
+  ResetHWComponentRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ResetHWComponentRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ResetHWComponentRequest& from);
+  void MergeFrom(const ResetHWComponentRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ResetHWComponentRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.ResetHWComponentRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class ResetHWComponentResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.ResetHWComponentResponse) */ {
+ public:
+  ResetHWComponentResponse();
+  virtual ~ResetHWComponentResponse();
+
+  ResetHWComponentResponse(const ResetHWComponentResponse& from);
+
+  inline ResetHWComponentResponse& operator=(const ResetHWComponentResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  ResetHWComponentResponse(ResetHWComponentResponse&& from) noexcept
+    : ResetHWComponentResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline ResetHWComponentResponse& operator=(ResetHWComponentResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const ResetHWComponentResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const ResetHWComponentResponse* internal_default_instance() {
+    return reinterpret_cast<const ResetHWComponentResponse*>(
+               &_ResetHWComponentResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    32;
+
+  void Swap(ResetHWComponentResponse* other);
+  friend void swap(ResetHWComponentResponse& a, ResetHWComponentResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline ResetHWComponentResponse* New() const final {
+    return CreateMaybeMessage<ResetHWComponentResponse>(nullptr);
+  }
+
+  ResetHWComponentResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<ResetHWComponentResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const ResetHWComponentResponse& from);
+  void MergeFrom(const ResetHWComponentResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(ResetHWComponentResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef ResetHWComponentResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    ResetHWComponentResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    ResetHWComponentResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    ResetHWComponentResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INTERNAL_ERROR =
+    ResetHWComponentResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    ResetHWComponentResponse_Reason_DEVICE_UNREACHABLE;
+  static const Reason RESET_UNSUPPORTED =
+    ResetHWComponentResponse_Reason_RESET_UNSUPPORTED;
+  static const Reason INVALID_PARAMS =
+    ResetHWComponentResponse_Reason_INVALID_PARAMS;
+  static inline bool Reason_IsValid(int value) {
+    return ResetHWComponentResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    ResetHWComponentResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    ResetHWComponentResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    ResetHWComponentResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return ResetHWComponentResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return ResetHWComponentResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return ResetHWComponentResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.ResetHWComponentResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::ResetHWComponentResponse_Reason reason() const;
+  void set_reason(::dmi::ResetHWComponentResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.ResetHWComponentResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EnableHWComponentRequest final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EnableHWComponentRequest) */ {
+ public:
+  EnableHWComponentRequest();
+  virtual ~EnableHWComponentRequest();
+
+  EnableHWComponentRequest(const EnableHWComponentRequest& from);
+
+  inline EnableHWComponentRequest& operator=(const EnableHWComponentRequest& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EnableHWComponentRequest(EnableHWComponentRequest&& from) noexcept
+    : EnableHWComponentRequest() {
+    *this = ::std::move(from);
+  }
+
+  inline EnableHWComponentRequest& operator=(EnableHWComponentRequest&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EnableHWComponentRequest& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EnableHWComponentRequest* internal_default_instance() {
+    return reinterpret_cast<const EnableHWComponentRequest*>(
+               &_EnableHWComponentRequest_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    33;
+
+  void Swap(EnableHWComponentRequest* other);
+  friend void swap(EnableHWComponentRequest& a, EnableHWComponentRequest& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EnableHWComponentRequest* New() const final {
+    return CreateMaybeMessage<EnableHWComponentRequest>(nullptr);
+  }
+
+  EnableHWComponentRequest* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EnableHWComponentRequest>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EnableHWComponentRequest& from);
+  void MergeFrom(const EnableHWComponentRequest& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EnableHWComponentRequest* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  // accessors -------------------------------------------------------
+
+  // string component_name = 3;
+  void clear_component_name();
+  static const int kComponentNameFieldNumber = 3;
+  const ::std::string& component_name() const;
+  void set_component_name(const ::std::string& value);
+  #if LANG_CXX11
+  void set_component_name(::std::string&& value);
+  #endif
+  void set_component_name(const char* value);
+  void set_component_name(const char* value, size_t size);
+  ::std::string* mutable_component_name();
+  ::std::string* release_component_name();
+  void set_allocated_component_name(::std::string* component_name);
+
+  // .dmi.Uuid device_uuid = 1;
+  bool has_device_uuid() const;
+  void clear_device_uuid();
+  static const int kDeviceUuidFieldNumber = 1;
+  const ::dmi::Uuid& device_uuid() const;
+  ::dmi::Uuid* release_device_uuid();
+  ::dmi::Uuid* mutable_device_uuid();
+  void set_allocated_device_uuid(::dmi::Uuid* device_uuid);
+
+  // .dmi.Uuid component_uuid = 2;
+  bool has_component_uuid() const;
+  void clear_component_uuid();
+  static const int kComponentUuidFieldNumber = 2;
+  const ::dmi::Uuid& component_uuid() const;
+  ::dmi::Uuid* release_component_uuid();
+  ::dmi::Uuid* mutable_component_uuid();
+  void set_allocated_component_uuid(::dmi::Uuid* component_uuid);
+
+  // @@protoc_insertion_point(class_scope:dmi.EnableHWComponentRequest)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr component_name_;
+  ::dmi::Uuid* device_uuid_;
+  ::dmi::Uuid* component_uuid_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
+// -------------------------------------------------------------------
+
+class EnableHWComponentResponse final :
+    public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:dmi.EnableHWComponentResponse) */ {
+ public:
+  EnableHWComponentResponse();
+  virtual ~EnableHWComponentResponse();
+
+  EnableHWComponentResponse(const EnableHWComponentResponse& from);
+
+  inline EnableHWComponentResponse& operator=(const EnableHWComponentResponse& from) {
+    CopyFrom(from);
+    return *this;
+  }
+  #if LANG_CXX11
+  EnableHWComponentResponse(EnableHWComponentResponse&& from) noexcept
+    : EnableHWComponentResponse() {
+    *this = ::std::move(from);
+  }
+
+  inline EnableHWComponentResponse& operator=(EnableHWComponentResponse&& from) noexcept {
+    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
+      if (this != &from) InternalSwap(&from);
+    } else {
+      CopyFrom(from);
+    }
+    return *this;
+  }
+  #endif
+  static const ::google::protobuf::Descriptor* descriptor() {
+    return default_instance().GetDescriptor();
+  }
+  static const EnableHWComponentResponse& default_instance();
+
+  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
+  static inline const EnableHWComponentResponse* internal_default_instance() {
+    return reinterpret_cast<const EnableHWComponentResponse*>(
+               &_EnableHWComponentResponse_default_instance_);
+  }
+  static constexpr int kIndexInFileMessages =
+    34;
+
+  void Swap(EnableHWComponentResponse* other);
+  friend void swap(EnableHWComponentResponse& a, EnableHWComponentResponse& b) {
+    a.Swap(&b);
+  }
+
+  // implements Message ----------------------------------------------
+
+  inline EnableHWComponentResponse* New() const final {
+    return CreateMaybeMessage<EnableHWComponentResponse>(nullptr);
+  }
+
+  EnableHWComponentResponse* New(::google::protobuf::Arena* arena) const final {
+    return CreateMaybeMessage<EnableHWComponentResponse>(arena);
+  }
+  void CopyFrom(const ::google::protobuf::Message& from) final;
+  void MergeFrom(const ::google::protobuf::Message& from) final;
+  void CopyFrom(const EnableHWComponentResponse& from);
+  void MergeFrom(const EnableHWComponentResponse& from);
+  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
+  bool IsInitialized() const final;
+
+  size_t ByteSizeLong() const final;
+  #if GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  static const char* _InternalParse(const char* begin, const char* end, void* object, ::google::protobuf::internal::ParseContext* ctx);
+  ::google::protobuf::internal::ParseFunc _ParseFunc() const final { return _InternalParse; }
+  #else
+  bool MergePartialFromCodedStream(
+      ::google::protobuf::io::CodedInputStream* input) final;
+  #endif  // GOOGLE_PROTOBUF_ENABLE_EXPERIMENTAL_PARSER
+  void SerializeWithCachedSizes(
+      ::google::protobuf::io::CodedOutputStream* output) const final;
+  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
+      ::google::protobuf::uint8* target) const final;
+  int GetCachedSize() const final { return _cached_size_.Get(); }
+
+  private:
+  void SharedCtor();
+  void SharedDtor();
+  void SetCachedSize(int size) const final;
+  void InternalSwap(EnableHWComponentResponse* other);
+  private:
+  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
+    return nullptr;
+  }
+  inline void* MaybeArenaPtr() const {
+    return nullptr;
+  }
+  public:
+
+  ::google::protobuf::Metadata GetMetadata() const final;
+
+  // nested types ----------------------------------------------------
+
+  typedef EnableHWComponentResponse_Reason Reason;
+  static const Reason UNDEFINED_REASON =
+    EnableHWComponentResponse_Reason_UNDEFINED_REASON;
+  static const Reason UNKNOWN_DEVICE =
+    EnableHWComponentResponse_Reason_UNKNOWN_DEVICE;
+  static const Reason UNKNOWN_COMPONENT =
+    EnableHWComponentResponse_Reason_UNKNOWN_COMPONENT;
+  static const Reason INTERNAL_ERROR =
+    EnableHWComponentResponse_Reason_INTERNAL_ERROR;
+  static const Reason DEVICE_UNREACHABLE =
+    EnableHWComponentResponse_Reason_DEVICE_UNREACHABLE;
+  static const Reason ENABLE_UNSUPPORTED =
+    EnableHWComponentResponse_Reason_ENABLE_UNSUPPORTED;
+  static const Reason INVALID_PARAMS =
+    EnableHWComponentResponse_Reason_INVALID_PARAMS;
+  static inline bool Reason_IsValid(int value) {
+    return EnableHWComponentResponse_Reason_IsValid(value);
+  }
+  static const Reason Reason_MIN =
+    EnableHWComponentResponse_Reason_Reason_MIN;
+  static const Reason Reason_MAX =
+    EnableHWComponentResponse_Reason_Reason_MAX;
+  static const int Reason_ARRAYSIZE =
+    EnableHWComponentResponse_Reason_Reason_ARRAYSIZE;
+  static inline const ::google::protobuf::EnumDescriptor*
+  Reason_descriptor() {
+    return EnableHWComponentResponse_Reason_descriptor();
+  }
+  static inline const ::std::string& Reason_Name(Reason value) {
+    return EnableHWComponentResponse_Reason_Name(value);
+  }
+  static inline bool Reason_Parse(const ::std::string& name,
+      Reason* value) {
+    return EnableHWComponentResponse_Reason_Parse(name, value);
+  }
+
+  // accessors -------------------------------------------------------
+
+  // string reason_detail = 3;
+  void clear_reason_detail();
+  static const int kReasonDetailFieldNumber = 3;
+  const ::std::string& reason_detail() const;
+  void set_reason_detail(const ::std::string& value);
+  #if LANG_CXX11
+  void set_reason_detail(::std::string&& value);
+  #endif
+  void set_reason_detail(const char* value);
+  void set_reason_detail(const char* value, size_t size);
+  ::std::string* mutable_reason_detail();
+  ::std::string* release_reason_detail();
+  void set_allocated_reason_detail(::std::string* reason_detail);
+
+  // .dmi.Status status = 1;
+  void clear_status();
+  static const int kStatusFieldNumber = 1;
+  ::dmi::Status status() const;
+  void set_status(::dmi::Status value);
+
+  // .dmi.EnableHWComponentResponse.Reason reason = 2;
+  void clear_reason();
+  static const int kReasonFieldNumber = 2;
+  ::dmi::EnableHWComponentResponse_Reason reason() const;
+  void set_reason(::dmi::EnableHWComponentResponse_Reason value);
+
+  // @@protoc_insertion_point(class_scope:dmi.EnableHWComponentResponse)
+ private:
+  class HasBitSetters;
+
+  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
+  ::google::protobuf::internal::ArenaStringPtr reason_detail_;
+  int status_;
+  int reason_;
+  mutable ::google::protobuf::internal::CachedSize _cached_size_;
+  friend struct ::TableStruct_dmi_2fhw_5fmanagement_5fservice_2eproto;
+};
 // ===================================================================
 
 
@@ -7575,6 +8607,702 @@
   // @@protoc_insertion_point(field_set_allocated:dmi.RebootDeviceResponse.reason_detail)
 }
 
+// -------------------------------------------------------------------
+
+// DisableHWComponentRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool DisableHWComponentRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& DisableHWComponentRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* DisableHWComponentRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.DisableHWComponentRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* DisableHWComponentRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.DisableHWComponentRequest.device_uuid)
+  return device_uuid_;
+}
+inline void DisableHWComponentRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
+  }
+  if (device_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, device_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  device_uuid_ = device_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.DisableHWComponentRequest.device_uuid)
+}
+
+// .dmi.Uuid component_uuid = 2;
+inline bool DisableHWComponentRequest::has_component_uuid() const {
+  return this != internal_default_instance() && component_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& DisableHWComponentRequest::component_uuid() const {
+  const ::dmi::Uuid* p = component_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentRequest.component_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* DisableHWComponentRequest::release_component_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.DisableHWComponentRequest.component_uuid)
+  
+  ::dmi::Uuid* temp = component_uuid_;
+  component_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* DisableHWComponentRequest::mutable_component_uuid() {
+  
+  if (component_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    component_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.DisableHWComponentRequest.component_uuid)
+  return component_uuid_;
+}
+inline void DisableHWComponentRequest::set_allocated_component_uuid(::dmi::Uuid* component_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_uuid_);
+  }
+  if (component_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      component_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, component_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  component_uuid_ = component_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.DisableHWComponentRequest.component_uuid)
+}
+
+// string component_name = 3;
+inline void DisableHWComponentRequest::clear_component_name() {
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& DisableHWComponentRequest::component_name() const {
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentRequest.component_name)
+  return component_name_.GetNoArena();
+}
+inline void DisableHWComponentRequest::set_component_name(const ::std::string& value) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.DisableHWComponentRequest.component_name)
+}
+#if LANG_CXX11
+inline void DisableHWComponentRequest::set_component_name(::std::string&& value) {
+  
+  component_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.DisableHWComponentRequest.component_name)
+}
+#endif
+inline void DisableHWComponentRequest::set_component_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.DisableHWComponentRequest.component_name)
+}
+inline void DisableHWComponentRequest::set_component_name(const char* value, size_t size) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.DisableHWComponentRequest.component_name)
+}
+inline ::std::string* DisableHWComponentRequest::mutable_component_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.DisableHWComponentRequest.component_name)
+  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* DisableHWComponentRequest::release_component_name() {
+  // @@protoc_insertion_point(field_release:dmi.DisableHWComponentRequest.component_name)
+  
+  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void DisableHWComponentRequest::set_allocated_component_name(::std::string* component_name) {
+  if (component_name != nullptr) {
+    
+  } else {
+    
+  }
+  component_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), component_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.DisableHWComponentRequest.component_name)
+}
+
+// -------------------------------------------------------------------
+
+// DisableHWComponentResponse
+
+// .dmi.Status status = 1;
+inline void DisableHWComponentResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status DisableHWComponentResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void DisableHWComponentResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.DisableHWComponentResponse.status)
+}
+
+// .dmi.DisableHWComponentResponse.Reason reason = 2;
+inline void DisableHWComponentResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::DisableHWComponentResponse_Reason DisableHWComponentResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentResponse.reason)
+  return static_cast< ::dmi::DisableHWComponentResponse_Reason >(reason_);
+}
+inline void DisableHWComponentResponse::set_reason(::dmi::DisableHWComponentResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.DisableHWComponentResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void DisableHWComponentResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& DisableHWComponentResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.DisableHWComponentResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void DisableHWComponentResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.DisableHWComponentResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void DisableHWComponentResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.DisableHWComponentResponse.reason_detail)
+}
+#endif
+inline void DisableHWComponentResponse::set_reason_detail(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.DisableHWComponentResponse.reason_detail)
+}
+inline void DisableHWComponentResponse::set_reason_detail(const char* value, size_t size) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.DisableHWComponentResponse.reason_detail)
+}
+inline ::std::string* DisableHWComponentResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.DisableHWComponentResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* DisableHWComponentResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.DisableHWComponentResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void DisableHWComponentResponse::set_allocated_reason_detail(::std::string* reason_detail) {
+  if (reason_detail != nullptr) {
+    
+  } else {
+    
+  }
+  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
+  // @@protoc_insertion_point(field_set_allocated:dmi.DisableHWComponentResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// ResetHWComponentRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool ResetHWComponentRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& ResetHWComponentRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* ResetHWComponentRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.ResetHWComponentRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* ResetHWComponentRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ResetHWComponentRequest.device_uuid)
+  return device_uuid_;
+}
+inline void ResetHWComponentRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
+  }
+  if (device_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, device_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  device_uuid_ = device_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ResetHWComponentRequest.device_uuid)
+}
+
+// .dmi.Uuid component_uuid = 2;
+inline bool ResetHWComponentRequest::has_component_uuid() const {
+  return this != internal_default_instance() && component_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& ResetHWComponentRequest::component_uuid() const {
+  const ::dmi::Uuid* p = component_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentRequest.component_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* ResetHWComponentRequest::release_component_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.ResetHWComponentRequest.component_uuid)
+  
+  ::dmi::Uuid* temp = component_uuid_;
+  component_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* ResetHWComponentRequest::mutable_component_uuid() {
+  
+  if (component_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    component_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.ResetHWComponentRequest.component_uuid)
+  return component_uuid_;
+}
+inline void ResetHWComponentRequest::set_allocated_component_uuid(::dmi::Uuid* component_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_uuid_);
+  }
+  if (component_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      component_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, component_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  component_uuid_ = component_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.ResetHWComponentRequest.component_uuid)
+}
+
+// string component_name = 3;
+inline void ResetHWComponentRequest::clear_component_name() {
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ResetHWComponentRequest::component_name() const {
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentRequest.component_name)
+  return component_name_.GetNoArena();
+}
+inline void ResetHWComponentRequest::set_component_name(const ::std::string& value) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ResetHWComponentRequest.component_name)
+}
+#if LANG_CXX11
+inline void ResetHWComponentRequest::set_component_name(::std::string&& value) {
+  
+  component_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ResetHWComponentRequest.component_name)
+}
+#endif
+inline void ResetHWComponentRequest::set_component_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ResetHWComponentRequest.component_name)
+}
+inline void ResetHWComponentRequest::set_component_name(const char* value, size_t size) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ResetHWComponentRequest.component_name)
+}
+inline ::std::string* ResetHWComponentRequest::mutable_component_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ResetHWComponentRequest.component_name)
+  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ResetHWComponentRequest::release_component_name() {
+  // @@protoc_insertion_point(field_release:dmi.ResetHWComponentRequest.component_name)
+  
+  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ResetHWComponentRequest::set_allocated_component_name(::std::string* component_name) {
+  if (component_name != nullptr) {
+    
+  } else {
+    
+  }
+  component_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), component_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ResetHWComponentRequest.component_name)
+}
+
+// -------------------------------------------------------------------
+
+// ResetHWComponentResponse
+
+// .dmi.Status status = 1;
+inline void ResetHWComponentResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status ResetHWComponentResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void ResetHWComponentResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ResetHWComponentResponse.status)
+}
+
+// .dmi.ResetHWComponentResponse.Reason reason = 2;
+inline void ResetHWComponentResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::ResetHWComponentResponse_Reason ResetHWComponentResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentResponse.reason)
+  return static_cast< ::dmi::ResetHWComponentResponse_Reason >(reason_);
+}
+inline void ResetHWComponentResponse::set_reason(::dmi::ResetHWComponentResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.ResetHWComponentResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void ResetHWComponentResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& ResetHWComponentResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.ResetHWComponentResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void ResetHWComponentResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.ResetHWComponentResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void ResetHWComponentResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.ResetHWComponentResponse.reason_detail)
+}
+#endif
+inline void ResetHWComponentResponse::set_reason_detail(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.ResetHWComponentResponse.reason_detail)
+}
+inline void ResetHWComponentResponse::set_reason_detail(const char* value, size_t size) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.ResetHWComponentResponse.reason_detail)
+}
+inline ::std::string* ResetHWComponentResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.ResetHWComponentResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* ResetHWComponentResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.ResetHWComponentResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void ResetHWComponentResponse::set_allocated_reason_detail(::std::string* reason_detail) {
+  if (reason_detail != nullptr) {
+    
+  } else {
+    
+  }
+  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
+  // @@protoc_insertion_point(field_set_allocated:dmi.ResetHWComponentResponse.reason_detail)
+}
+
+// -------------------------------------------------------------------
+
+// EnableHWComponentRequest
+
+// .dmi.Uuid device_uuid = 1;
+inline bool EnableHWComponentRequest::has_device_uuid() const {
+  return this != internal_default_instance() && device_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& EnableHWComponentRequest::device_uuid() const {
+  const ::dmi::Uuid* p = device_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentRequest.device_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* EnableHWComponentRequest::release_device_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.EnableHWComponentRequest.device_uuid)
+  
+  ::dmi::Uuid* temp = device_uuid_;
+  device_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* EnableHWComponentRequest::mutable_device_uuid() {
+  
+  if (device_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    device_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EnableHWComponentRequest.device_uuid)
+  return device_uuid_;
+}
+inline void EnableHWComponentRequest::set_allocated_device_uuid(::dmi::Uuid* device_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(device_uuid_);
+  }
+  if (device_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      device_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, device_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  device_uuid_ = device_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EnableHWComponentRequest.device_uuid)
+}
+
+// .dmi.Uuid component_uuid = 2;
+inline bool EnableHWComponentRequest::has_component_uuid() const {
+  return this != internal_default_instance() && component_uuid_ != nullptr;
+}
+inline const ::dmi::Uuid& EnableHWComponentRequest::component_uuid() const {
+  const ::dmi::Uuid* p = component_uuid_;
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentRequest.component_uuid)
+  return p != nullptr ? *p : *reinterpret_cast<const ::dmi::Uuid*>(
+      &::dmi::_Uuid_default_instance_);
+}
+inline ::dmi::Uuid* EnableHWComponentRequest::release_component_uuid() {
+  // @@protoc_insertion_point(field_release:dmi.EnableHWComponentRequest.component_uuid)
+  
+  ::dmi::Uuid* temp = component_uuid_;
+  component_uuid_ = nullptr;
+  return temp;
+}
+inline ::dmi::Uuid* EnableHWComponentRequest::mutable_component_uuid() {
+  
+  if (component_uuid_ == nullptr) {
+    auto* p = CreateMaybeMessage<::dmi::Uuid>(GetArenaNoVirtual());
+    component_uuid_ = p;
+  }
+  // @@protoc_insertion_point(field_mutable:dmi.EnableHWComponentRequest.component_uuid)
+  return component_uuid_;
+}
+inline void EnableHWComponentRequest::set_allocated_component_uuid(::dmi::Uuid* component_uuid) {
+  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
+  if (message_arena == nullptr) {
+    delete reinterpret_cast< ::google::protobuf::MessageLite*>(component_uuid_);
+  }
+  if (component_uuid) {
+    ::google::protobuf::Arena* submessage_arena = nullptr;
+    if (message_arena != submessage_arena) {
+      component_uuid = ::google::protobuf::internal::GetOwnedMessage(
+          message_arena, component_uuid, submessage_arena);
+    }
+    
+  } else {
+    
+  }
+  component_uuid_ = component_uuid;
+  // @@protoc_insertion_point(field_set_allocated:dmi.EnableHWComponentRequest.component_uuid)
+}
+
+// string component_name = 3;
+inline void EnableHWComponentRequest::clear_component_name() {
+  component_name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& EnableHWComponentRequest::component_name() const {
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentRequest.component_name)
+  return component_name_.GetNoArena();
+}
+inline void EnableHWComponentRequest::set_component_name(const ::std::string& value) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.EnableHWComponentRequest.component_name)
+}
+#if LANG_CXX11
+inline void EnableHWComponentRequest::set_component_name(::std::string&& value) {
+  
+  component_name_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.EnableHWComponentRequest.component_name)
+}
+#endif
+inline void EnableHWComponentRequest::set_component_name(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.EnableHWComponentRequest.component_name)
+}
+inline void EnableHWComponentRequest::set_component_name(const char* value, size_t size) {
+  
+  component_name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.EnableHWComponentRequest.component_name)
+}
+inline ::std::string* EnableHWComponentRequest::mutable_component_name() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.EnableHWComponentRequest.component_name)
+  return component_name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* EnableHWComponentRequest::release_component_name() {
+  // @@protoc_insertion_point(field_release:dmi.EnableHWComponentRequest.component_name)
+  
+  return component_name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void EnableHWComponentRequest::set_allocated_component_name(::std::string* component_name) {
+  if (component_name != nullptr) {
+    
+  } else {
+    
+  }
+  component_name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), component_name);
+  // @@protoc_insertion_point(field_set_allocated:dmi.EnableHWComponentRequest.component_name)
+}
+
+// -------------------------------------------------------------------
+
+// EnableHWComponentResponse
+
+// .dmi.Status status = 1;
+inline void EnableHWComponentResponse::clear_status() {
+  status_ = 0;
+}
+inline ::dmi::Status EnableHWComponentResponse::status() const {
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentResponse.status)
+  return static_cast< ::dmi::Status >(status_);
+}
+inline void EnableHWComponentResponse::set_status(::dmi::Status value) {
+  
+  status_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EnableHWComponentResponse.status)
+}
+
+// .dmi.EnableHWComponentResponse.Reason reason = 2;
+inline void EnableHWComponentResponse::clear_reason() {
+  reason_ = 0;
+}
+inline ::dmi::EnableHWComponentResponse_Reason EnableHWComponentResponse::reason() const {
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentResponse.reason)
+  return static_cast< ::dmi::EnableHWComponentResponse_Reason >(reason_);
+}
+inline void EnableHWComponentResponse::set_reason(::dmi::EnableHWComponentResponse_Reason value) {
+  
+  reason_ = value;
+  // @@protoc_insertion_point(field_set:dmi.EnableHWComponentResponse.reason)
+}
+
+// string reason_detail = 3;
+inline void EnableHWComponentResponse::clear_reason_detail() {
+  reason_detail_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline const ::std::string& EnableHWComponentResponse::reason_detail() const {
+  // @@protoc_insertion_point(field_get:dmi.EnableHWComponentResponse.reason_detail)
+  return reason_detail_.GetNoArena();
+}
+inline void EnableHWComponentResponse::set_reason_detail(const ::std::string& value) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
+  // @@protoc_insertion_point(field_set:dmi.EnableHWComponentResponse.reason_detail)
+}
+#if LANG_CXX11
+inline void EnableHWComponentResponse::set_reason_detail(::std::string&& value) {
+  
+  reason_detail_.SetNoArena(
+    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
+  // @@protoc_insertion_point(field_set_rvalue:dmi.EnableHWComponentResponse.reason_detail)
+}
+#endif
+inline void EnableHWComponentResponse::set_reason_detail(const char* value) {
+  GOOGLE_DCHECK(value != nullptr);
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
+  // @@protoc_insertion_point(field_set_char:dmi.EnableHWComponentResponse.reason_detail)
+}
+inline void EnableHWComponentResponse::set_reason_detail(const char* value, size_t size) {
+  
+  reason_detail_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
+      ::std::string(reinterpret_cast<const char*>(value), size));
+  // @@protoc_insertion_point(field_set_pointer:dmi.EnableHWComponentResponse.reason_detail)
+}
+inline ::std::string* EnableHWComponentResponse::mutable_reason_detail() {
+  
+  // @@protoc_insertion_point(field_mutable:dmi.EnableHWComponentResponse.reason_detail)
+  return reason_detail_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline ::std::string* EnableHWComponentResponse::release_reason_detail() {
+  // @@protoc_insertion_point(field_release:dmi.EnableHWComponentResponse.reason_detail)
+  
+  return reason_detail_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
+}
+inline void EnableHWComponentResponse::set_allocated_reason_detail(::std::string* reason_detail) {
+  if (reason_detail != nullptr) {
+    
+  } else {
+    
+  }
+  reason_detail_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), reason_detail);
+  // @@protoc_insertion_point(field_set_allocated:dmi.EnableHWComponentResponse.reason_detail)
+}
+
 #ifdef __GNUC__
   #pragma GCC diagnostic pop
 #endif  // __GNUC__
@@ -7634,6 +9362,18 @@
 
 // -------------------------------------------------------------------
 
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
+// -------------------------------------------------------------------
+
 
 // @@protoc_insertion_point(namespace_scope)
 
@@ -7712,6 +9452,21 @@
 inline const EnumDescriptor* GetEnumDescriptor< ::dmi::RebootDeviceResponse_Reason>() {
   return ::dmi::RebootDeviceResponse_Reason_descriptor();
 }
+template <> struct is_proto_enum< ::dmi::DisableHWComponentResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::DisableHWComponentResponse_Reason>() {
+  return ::dmi::DisableHWComponentResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::ResetHWComponentResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::ResetHWComponentResponse_Reason>() {
+  return ::dmi::ResetHWComponentResponse_Reason_descriptor();
+}
+template <> struct is_proto_enum< ::dmi::EnableHWComponentResponse_Reason> : ::std::true_type {};
+template <>
+inline const EnumDescriptor* GetEnumDescriptor< ::dmi::EnableHWComponentResponse_Reason>() {
+  return ::dmi::EnableHWComponentResponse_Reason_descriptor();
+}
 
 }  // namespace protobuf
 }  // namespace google
