/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * NOTE: This file was generated, manual edits will be overwritten!
 *
 * Generated by 'goCodeGenerator.py':
 *              https://github.com/cboling/OMCI-parser/README.md
 */
package generated

import "github.com/deckarep/golang-set"

const EfmBondingGroupPerformanceMonitoringHistoryDataPart2ClassId ClassID = ClassID(422)

var efmbondinggroupperformancemonitoringhistorydatapart2BME *ManagedEntityDefinition

// EfmBondingGroupPerformanceMonitoringHistoryDataPart2 (class ID #422)
//	This ME collects PM data as seen at the xTU-C. Instances of this ME are created and deleted by
//	the OLT.
//
//	Relationships
//		An instance of this ME is associated with an xDSL UNI.
//
//	Attributes
//		Managed Entity Id
//			Managed entity ID: This attribute uniquely identifies each instance of this ME. Through an
//			identical ID, this ME is implicitly linked to an instance of the EFM bonding group. (R,
//			setbycreate) (mandatory) (2 bytes)
//
//		Interval End Time
//			Interval end time: This attribute identifies the most recently finished 15 min interval. (R)
//			(mandatory) (1 byte)
//
//		Threshold Data 1_2 Id
//			Threshold data 1/2 ID: This attribute points to an instance of the threshold data 1 and 2 MEs
//			that contain PM threshold values. (R, W, setbycreate) (mandatory) (2 bytes)
//
//		Rx Unicast Frames
//			Rx unicast frames: Number of unicast Ethernet frames received over this group. (R) (mandatory)
//			(4 bytes)
//
//		Tx Unicast Frames
//			Tx unicast frames: Number of unicast Ethernet frames transmitted over this group. (R)
//			(mandatory) (4 bytes)
//
//		Rx Unicast Bytes
//			Rx unicast bytes: Number of bytes contained in the unicast Ethernet frames received over this
//			group. (R) (mandatory) (8 bytes)
//
//		Tx Unicast Bytes
//			Tx unicast bytes: Number of bytes contained in the unicast Ethernet frames transmitted over this
//			group. (R) (mandatory) (8 bytes)
//
//		Rx Broadcast Frames
//			Rx broadcast frames: Number of broadcast Ethernet frames received over this group. (R)
//			(mandatory) (4 bytes)
//
//		Tx Broadcast Frames
//			Tx broadcast frames: Number of broadcast Ethernet frames transmitted over this group. (R)
//			(mandatory) (4 bytes)
//
//		Rx Broadcast Bytes
//			Rx broadcast bytes: Number of bytes contained in the broadcast Ethernet frames received over
//			this group. (R) (mandatory) (8 bytes)
//
//		Tx Broadcast Bytes
//			Tx broadcast bytes: Number of bytes contained in the broadcast Ethernet frames transmitted over
//			this group. (R) (mandatory) (8 bytes)
//
//		Rx Multicast Frames
//			Rx multicast frames: Number of multicast Ethernet frames received over this group. (R)
//			(mandatory) (4 bytes)
//
//		Tx Multicast Frames
//			Tx multicast frames: Number of multicast Ethernet frames transmitted over this group. (R)
//			(mandatory) (4 bytes)
//
//		Rx Multicast Bytes
//			Rx multicast bytes: Number of bytes contained in the multicast Ethernet frames received over
//			this group. (R) (mandatory) (8 bytes)
//
//		Tx Multicast Bytes
//			Tx multicast bytes: Number of bytes contained in the multicast Ethernet frames transmitted over
//			this group. (R) (mandatory) (8 bytes)
//
type EfmBondingGroupPerformanceMonitoringHistoryDataPart2 struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

func init() {
	efmbondinggroupperformancemonitoringhistorydatapart2BME = &ManagedEntityDefinition{
		Name:    "EfmBondingGroupPerformanceMonitoringHistoryDataPart2",
		ClassID: 422,
		MessageTypes: mapset.NewSetWith(
			Create,
			Delete,
			Get,
			Set,
		),
		AllowedAttributeMask: 0XFFFC,
		AttributeDefinitions: AttributeDefinitionMap{
			0:  Uint16Field("ManagedEntityId", 0, mapset.NewSetWith(Read, SetByCreate), false, false, false, false, 0),
			1:  ByteField("IntervalEndTime", 0, mapset.NewSetWith(Read), false, false, false, false, 1),
			2:  Uint16Field("ThresholdData12Id", 0, mapset.NewSetWith(Read, SetByCreate, Write), false, false, false, false, 2),
			3:  Uint32Field("RxUnicastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 3),
			4:  Uint32Field("TxUnicastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 4),
			5:  Uint64Field("RxUnicastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 5),
			6:  Uint64Field("TxUnicastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 6),
			7:  Uint32Field("RxBroadcastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 7),
			8:  Uint32Field("TxBroadcastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 8),
			9:  Uint64Field("RxBroadcastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 9),
			10: Uint64Field("TxBroadcastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 10),
			11: Uint32Field("RxMulticastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 11),
			12: Uint32Field("TxMulticastFrames", 0, mapset.NewSetWith(Read), false, false, false, false, 12),
			13: Uint64Field("RxMulticastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 13),
			14: Uint64Field("TxMulticastBytes", 0, mapset.NewSetWith(Read), false, false, false, false, 14),
		},
	}
}

// NewEfmBondingGroupPerformanceMonitoringHistoryDataPart2 (class ID 422 creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from the wire, about to be sent on the wire.
func NewEfmBondingGroupPerformanceMonitoringHistoryDataPart2(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(efmbondinggroupperformancemonitoringhistorydatapart2BME, params...)
}
