// Code generated by protoc-gen-go. DO NOT EDIT.
// source: dmi/hw_metrics_mgmt_service.proto

package dmi

import (
	context "context"
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	empty "github.com/golang/protobuf/ptypes/empty"
	grpc "google.golang.org/grpc"
	codes "google.golang.org/grpc/codes"
	status "google.golang.org/grpc/status"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type MetricNames int32

const (
	MetricNames_METRIC_NAME_UNDEFINED MetricNames = 0
	// FAN related metrics
	MetricNames_METRIC_FAN_SPEED MetricNames = 1
	// CPU related metrics
	MetricNames_METRIC_CPU_TEMP             MetricNames = 100
	MetricNames_METRIC_CPU_USAGE_PERCENTAGE MetricNames = 101
	// Transceiver related metrics
	MetricNames_METRIC_TRANSCEIVER_TEMP            MetricNames = 200
	MetricNames_METRIC_TRANSCEIVER_VOLTAGE         MetricNames = 201
	MetricNames_METRIC_TRANSCEIVER_BIAS            MetricNames = 202
	MetricNames_METRIC_TRANSCEIVER_RX_POWER        MetricNames = 203
	MetricNames_METRIC_TRANSCEIVER_TX_POWER        MetricNames = 204
	MetricNames_METRIC_TRANSCEIVER_WAVELENGTH      MetricNames = 205
	MetricNames_METRIC_TRANSCEIVER_XGSPON_TX_POWER MetricNames = 206
	// Disk related metrics
	MetricNames_METRIC_DISK_TEMP                    MetricNames = 300
	MetricNames_METRIC_DISK_CAPACITY                MetricNames = 301
	MetricNames_METRIC_DISK_USAGE                   MetricNames = 302
	MetricNames_METRIC_DISK_USAGE_PERCENTAGE        MetricNames = 303
	MetricNames_METRIC_DISK_READ_WRITE_PERCENTAGE   MetricNames = 304
	MetricNames_METRIC_DISK_FAULTY_CELLS_PERCENTAGE MetricNames = 305
	// RAM related metrics
	MetricNames_METRIC_RAM_TEMP             MetricNames = 400
	MetricNames_METRIC_RAM_CAPACITY         MetricNames = 401
	MetricNames_METRIC_RAM_USAGE            MetricNames = 402
	MetricNames_METRIC_RAM_USAGE_PERCENTAGE MetricNames = 403
	// Power related metrics
	MetricNames_METRIC_POWER_MAX              MetricNames = 500
	MetricNames_METRIC_POWER_USAGE            MetricNames = 501
	MetricNames_METRIC_POWER_USAGE_PERCENTAGE MetricNames = 502
	// Chassis related metrics
	MetricNames_METRIC_INNER_SURROUNDING_TEMP MetricNames = 600
)

var MetricNames_name = map[int32]string{
	0:   "METRIC_NAME_UNDEFINED",
	1:   "METRIC_FAN_SPEED",
	100: "METRIC_CPU_TEMP",
	101: "METRIC_CPU_USAGE_PERCENTAGE",
	200: "METRIC_TRANSCEIVER_TEMP",
	201: "METRIC_TRANSCEIVER_VOLTAGE",
	202: "METRIC_TRANSCEIVER_BIAS",
	203: "METRIC_TRANSCEIVER_RX_POWER",
	204: "METRIC_TRANSCEIVER_TX_POWER",
	205: "METRIC_TRANSCEIVER_WAVELENGTH",
	206: "METRIC_TRANSCEIVER_XGSPON_TX_POWER",
	300: "METRIC_DISK_TEMP",
	301: "METRIC_DISK_CAPACITY",
	302: "METRIC_DISK_USAGE",
	303: "METRIC_DISK_USAGE_PERCENTAGE",
	304: "METRIC_DISK_READ_WRITE_PERCENTAGE",
	305: "METRIC_DISK_FAULTY_CELLS_PERCENTAGE",
	400: "METRIC_RAM_TEMP",
	401: "METRIC_RAM_CAPACITY",
	402: "METRIC_RAM_USAGE",
	403: "METRIC_RAM_USAGE_PERCENTAGE",
	500: "METRIC_POWER_MAX",
	501: "METRIC_POWER_USAGE",
	502: "METRIC_POWER_USAGE_PERCENTAGE",
	600: "METRIC_INNER_SURROUNDING_TEMP",
}

var MetricNames_value = map[string]int32{
	"METRIC_NAME_UNDEFINED":               0,
	"METRIC_FAN_SPEED":                    1,
	"METRIC_CPU_TEMP":                     100,
	"METRIC_CPU_USAGE_PERCENTAGE":         101,
	"METRIC_TRANSCEIVER_TEMP":             200,
	"METRIC_TRANSCEIVER_VOLTAGE":          201,
	"METRIC_TRANSCEIVER_BIAS":             202,
	"METRIC_TRANSCEIVER_RX_POWER":         203,
	"METRIC_TRANSCEIVER_TX_POWER":         204,
	"METRIC_TRANSCEIVER_WAVELENGTH":       205,
	"METRIC_TRANSCEIVER_XGSPON_TX_POWER":  206,
	"METRIC_DISK_TEMP":                    300,
	"METRIC_DISK_CAPACITY":                301,
	"METRIC_DISK_USAGE":                   302,
	"METRIC_DISK_USAGE_PERCENTAGE":        303,
	"METRIC_DISK_READ_WRITE_PERCENTAGE":   304,
	"METRIC_DISK_FAULTY_CELLS_PERCENTAGE": 305,
	"METRIC_RAM_TEMP":                     400,
	"METRIC_RAM_CAPACITY":                 401,
	"METRIC_RAM_USAGE":                    402,
	"METRIC_RAM_USAGE_PERCENTAGE":         403,
	"METRIC_POWER_MAX":                    500,
	"METRIC_POWER_USAGE":                  501,
	"METRIC_POWER_USAGE_PERCENTAGE":       502,
	"METRIC_INNER_SURROUNDING_TEMP":       600,
}

func (x MetricNames) String() string {
	return proto.EnumName(MetricNames_name, int32(x))
}

func (MetricNames) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{0}
}

type ListMetricsResponse_Reason int32

const (
	ListMetricsResponse_UNDEFINED_REASON   ListMetricsResponse_Reason = 0
	ListMetricsResponse_UNKNOWN_DEVICE     ListMetricsResponse_Reason = 1
	ListMetricsResponse_INTERNAL_ERROR     ListMetricsResponse_Reason = 2
	ListMetricsResponse_DEVICE_UNREACHABLE ListMetricsResponse_Reason = 3
)

var ListMetricsResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "INTERNAL_ERROR",
	3: "DEVICE_UNREACHABLE",
}

var ListMetricsResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":   0,
	"UNKNOWN_DEVICE":     1,
	"INTERNAL_ERROR":     2,
	"DEVICE_UNREACHABLE": 3,
}

func (x ListMetricsResponse_Reason) String() string {
	return proto.EnumName(ListMetricsResponse_Reason_name, int32(x))
}

func (ListMetricsResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{2, 0}
}

type MetricsConfigurationResponse_Reason int32

const (
	MetricsConfigurationResponse_UNDEFINED_REASON          MetricsConfigurationResponse_Reason = 0
	MetricsConfigurationResponse_UNKNOWN_DEVICE            MetricsConfigurationResponse_Reason = 1
	MetricsConfigurationResponse_INTERNAL_ERROR            MetricsConfigurationResponse_Reason = 2
	MetricsConfigurationResponse_POLL_INTERVAL_UNSUPPORTED MetricsConfigurationResponse_Reason = 3
	MetricsConfigurationResponse_INVALID_METRIC            MetricsConfigurationResponse_Reason = 4
	MetricsConfigurationResponse_DEVICE_UNREACHABLE        MetricsConfigurationResponse_Reason = 5
)

var MetricsConfigurationResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "INTERNAL_ERROR",
	3: "POLL_INTERVAL_UNSUPPORTED",
	4: "INVALID_METRIC",
	5: "DEVICE_UNREACHABLE",
}

var MetricsConfigurationResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":          0,
	"UNKNOWN_DEVICE":            1,
	"INTERNAL_ERROR":            2,
	"POLL_INTERVAL_UNSUPPORTED": 3,
	"INVALID_METRIC":            4,
	"DEVICE_UNREACHABLE":        5,
}

func (x MetricsConfigurationResponse_Reason) String() string {
	return proto.EnumName(MetricsConfigurationResponse_Reason_name, int32(x))
}

func (MetricsConfigurationResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{4, 0}
}

type GetMetricResponse_Reason int32

const (
	GetMetricResponse_UNDEFINED_REASON   GetMetricResponse_Reason = 0
	GetMetricResponse_UNKNOWN_DEVICE     GetMetricResponse_Reason = 1
	GetMetricResponse_UNKNOWN_COMPONENT  GetMetricResponse_Reason = 2
	GetMetricResponse_INTERNAL_ERROR     GetMetricResponse_Reason = 3
	GetMetricResponse_INVALID_METRIC     GetMetricResponse_Reason = 4
	GetMetricResponse_DEVICE_UNREACHABLE GetMetricResponse_Reason = 5
)

var GetMetricResponse_Reason_name = map[int32]string{
	0: "UNDEFINED_REASON",
	1: "UNKNOWN_DEVICE",
	2: "UNKNOWN_COMPONENT",
	3: "INTERNAL_ERROR",
	4: "INVALID_METRIC",
	5: "DEVICE_UNREACHABLE",
}

var GetMetricResponse_Reason_value = map[string]int32{
	"UNDEFINED_REASON":   0,
	"UNKNOWN_DEVICE":     1,
	"UNKNOWN_COMPONENT":  2,
	"INTERNAL_ERROR":     3,
	"INVALID_METRIC":     4,
	"DEVICE_UNREACHABLE": 5,
}

func (x GetMetricResponse_Reason) String() string {
	return proto.EnumName(GetMetricResponse_Reason_name, int32(x))
}

func (GetMetricResponse_Reason) EnumDescriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{8, 0}
}

type MetricConfig struct {
	MetricId MetricNames `protobuf:"varint,1,opt,name=metric_id,json=metricId,proto3,enum=dmi.MetricNames" json:"metric_id,omitempty"`
	// Whether the device manager is collecting and reporting this metric or not
	IsConfigured bool `protobuf:"varint,2,opt,name=is_configured,json=isConfigured,proto3" json:"is_configured,omitempty"`
	// Number of seconds between two consecutive polls of the particular metric
	// Each device manager implemenation could have it's per metric default poll frequency which
	// can be requested to be changed using this value
	PollInterval         uint32   `protobuf:"varint,3,opt,name=poll_interval,json=pollInterval,proto3" json:"poll_interval,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *MetricConfig) Reset()         { *m = MetricConfig{} }
func (m *MetricConfig) String() string { return proto.CompactTextString(m) }
func (*MetricConfig) ProtoMessage()    {}
func (*MetricConfig) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{0}
}

func (m *MetricConfig) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MetricConfig.Unmarshal(m, b)
}
func (m *MetricConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MetricConfig.Marshal(b, m, deterministic)
}
func (m *MetricConfig) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MetricConfig.Merge(m, src)
}
func (m *MetricConfig) XXX_Size() int {
	return xxx_messageInfo_MetricConfig.Size(m)
}
func (m *MetricConfig) XXX_DiscardUnknown() {
	xxx_messageInfo_MetricConfig.DiscardUnknown(m)
}

var xxx_messageInfo_MetricConfig proto.InternalMessageInfo

func (m *MetricConfig) GetMetricId() MetricNames {
	if m != nil {
		return m.MetricId
	}
	return MetricNames_METRIC_NAME_UNDEFINED
}

func (m *MetricConfig) GetIsConfigured() bool {
	if m != nil {
		return m.IsConfigured
	}
	return false
}

func (m *MetricConfig) GetPollInterval() uint32 {
	if m != nil {
		return m.PollInterval
	}
	return 0
}

type MetricsConfig struct {
	Metrics              []*MetricConfig `protobuf:"bytes,1,rep,name=metrics,proto3" json:"metrics,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *MetricsConfig) Reset()         { *m = MetricsConfig{} }
func (m *MetricsConfig) String() string { return proto.CompactTextString(m) }
func (*MetricsConfig) ProtoMessage()    {}
func (*MetricsConfig) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{1}
}

func (m *MetricsConfig) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MetricsConfig.Unmarshal(m, b)
}
func (m *MetricsConfig) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MetricsConfig.Marshal(b, m, deterministic)
}
func (m *MetricsConfig) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MetricsConfig.Merge(m, src)
}
func (m *MetricsConfig) XXX_Size() int {
	return xxx_messageInfo_MetricsConfig.Size(m)
}
func (m *MetricsConfig) XXX_DiscardUnknown() {
	xxx_messageInfo_MetricsConfig.DiscardUnknown(m)
}

var xxx_messageInfo_MetricsConfig proto.InternalMessageInfo

func (m *MetricsConfig) GetMetrics() []*MetricConfig {
	if m != nil {
		return m.Metrics
	}
	return nil
}

type ListMetricsResponse struct {
	Status               Status                     `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               ListMetricsResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.ListMetricsResponse_Reason" json:"reason,omitempty"`
	Metrics              *MetricsConfig             `protobuf:"bytes,3,opt,name=metrics,proto3" json:"metrics,omitempty"`
	ReasonDetail         string                     `protobuf:"bytes,4,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                   `json:"-"`
	XXX_unrecognized     []byte                     `json:"-"`
	XXX_sizecache        int32                      `json:"-"`
}

func (m *ListMetricsResponse) Reset()         { *m = ListMetricsResponse{} }
func (m *ListMetricsResponse) String() string { return proto.CompactTextString(m) }
func (*ListMetricsResponse) ProtoMessage()    {}
func (*ListMetricsResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{2}
}

func (m *ListMetricsResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_ListMetricsResponse.Unmarshal(m, b)
}
func (m *ListMetricsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_ListMetricsResponse.Marshal(b, m, deterministic)
}
func (m *ListMetricsResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_ListMetricsResponse.Merge(m, src)
}
func (m *ListMetricsResponse) XXX_Size() int {
	return xxx_messageInfo_ListMetricsResponse.Size(m)
}
func (m *ListMetricsResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_ListMetricsResponse.DiscardUnknown(m)
}

var xxx_messageInfo_ListMetricsResponse proto.InternalMessageInfo

func (m *ListMetricsResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *ListMetricsResponse) GetReason() ListMetricsResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return ListMetricsResponse_UNDEFINED_REASON
}

func (m *ListMetricsResponse) GetMetrics() *MetricsConfig {
	if m != nil {
		return m.Metrics
	}
	return nil
}

func (m *ListMetricsResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

type MetricsConfigurationRequest struct {
	DeviceUuid *Uuid `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	// Types that are valid to be assigned to Operation:
	//	*MetricsConfigurationRequest_Changes
	//	*MetricsConfigurationRequest_ResetToDefault
	Operation            isMetricsConfigurationRequest_Operation `protobuf_oneof:"operation"`
	XXX_NoUnkeyedLiteral struct{}                                `json:"-"`
	XXX_unrecognized     []byte                                  `json:"-"`
	XXX_sizecache        int32                                   `json:"-"`
}

func (m *MetricsConfigurationRequest) Reset()         { *m = MetricsConfigurationRequest{} }
func (m *MetricsConfigurationRequest) String() string { return proto.CompactTextString(m) }
func (*MetricsConfigurationRequest) ProtoMessage()    {}
func (*MetricsConfigurationRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{3}
}

func (m *MetricsConfigurationRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MetricsConfigurationRequest.Unmarshal(m, b)
}
func (m *MetricsConfigurationRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MetricsConfigurationRequest.Marshal(b, m, deterministic)
}
func (m *MetricsConfigurationRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MetricsConfigurationRequest.Merge(m, src)
}
func (m *MetricsConfigurationRequest) XXX_Size() int {
	return xxx_messageInfo_MetricsConfigurationRequest.Size(m)
}
func (m *MetricsConfigurationRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_MetricsConfigurationRequest.DiscardUnknown(m)
}

var xxx_messageInfo_MetricsConfigurationRequest proto.InternalMessageInfo

func (m *MetricsConfigurationRequest) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

type isMetricsConfigurationRequest_Operation interface {
	isMetricsConfigurationRequest_Operation()
}

type MetricsConfigurationRequest_Changes struct {
	Changes *MetricsConfig `protobuf:"bytes,2,opt,name=changes,proto3,oneof"`
}

type MetricsConfigurationRequest_ResetToDefault struct {
	ResetToDefault bool `protobuf:"varint,3,opt,name=reset_to_default,json=resetToDefault,proto3,oneof"`
}

func (*MetricsConfigurationRequest_Changes) isMetricsConfigurationRequest_Operation() {}

func (*MetricsConfigurationRequest_ResetToDefault) isMetricsConfigurationRequest_Operation() {}

func (m *MetricsConfigurationRequest) GetOperation() isMetricsConfigurationRequest_Operation {
	if m != nil {
		return m.Operation
	}
	return nil
}

func (m *MetricsConfigurationRequest) GetChanges() *MetricsConfig {
	if x, ok := m.GetOperation().(*MetricsConfigurationRequest_Changes); ok {
		return x.Changes
	}
	return nil
}

func (m *MetricsConfigurationRequest) GetResetToDefault() bool {
	if x, ok := m.GetOperation().(*MetricsConfigurationRequest_ResetToDefault); ok {
		return x.ResetToDefault
	}
	return false
}

// XXX_OneofWrappers is for the internal use of the proto package.
func (*MetricsConfigurationRequest) XXX_OneofWrappers() []interface{} {
	return []interface{}{
		(*MetricsConfigurationRequest_Changes)(nil),
		(*MetricsConfigurationRequest_ResetToDefault)(nil),
	}
}

type MetricsConfigurationResponse struct {
	Status               Status                              `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               MetricsConfigurationResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.MetricsConfigurationResponse_Reason" json:"reason,omitempty"`
	ReasonDetail         string                              `protobuf:"bytes,3,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                            `json:"-"`
	XXX_unrecognized     []byte                              `json:"-"`
	XXX_sizecache        int32                               `json:"-"`
}

func (m *MetricsConfigurationResponse) Reset()         { *m = MetricsConfigurationResponse{} }
func (m *MetricsConfigurationResponse) String() string { return proto.CompactTextString(m) }
func (*MetricsConfigurationResponse) ProtoMessage()    {}
func (*MetricsConfigurationResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{4}
}

func (m *MetricsConfigurationResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MetricsConfigurationResponse.Unmarshal(m, b)
}
func (m *MetricsConfigurationResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MetricsConfigurationResponse.Marshal(b, m, deterministic)
}
func (m *MetricsConfigurationResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MetricsConfigurationResponse.Merge(m, src)
}
func (m *MetricsConfigurationResponse) XXX_Size() int {
	return xxx_messageInfo_MetricsConfigurationResponse.Size(m)
}
func (m *MetricsConfigurationResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_MetricsConfigurationResponse.DiscardUnknown(m)
}

var xxx_messageInfo_MetricsConfigurationResponse proto.InternalMessageInfo

func (m *MetricsConfigurationResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *MetricsConfigurationResponse) GetReason() MetricsConfigurationResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return MetricsConfigurationResponse_UNDEFINED_REASON
}

func (m *MetricsConfigurationResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

type MetricMetaData struct {
	DeviceUuid *Uuid `protobuf:"bytes,1,opt,name=device_uuid,json=deviceUuid,proto3" json:"device_uuid,omitempty"`
	// uuid of the component
	ComponentUuid        *Uuid    `protobuf:"bytes,2,opt,name=component_uuid,json=componentUuid,proto3" json:"component_uuid,omitempty"`
	ComponentName        string   `protobuf:"bytes,3,opt,name=component_name,json=componentName,proto3" json:"component_name,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *MetricMetaData) Reset()         { *m = MetricMetaData{} }
func (m *MetricMetaData) String() string { return proto.CompactTextString(m) }
func (*MetricMetaData) ProtoMessage()    {}
func (*MetricMetaData) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{5}
}

func (m *MetricMetaData) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_MetricMetaData.Unmarshal(m, b)
}
func (m *MetricMetaData) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_MetricMetaData.Marshal(b, m, deterministic)
}
func (m *MetricMetaData) XXX_Merge(src proto.Message) {
	xxx_messageInfo_MetricMetaData.Merge(m, src)
}
func (m *MetricMetaData) XXX_Size() int {
	return xxx_messageInfo_MetricMetaData.Size(m)
}
func (m *MetricMetaData) XXX_DiscardUnknown() {
	xxx_messageInfo_MetricMetaData.DiscardUnknown(m)
}

var xxx_messageInfo_MetricMetaData proto.InternalMessageInfo

func (m *MetricMetaData) GetDeviceUuid() *Uuid {
	if m != nil {
		return m.DeviceUuid
	}
	return nil
}

func (m *MetricMetaData) GetComponentUuid() *Uuid {
	if m != nil {
		return m.ComponentUuid
	}
	return nil
}

func (m *MetricMetaData) GetComponentName() string {
	if m != nil {
		return m.ComponentName
	}
	return ""
}

// The Metrics are conveyed to external systems either by submitting them on a message bus or using gRPC server streaming.
// The topic to which are Metrics are submitted would be configured as startup
// configuration of the components
type Metric struct {
	MetricId             MetricNames          `protobuf:"varint,1,opt,name=metric_id,json=metricId,proto3,enum=dmi.MetricNames" json:"metric_id,omitempty"`
	MetricMetadata       *MetricMetaData      `protobuf:"bytes,2,opt,name=metric_metadata,json=metricMetadata,proto3" json:"metric_metadata,omitempty"`
	Value                *ComponentSensorData `protobuf:"bytes,3,opt,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{}             `json:"-"`
	XXX_unrecognized     []byte               `json:"-"`
	XXX_sizecache        int32                `json:"-"`
}

func (m *Metric) Reset()         { *m = Metric{} }
func (m *Metric) String() string { return proto.CompactTextString(m) }
func (*Metric) ProtoMessage()    {}
func (*Metric) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{6}
}

func (m *Metric) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_Metric.Unmarshal(m, b)
}
func (m *Metric) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_Metric.Marshal(b, m, deterministic)
}
func (m *Metric) XXX_Merge(src proto.Message) {
	xxx_messageInfo_Metric.Merge(m, src)
}
func (m *Metric) XXX_Size() int {
	return xxx_messageInfo_Metric.Size(m)
}
func (m *Metric) XXX_DiscardUnknown() {
	xxx_messageInfo_Metric.DiscardUnknown(m)
}

var xxx_messageInfo_Metric proto.InternalMessageInfo

func (m *Metric) GetMetricId() MetricNames {
	if m != nil {
		return m.MetricId
	}
	return MetricNames_METRIC_NAME_UNDEFINED
}

func (m *Metric) GetMetricMetadata() *MetricMetaData {
	if m != nil {
		return m.MetricMetadata
	}
	return nil
}

func (m *Metric) GetValue() *ComponentSensorData {
	if m != nil {
		return m.Value
	}
	return nil
}

type GetMetricRequest struct {
	MetaData             *MetricMetaData `protobuf:"bytes,1,opt,name=meta_data,json=metaData,proto3" json:"meta_data,omitempty"`
	MetricId             MetricNames     `protobuf:"varint,2,opt,name=metric_id,json=metricId,proto3,enum=dmi.MetricNames" json:"metric_id,omitempty"`
	XXX_NoUnkeyedLiteral struct{}        `json:"-"`
	XXX_unrecognized     []byte          `json:"-"`
	XXX_sizecache        int32           `json:"-"`
}

func (m *GetMetricRequest) Reset()         { *m = GetMetricRequest{} }
func (m *GetMetricRequest) String() string { return proto.CompactTextString(m) }
func (*GetMetricRequest) ProtoMessage()    {}
func (*GetMetricRequest) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{7}
}

func (m *GetMetricRequest) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_GetMetricRequest.Unmarshal(m, b)
}
func (m *GetMetricRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_GetMetricRequest.Marshal(b, m, deterministic)
}
func (m *GetMetricRequest) XXX_Merge(src proto.Message) {
	xxx_messageInfo_GetMetricRequest.Merge(m, src)
}
func (m *GetMetricRequest) XXX_Size() int {
	return xxx_messageInfo_GetMetricRequest.Size(m)
}
func (m *GetMetricRequest) XXX_DiscardUnknown() {
	xxx_messageInfo_GetMetricRequest.DiscardUnknown(m)
}

var xxx_messageInfo_GetMetricRequest proto.InternalMessageInfo

func (m *GetMetricRequest) GetMetaData() *MetricMetaData {
	if m != nil {
		return m.MetaData
	}
	return nil
}

func (m *GetMetricRequest) GetMetricId() MetricNames {
	if m != nil {
		return m.MetricId
	}
	return MetricNames_METRIC_NAME_UNDEFINED
}

type GetMetricResponse struct {
	Status               Status                   `protobuf:"varint,1,opt,name=status,proto3,enum=dmi.Status" json:"status,omitempty"`
	Reason               GetMetricResponse_Reason `protobuf:"varint,2,opt,name=reason,proto3,enum=dmi.GetMetricResponse_Reason" json:"reason,omitempty"`
	Metric               *Metric                  `protobuf:"bytes,3,opt,name=metric,proto3" json:"metric,omitempty"`
	ReasonDetail         string                   `protobuf:"bytes,4,opt,name=reason_detail,json=reasonDetail,proto3" json:"reason_detail,omitempty"`
	XXX_NoUnkeyedLiteral struct{}                 `json:"-"`
	XXX_unrecognized     []byte                   `json:"-"`
	XXX_sizecache        int32                    `json:"-"`
}

func (m *GetMetricResponse) Reset()         { *m = GetMetricResponse{} }
func (m *GetMetricResponse) String() string { return proto.CompactTextString(m) }
func (*GetMetricResponse) ProtoMessage()    {}
func (*GetMetricResponse) Descriptor() ([]byte, []int) {
	return fileDescriptor_6b6c2f1384c11ff5, []int{8}
}

func (m *GetMetricResponse) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_GetMetricResponse.Unmarshal(m, b)
}
func (m *GetMetricResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_GetMetricResponse.Marshal(b, m, deterministic)
}
func (m *GetMetricResponse) XXX_Merge(src proto.Message) {
	xxx_messageInfo_GetMetricResponse.Merge(m, src)
}
func (m *GetMetricResponse) XXX_Size() int {
	return xxx_messageInfo_GetMetricResponse.Size(m)
}
func (m *GetMetricResponse) XXX_DiscardUnknown() {
	xxx_messageInfo_GetMetricResponse.DiscardUnknown(m)
}

var xxx_messageInfo_GetMetricResponse proto.InternalMessageInfo

func (m *GetMetricResponse) GetStatus() Status {
	if m != nil {
		return m.Status
	}
	return Status_UNDEFINED_STATUS
}

func (m *GetMetricResponse) GetReason() GetMetricResponse_Reason {
	if m != nil {
		return m.Reason
	}
	return GetMetricResponse_UNDEFINED_REASON
}

func (m *GetMetricResponse) GetMetric() *Metric {
	if m != nil {
		return m.Metric
	}
	return nil
}

func (m *GetMetricResponse) GetReasonDetail() string {
	if m != nil {
		return m.ReasonDetail
	}
	return ""
}

func init() {
	proto.RegisterEnum("dmi.MetricNames", MetricNames_name, MetricNames_value)
	proto.RegisterEnum("dmi.ListMetricsResponse_Reason", ListMetricsResponse_Reason_name, ListMetricsResponse_Reason_value)
	proto.RegisterEnum("dmi.MetricsConfigurationResponse_Reason", MetricsConfigurationResponse_Reason_name, MetricsConfigurationResponse_Reason_value)
	proto.RegisterEnum("dmi.GetMetricResponse_Reason", GetMetricResponse_Reason_name, GetMetricResponse_Reason_value)
	proto.RegisterType((*MetricConfig)(nil), "dmi.MetricConfig")
	proto.RegisterType((*MetricsConfig)(nil), "dmi.MetricsConfig")
	proto.RegisterType((*ListMetricsResponse)(nil), "dmi.ListMetricsResponse")
	proto.RegisterType((*MetricsConfigurationRequest)(nil), "dmi.MetricsConfigurationRequest")
	proto.RegisterType((*MetricsConfigurationResponse)(nil), "dmi.MetricsConfigurationResponse")
	proto.RegisterType((*MetricMetaData)(nil), "dmi.MetricMetaData")
	proto.RegisterType((*Metric)(nil), "dmi.Metric")
	proto.RegisterType((*GetMetricRequest)(nil), "dmi.GetMetricRequest")
	proto.RegisterType((*GetMetricResponse)(nil), "dmi.GetMetricResponse")
}

func init() { proto.RegisterFile("dmi/hw_metrics_mgmt_service.proto", fileDescriptor_6b6c2f1384c11ff5) }

var fileDescriptor_6b6c2f1384c11ff5 = []byte{
	// 1258 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x56, 0x4d, 0x6f, 0xdb, 0x46,
	0x13, 0x36, 0xa9, 0xc4, 0x89, 0x57, 0xb6, 0x42, 0xaf, 0xf3, 0xa1, 0x28, 0xc9, 0x1b, 0x59, 0xc1,
	0xdb, 0x0a, 0x69, 0x23, 0x05, 0x0e, 0xfa, 0x9d, 0x43, 0x69, 0x72, 0x63, 0x13, 0x91, 0x28, 0x61,
	0x49, 0xd9, 0x49, 0x0f, 0x5d, 0x6c, 0xc4, 0xb5, 0x42, 0x40, 0x24, 0x55, 0x92, 0x72, 0xd0, 0x6b,
	0x2f, 0x45, 0x6f, 0x4d, 0x8b, 0xfe, 0x84, 0xf6, 0xd4, 0xaf, 0xf4, 0x07, 0xf4, 0x56, 0xa0, 0xdf,
	0xe7, 0xfe, 0x90, 0xb6, 0xe7, 0x82, 0xbb, 0x94, 0xb2, 0x96, 0xe5, 0xa6, 0x2e, 0x7a, 0x93, 0x9e,
	0x79, 0x66, 0xe6, 0x99, 0x99, 0xe5, 0xec, 0x82, 0x75, 0x2f, 0xf0, 0x9b, 0x0f, 0x1f, 0x91, 0x80,
	0xa5, 0xb1, 0xdf, 0x4f, 0x48, 0x30, 0x08, 0x52, 0x92, 0xb0, 0x78, 0xdf, 0xef, 0xb3, 0xc6, 0x28,
	0x8e, 0xd2, 0x08, 0x16, 0xbc, 0xc0, 0xaf, 0xac, 0x66, 0xbc, 0x7e, 0x14, 0x04, 0x51, 0x98, 0x08,
	0xbc, 0xb2, 0x2c, 0x5c, 0xf3, 0x7f, 0x97, 0x06, 0x51, 0x34, 0x18, 0xb2, 0x26, 0xff, 0xf7, 0x60,
	0xbc, 0xd7, 0x64, 0xc1, 0x28, 0x7d, 0x57, 0x18, 0x6b, 0xef, 0x2b, 0x60, 0xb9, 0xcd, 0x33, 0x18,
	0x51, 0xb8, 0xe7, 0x0f, 0xe0, 0x0d, 0xb0, 0x24, 0x32, 0x12, 0xdf, 0x2b, 0x2b, 0x55, 0xa5, 0x5e,
	0xda, 0xd0, 0x1a, 0x5e, 0xe0, 0x37, 0x04, 0xcb, 0xa6, 0x01, 0x4b, 0xf0, 0x69, 0x41, 0xb1, 0x3c,
	0x78, 0x0d, 0xac, 0xf8, 0x09, 0xe9, 0x73, 0xdf, 0x71, 0xcc, 0xbc, 0xb2, 0x5a, 0x55, 0xea, 0xa7,
	0xf1, 0xb2, 0x9f, 0x18, 0x53, 0x2c, 0x23, 0x8d, 0xa2, 0xe1, 0x90, 0xf8, 0x61, 0xca, 0xe2, 0x7d,
	0x3a, 0x2c, 0x17, 0xaa, 0x4a, 0x7d, 0x05, 0x2f, 0x67, 0xa0, 0x95, 0x63, 0xb5, 0xdb, 0x60, 0x45,
	0xa4, 0xc8, 0x3d, 0xe1, 0x0b, 0xe0, 0x54, 0x5e, 0x7b, 0x59, 0xa9, 0x16, 0xea, 0xc5, 0x8d, 0x55,
	0x49, 0x87, 0xe0, 0xe0, 0x09, 0xa3, 0xf6, 0x99, 0x0a, 0xd6, 0x5a, 0x7e, 0x92, 0xe6, 0x21, 0x30,
	0x4b, 0x46, 0x51, 0x98, 0x30, 0x78, 0x0d, 0x2c, 0x26, 0x29, 0x4d, 0xc7, 0x49, 0x5e, 0x4b, 0x91,
	0xc7, 0x70, 0x38, 0x84, 0x73, 0x13, 0x7c, 0x05, 0x2c, 0xc6, 0x8c, 0x26, 0x51, 0xc8, 0xd5, 0x97,
	0x36, 0xae, 0x72, 0xd2, 0x9c, 0x70, 0x0d, 0xcc, 0x69, 0x38, 0xa7, 0xc3, 0x17, 0x9f, 0x4a, 0xcc,
	0x4a, 0x2a, 0x6e, 0x40, 0x49, 0x62, 0x32, 0xa3, 0x31, 0x6b, 0x83, 0xf0, 0x23, 0x1e, 0x4b, 0xa9,
	0x3f, 0x2c, 0x9f, 0xa8, 0x2a, 0xf5, 0x25, 0xbc, 0x2c, 0x40, 0x93, 0x63, 0xb5, 0xb7, 0xc1, 0xa2,
	0x48, 0x02, 0xcf, 0x02, 0xad, 0x67, 0x9b, 0xe8, 0x8e, 0x65, 0x23, 0x93, 0x60, 0xa4, 0x3b, 0x1d,
	0x5b, 0x5b, 0x80, 0x10, 0x94, 0x7a, 0xf6, 0x5d, 0xbb, 0xb3, 0x6b, 0x13, 0x13, 0xed, 0x58, 0x06,
	0xd2, 0x94, 0x0c, 0xb3, 0x6c, 0x17, 0x61, 0x5b, 0x6f, 0x11, 0x84, 0x71, 0x07, 0x6b, 0x2a, 0x3c,
	0x0f, 0xa0, 0xb0, 0x93, 0x9e, 0x8d, 0x91, 0x6e, 0x6c, 0xeb, 0x9b, 0x2d, 0xa4, 0x15, 0x6a, 0xdf,
	0x28, 0xe0, 0xd2, 0x01, 0x7d, 0xe3, 0x98, 0xa6, 0x7e, 0x14, 0x62, 0xf6, 0xce, 0x98, 0x25, 0x29,
	0xbc, 0x0e, 0x8a, 0x1e, 0xcb, 0xce, 0x18, 0x19, 0x8f, 0xf3, 0x13, 0x50, 0xdc, 0x58, 0xe2, 0x65,
	0xf5, 0xc6, 0xbe, 0x87, 0x81, 0xb0, 0x66, 0xbf, 0x61, 0x03, 0x9c, 0xea, 0x3f, 0xa4, 0xe1, 0x80,
	0x25, 0xbc, 0x71, 0x73, 0xcb, 0xdf, 0x5e, 0xc0, 0x13, 0x12, 0xbc, 0x0e, 0xb4, 0x98, 0x25, 0x2c,
	0x25, 0x69, 0x44, 0x3c, 0xb6, 0x47, 0xc7, 0xc3, 0x94, 0xf7, 0xed, 0xf4, 0xf6, 0x02, 0x2e, 0x71,
	0x8b, 0x1b, 0x99, 0x02, 0xdf, 0x2c, 0x82, 0xa5, 0x68, 0xc4, 0x84, 0xb6, 0xda, 0xb7, 0x2a, 0xb8,
	0x3c, 0x5f, 0xf4, 0x71, 0xc6, 0xfc, 0xe6, 0xcc, 0x98, 0xeb, 0x87, 0xd5, 0xce, 0xc4, 0x9d, 0x9d,
	0xf7, 0xa1, 0x09, 0x16, 0xe6, 0x4c, 0xf0, 0xb1, 0xf2, 0x1f, 0x8d, 0xf0, 0x0a, 0xb8, 0xd8, 0xed,
	0xb4, 0x5a, 0x84, 0x1b, 0x76, 0xf4, 0x16, 0xe9, 0xd9, 0x4e, 0xaf, 0xdb, 0xed, 0x60, 0x17, 0x99,
	0x5a, 0x41, 0xb8, 0xec, 0xe8, 0x2d, 0xcb, 0x24, 0x6d, 0xe4, 0x62, 0xcb, 0xd0, 0x4e, 0x1c, 0x31,
	0xf5, 0x93, 0xb5, 0x4f, 0x14, 0x50, 0x12, 0x85, 0xb6, 0x59, 0x4a, 0x4d, 0x9a, 0xd2, 0x63, 0x0d,
	0xfa, 0x26, 0x28, 0xf5, 0xa3, 0x60, 0x14, 0x85, 0x2c, 0x4c, 0x05, 0x5d, 0x9d, 0xa5, 0xaf, 0x4c,
	0x09, 0xdc, 0xe3, 0xff, 0xb2, 0x47, 0x48, 0x03, 0x96, 0xb7, 0xea, 0x29, 0x2d, 0xdb, 0x24, 0xb5,
	0x4f, 0x15, 0xb0, 0x28, 0x74, 0x1d, 0x77, 0xf1, 0xdc, 0x06, 0x67, 0x72, 0x7a, 0xc0, 0x52, 0xea,
	0xd1, 0x94, 0xe6, 0x9a, 0xd6, 0x24, 0xa7, 0x49, 0xb1, 0xb8, 0x14, 0x4c, 0xff, 0x67, 0x54, 0xd8,
	0x00, 0x27, 0xf7, 0xe9, 0x70, 0xcc, 0xf2, 0xcf, 0xb6, 0xcc, 0x7d, 0x8c, 0x89, 0x34, 0x87, 0x85,
	0x49, 0x14, 0x73, 0x47, 0x41, 0xab, 0x25, 0x40, 0xdb, 0x62, 0xf9, 0x36, 0x98, 0x7c, 0x29, 0x37,
	0xb9, 0x60, 0x4a, 0x78, 0x6e, 0xe5, 0xe8, 0xdc, 0x99, 0x66, 0xd1, 0xf2, 0x03, 0x25, 0xaa, 0xcf,
	0x2a, 0xb1, 0xf6, 0x9d, 0x0a, 0x56, 0xa5, 0xac, 0xc7, 0x39, 0xea, 0x2f, 0xcd, 0x1c, 0xf5, 0x2b,
	0x9c, 0x74, 0x28, 0xd8, 0xe1, 0xf3, 0xbd, 0x28, 0xb2, 0xe7, 0x7d, 0x29, 0x4a, 0xea, 0x70, 0x6e,
	0xfa, 0x67, 0x6b, 0xec, 0x83, 0x7f, 0xf3, 0x11, 0x9c, 0x03, 0xab, 0x13, 0xcc, 0xe8, 0xb4, 0xbb,
	0x1d, 0x1b, 0xd9, 0xae, 0xa6, 0xce, 0xf9, 0x36, 0x8e, 0x75, 0xf8, 0xaf, 0xbf, 0xb7, 0x08, 0x8a,
	0x52, 0x87, 0xe1, 0x45, 0x70, 0x4e, 0xf8, 0x10, 0x5b, 0x6f, 0x67, 0xe4, 0x5c, 0x9c, 0xb6, 0x90,
	0x69, 0xcd, 0x4d, 0x77, 0x74, 0x9b, 0x38, 0x5d, 0x84, 0x4c, 0x4d, 0x81, 0x6b, 0xe0, 0x4c, 0x8e,
	0x1a, 0xdd, 0x1e, 0x71, 0x51, 0xbb, 0xab, 0x79, 0xf0, 0x2a, 0xb8, 0x24, 0x81, 0x3d, 0x47, 0xdf,
	0x42, 0xa4, 0x8b, 0xb0, 0x81, 0x6c, 0x57, 0xdf, 0x42, 0x1a, 0x83, 0x97, 0xc1, 0x85, 0x9c, 0xe0,
	0x62, 0xdd, 0x76, 0x0c, 0x64, 0xed, 0x20, 0x2c, 0xbc, 0xbf, 0x57, 0xe0, 0x55, 0x50, 0x99, 0x63,
	0xdd, 0xe9, 0xb4, 0xb8, 0xf7, 0x0f, 0xca, 0x11, 0xee, 0x9b, 0x96, 0xee, 0x68, 0x3f, 0x2a, 0xb0,
	0x3a, 0xcd, 0x2e, 0x5b, 0xf1, 0x3d, 0xd2, 0xed, 0xec, 0x22, 0xac, 0xfd, 0x74, 0x14, 0xc3, 0x9d,
	0x30, 0x7e, 0x56, 0x60, 0x0d, 0x5c, 0x99, 0xc3, 0xd8, 0xd5, 0x77, 0x50, 0x0b, 0xd9, 0x5b, 0xee,
	0xb6, 0xf6, 0x8b, 0x02, 0x9f, 0x07, 0xb5, 0x39, 0x9c, 0x7b, 0x5b, 0x4e, 0xb7, 0x63, 0x3f, 0x0d,
	0xf6, 0x6b, 0x36, 0xbb, 0x49, 0xe7, 0x4c, 0xcb, 0xb9, 0x2b, 0xca, 0xfc, 0x5c, 0x85, 0x17, 0xc1,
	0x59, 0x19, 0x36, 0xf4, 0xae, 0x6e, 0x58, 0xee, 0x7d, 0xed, 0x8b, 0xec, 0x86, 0x5a, 0x95, 0x4d,
	0xbc, 0x83, 0xda, 0x97, 0x2a, 0x5c, 0x07, 0x97, 0x0f, 0xe1, 0x72, 0x67, 0xbf, 0x52, 0xe1, 0x73,
	0x60, 0x5d, 0xa6, 0x60, 0xa4, 0x9b, 0x64, 0x17, 0x5b, 0xee, 0x01, 0xde, 0xd7, 0x2a, 0xac, 0x83,
	0x6b, 0x32, 0xef, 0x8e, 0xde, 0x6b, 0xb9, 0xf7, 0x89, 0x81, 0x5a, 0x2d, 0x47, 0x66, 0x3e, 0x51,
	0xe1, 0xd9, 0xe9, 0x88, 0xb1, 0xde, 0x16, 0xea, 0x3f, 0x2c, 0xc0, 0x32, 0x58, 0x93, 0xd0, 0xa9,
	0xf8, 0xc7, 0x05, 0xa9, 0xdc, 0xcc, 0x22, 0xb4, 0x7f, 0x54, 0x90, 0x9a, 0x3e, 0x85, 0xe5, 0x44,
	0x1f, 0xcb, 0x8e, 0xbc, 0x75, 0xa4, 0xad, 0xdf, 0xd3, 0x7e, 0x2f, 0xc0, 0x0b, 0x00, 0x1e, 0x80,
	0x45, 0xc4, 0x3f, 0x0a, 0xd2, 0x90, 0x24, 0x83, 0x1c, 0xf3, 0x4f, 0x99, 0x63, 0xd9, 0x36, 0xc2,
	0xc4, 0xe9, 0x61, 0xdc, 0xe9, 0xd9, 0xa6, 0x65, 0x6f, 0x89, 0x52, 0x7e, 0x3b, 0xb1, 0xf1, 0x44,
	0x05, 0xff, 0xb3, 0x69, 0xea, 0xef, 0xb3, 0xfc, 0xc2, 0x6b, 0xd3, 0x90, 0x0e, 0x58, 0xc0, 0xd7,
	0x1d, 0x7f, 0x54, 0xc2, 0x57, 0x41, 0x51, 0x7a, 0xf3, 0xc0, 0x33, 0xfc, 0xe3, 0xdf, 0xa6, 0xb1,
	0xf7, 0x88, 0xc6, 0xcc, 0x32, 0x2b, 0xe5, 0xa3, 0x9e, 0x45, 0x90, 0x82, 0x4a, 0x6f, 0xe4, 0xd1,
	0x94, 0xcd, 0xbb, 0x4c, 0x61, 0xf5, 0x6f, 0xee, 0x59, 0xbe, 0x4a, 0x2b, 0xeb, 0xcf, 0xbc, 0x89,
	0xe1, 0xeb, 0x60, 0x69, 0xba, 0xbe, 0xe0, 0xb9, 0xd9, 0x75, 0x26, 0xc2, 0x9c, 0x9f, 0xbf, 0xe5,
	0xe0, 0xcb, 0x60, 0xc5, 0x49, 0x63, 0x46, 0x83, 0x49, 0x69, 0xe7, 0x1b, 0xe2, 0x4d, 0xdc, 0x98,
	0xbc, 0x89, 0x1b, 0x28, 0x7b, 0x13, 0x57, 0xe4, 0x7d, 0x77, 0x53, 0xd9, 0x7c, 0xe3, 0xad, 0xd7,
	0x06, 0x7e, 0xfa, 0x70, 0xfc, 0xa0, 0xd1, 0x8f, 0x82, 0x66, 0x34, 0x62, 0x61, 0x3f, 0x8a, 0xbd,
	0xa6, 0xb8, 0x18, 0x6f, 0x04, 0xd3, 0x06, 0xde, 0xe0, 0x0f, 0xdb, 0x3d, 0xda, 0x67, 0xcd, 0xfd,
	0x5b, 0xcd, 0x41, 0xd4, 0xf4, 0x02, 0xff, 0xc1, 0x22, 0x8f, 0x7d, 0xeb, 0xaf, 0x00, 0x00, 0x00,
	0xff, 0xff, 0x08, 0x7e, 0xf5, 0xaf, 0xc8, 0x0b, 0x00, 0x00,
}

// Reference imports to suppress errors if they are not otherwise used.
var _ context.Context
var _ grpc.ClientConn

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
const _ = grpc.SupportPackageIsVersion4

// NativeMetricsManagementServiceClient is the client API for NativeMetricsManagementService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.
type NativeMetricsManagementServiceClient interface {
	// List the supported metrics for the passed device.
	// This would be the first call that you make to know about the metrics that a particular device supports and
	// then use the UpdateMetricsConfiguration API to monitor only the required metrics.
	ListMetrics(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (*ListMetricsResponse, error)
	// Updates the configuration of the list of metrics in the request
	// Acts upon single metric configuration, collection of a single metric can be started/stopped
	// by changing its configuration.
	//
	// This configuration is persisted across restart of the device or the device manager
	UpdateMetricsConfiguration(ctx context.Context, in *MetricsConfigurationRequest, opts ...grpc.CallOption) (*MetricsConfigurationResponse, error)
	// Get the instantenous value of a metric
	GetMetric(ctx context.Context, in *GetMetricRequest, opts ...grpc.CallOption) (*GetMetricResponse, error)
	// Initiate the server streaming of the metrics
	StreamMetrics(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (NativeMetricsManagementService_StreamMetricsClient, error)
}

type nativeMetricsManagementServiceClient struct {
	cc *grpc.ClientConn
}

func NewNativeMetricsManagementServiceClient(cc *grpc.ClientConn) NativeMetricsManagementServiceClient {
	return &nativeMetricsManagementServiceClient{cc}
}

func (c *nativeMetricsManagementServiceClient) ListMetrics(ctx context.Context, in *HardwareID, opts ...grpc.CallOption) (*ListMetricsResponse, error) {
	out := new(ListMetricsResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeMetricsManagementService/ListMetrics", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeMetricsManagementServiceClient) UpdateMetricsConfiguration(ctx context.Context, in *MetricsConfigurationRequest, opts ...grpc.CallOption) (*MetricsConfigurationResponse, error) {
	out := new(MetricsConfigurationResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeMetricsManagementService/UpdateMetricsConfiguration", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeMetricsManagementServiceClient) GetMetric(ctx context.Context, in *GetMetricRequest, opts ...grpc.CallOption) (*GetMetricResponse, error) {
	out := new(GetMetricResponse)
	err := c.cc.Invoke(ctx, "/dmi.NativeMetricsManagementService/GetMetric", in, out, opts...)
	if err != nil {
		return nil, err
	}
	return out, nil
}

func (c *nativeMetricsManagementServiceClient) StreamMetrics(ctx context.Context, in *empty.Empty, opts ...grpc.CallOption) (NativeMetricsManagementService_StreamMetricsClient, error) {
	stream, err := c.cc.NewStream(ctx, &_NativeMetricsManagementService_serviceDesc.Streams[0], "/dmi.NativeMetricsManagementService/StreamMetrics", opts...)
	if err != nil {
		return nil, err
	}
	x := &nativeMetricsManagementServiceStreamMetricsClient{stream}
	if err := x.ClientStream.SendMsg(in); err != nil {
		return nil, err
	}
	if err := x.ClientStream.CloseSend(); err != nil {
		return nil, err
	}
	return x, nil
}

type NativeMetricsManagementService_StreamMetricsClient interface {
	Recv() (*Metric, error)
	grpc.ClientStream
}

type nativeMetricsManagementServiceStreamMetricsClient struct {
	grpc.ClientStream
}

func (x *nativeMetricsManagementServiceStreamMetricsClient) Recv() (*Metric, error) {
	m := new(Metric)
	if err := x.ClientStream.RecvMsg(m); err != nil {
		return nil, err
	}
	return m, nil
}

// NativeMetricsManagementServiceServer is the server API for NativeMetricsManagementService service.
type NativeMetricsManagementServiceServer interface {
	// List the supported metrics for the passed device.
	// This would be the first call that you make to know about the metrics that a particular device supports and
	// then use the UpdateMetricsConfiguration API to monitor only the required metrics.
	ListMetrics(context.Context, *HardwareID) (*ListMetricsResponse, error)
	// Updates the configuration of the list of metrics in the request
	// Acts upon single metric configuration, collection of a single metric can be started/stopped
	// by changing its configuration.
	//
	// This configuration is persisted across restart of the device or the device manager
	UpdateMetricsConfiguration(context.Context, *MetricsConfigurationRequest) (*MetricsConfigurationResponse, error)
	// Get the instantenous value of a metric
	GetMetric(context.Context, *GetMetricRequest) (*GetMetricResponse, error)
	// Initiate the server streaming of the metrics
	StreamMetrics(*empty.Empty, NativeMetricsManagementService_StreamMetricsServer) error
}

// UnimplementedNativeMetricsManagementServiceServer can be embedded to have forward compatible implementations.
type UnimplementedNativeMetricsManagementServiceServer struct {
}

func (*UnimplementedNativeMetricsManagementServiceServer) ListMetrics(ctx context.Context, req *HardwareID) (*ListMetricsResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method ListMetrics not implemented")
}
func (*UnimplementedNativeMetricsManagementServiceServer) UpdateMetricsConfiguration(ctx context.Context, req *MetricsConfigurationRequest) (*MetricsConfigurationResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method UpdateMetricsConfiguration not implemented")
}
func (*UnimplementedNativeMetricsManagementServiceServer) GetMetric(ctx context.Context, req *GetMetricRequest) (*GetMetricResponse, error) {
	return nil, status.Errorf(codes.Unimplemented, "method GetMetric not implemented")
}
func (*UnimplementedNativeMetricsManagementServiceServer) StreamMetrics(req *empty.Empty, srv NativeMetricsManagementService_StreamMetricsServer) error {
	return status.Errorf(codes.Unimplemented, "method StreamMetrics not implemented")
}

func RegisterNativeMetricsManagementServiceServer(s *grpc.Server, srv NativeMetricsManagementServiceServer) {
	s.RegisterService(&_NativeMetricsManagementService_serviceDesc, srv)
}

func _NativeMetricsManagementService_ListMetrics_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(HardwareID)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeMetricsManagementServiceServer).ListMetrics(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeMetricsManagementService/ListMetrics",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeMetricsManagementServiceServer).ListMetrics(ctx, req.(*HardwareID))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeMetricsManagementService_UpdateMetricsConfiguration_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(MetricsConfigurationRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeMetricsManagementServiceServer).UpdateMetricsConfiguration(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeMetricsManagementService/UpdateMetricsConfiguration",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeMetricsManagementServiceServer).UpdateMetricsConfiguration(ctx, req.(*MetricsConfigurationRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeMetricsManagementService_GetMetric_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
	in := new(GetMetricRequest)
	if err := dec(in); err != nil {
		return nil, err
	}
	if interceptor == nil {
		return srv.(NativeMetricsManagementServiceServer).GetMetric(ctx, in)
	}
	info := &grpc.UnaryServerInfo{
		Server:     srv,
		FullMethod: "/dmi.NativeMetricsManagementService/GetMetric",
	}
	handler := func(ctx context.Context, req interface{}) (interface{}, error) {
		return srv.(NativeMetricsManagementServiceServer).GetMetric(ctx, req.(*GetMetricRequest))
	}
	return interceptor(ctx, in, info, handler)
}

func _NativeMetricsManagementService_StreamMetrics_Handler(srv interface{}, stream grpc.ServerStream) error {
	m := new(empty.Empty)
	if err := stream.RecvMsg(m); err != nil {
		return err
	}
	return srv.(NativeMetricsManagementServiceServer).StreamMetrics(m, &nativeMetricsManagementServiceStreamMetricsServer{stream})
}

type NativeMetricsManagementService_StreamMetricsServer interface {
	Send(*Metric) error
	grpc.ServerStream
}

type nativeMetricsManagementServiceStreamMetricsServer struct {
	grpc.ServerStream
}

func (x *nativeMetricsManagementServiceStreamMetricsServer) Send(m *Metric) error {
	return x.ServerStream.SendMsg(m)
}

var _NativeMetricsManagementService_serviceDesc = grpc.ServiceDesc{
	ServiceName: "dmi.NativeMetricsManagementService",
	HandlerType: (*NativeMetricsManagementServiceServer)(nil),
	Methods: []grpc.MethodDesc{
		{
			MethodName: "ListMetrics",
			Handler:    _NativeMetricsManagementService_ListMetrics_Handler,
		},
		{
			MethodName: "UpdateMetricsConfiguration",
			Handler:    _NativeMetricsManagementService_UpdateMetricsConfiguration_Handler,
		},
		{
			MethodName: "GetMetric",
			Handler:    _NativeMetricsManagementService_GetMetric_Handler,
		},
	},
	Streams: []grpc.StreamDesc{
		{
			StreamName:    "StreamMetrics",
			Handler:       _NativeMetricsManagementService_StreamMetrics_Handler,
			ServerStreams: true,
		},
	},
	Metadata: "dmi/hw_metrics_mgmt_service.proto",
}
