/*
 * Copyright (c) 2018 - present.  Boling Consulting Solutions (bcsw.net)
 * Copyright 2020-present Open Networking Foundation
 *
 * 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"

// EquipmentExtensionPackageClassID is the 16-bit ID for the OMCI
// Managed entity Equipment extension package
const EquipmentExtensionPackageClassID = ClassID(160) // 0x00a0

var equipmentextensionpackageBME *ManagedEntityDefinition

// EquipmentExtensionPackage (Class ID: #160 / 0x00a0)
//	This ME supports optional extensions to circuit pack MEs. If the circuit pack supports these
//	features, the ONU creates and deletes this ME along with its associated real or virtual circuit
//	pack.
//
//	Relationships
//		An equipment extension package may be contained by an ONU-G or cardholder.
//
//	Attributes
//		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 ONU-G or cardholder. (R) (mandatory) (2-bytes)
//
//		Environmental Sense
//			This attribute provisions an ONU that supports external sense points, e.g., physical security
//			detectors at an enclosure. Each pair of bits is defined as follows.
//
//			00	Sense point disabled (default)
//
//			01	Report contact closure
//
//			10	Report contact open
//
//			11	Sense point disabled (same as 00)
//
//			If the byte is represented in binary as 0B hhgg ffee ddcc bbaa, bits hh correspond to sense
//			point 1, while bits aa correspond to sense point 8. (R,-W) (optional) (2-bytes)
//
//			NOTE - Some specific sense point applications are already defined on the ONU-G ME. It is the
//			vendor's choice how to configure and report sense points that appear both generically and
//			specifically.
//
//		Contact Closure Output
//			This attribute provisions an ONU that supports external contact closure outputs, e.g., sump pump
//			or air conditioner activation at an ONU enclosure. A contact point is said to be released when
//			it is not energized. Whether this corresponds to an open or a closed electrical circuit depends
//			on the ONU's wiring options. Upon ONU initialization, all contact points should go to the
//			released state.
//
//			If the byte is represented in binary as 0B hhgg ffee ddcc bbaa, bits hh correspond to contact
//			output point 1, while bits aa correspond to contact output point 8.
//
//			On write, the bits of this attribute have the following meaning.
//
//			0x	No change to contact output point state
//
//			10	Release contact output point
//
//			11	Operate contact output point
//
//			On read, the left bit in each pair should be set to 0 at the ONU and ignored at the OLT. The
//			right bit indicates a released output point with 0 and an operated contact point with 1. (R,-W)
//			(optional) (2-bytes)
//
type EquipmentExtensionPackage struct {
	ManagedEntityDefinition
	Attributes AttributeValueMap
}

// Attribute name constants

const EquipmentExtensionPackage_EnvironmentalSense = "EnvironmentalSense"
const EquipmentExtensionPackage_ContactClosureOutput = "ContactClosureOutput"

func init() {
	equipmentextensionpackageBME = &ManagedEntityDefinition{
		Name:    "EquipmentExtensionPackage",
		ClassID: EquipmentExtensionPackageClassID,
		MessageTypes: mapset.NewSetWith(
			Get,
			Set,
		),
		AllowedAttributeMask: 0xc000,
		AttributeDefinitions: AttributeDefinitionMap{
			0: Uint16Field(ManagedEntityID, PointerAttributeType, 0x0000, 0, mapset.NewSetWith(Read), false, false, false, 0),
			1: Uint16Field(EquipmentExtensionPackage_EnvironmentalSense, UnsignedIntegerAttributeType, 0x8000, 0, mapset.NewSetWith(Read, Write), false, true, false, 1),
			2: Uint16Field(EquipmentExtensionPackage_ContactClosureOutput, UnsignedIntegerAttributeType, 0x4000, 0, mapset.NewSetWith(Read, Write), false, true, false, 2),
		},
		Access:  CreatedByOnu,
		Support: UnknownSupport,
		Alarms: AlarmMap{
			0: "Reserved",
			1: "Sense point 1",
			2: "Sense point 2",
			3: "Sense point 3",
			4: "Sense point 4",
			5: "Sense point 5",
			6: "Sense point 6",
			7: "Sense point 7",
			8: "Sense point 8",
		},
	}
}

// NewEquipmentExtensionPackage (class ID 160) creates the basic
// Managed Entity definition that is used to validate an ME of this type that
// is received from or transmitted to the OMCC.
func NewEquipmentExtensionPackage(params ...ParamData) (*ManagedEntity, OmciErrors) {
	return NewManagedEntity(*equipmentextensionpackageBME, params...)
}
