Exemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="displayItem"></param>
        /// <returns></returns>
        override internal int TranslateDisplayAddress(SCSDisplayItem displayItem)
        {
            int nAddress;

            switch (displayItem.UpperAddress)
            {
            case 0x08: nAddress = (0x0100 | displayItem.LowerAddress);
                break;

            case 0x09: nAddress = (0x0200 | displayItem.LowerAddress);
                break;

            case 0x0A: nAddress = (0x0300 | displayItem.LowerAddress);
                break;

            case 0x0B: nAddress = (0x0400 | displayItem.LowerAddress);
                break;

            default:
                nAddress = displayItem.LowerAddress;
                break;
            }

            return(nAddress);
        }
Exemplo n.º 2
0
        /// <summary>
        /// This method returns a user viewable description for a given display item.  NOte that
        /// all derived device classes must override this method.  The base class implementation
        /// here is only provided as a debugging tool should a derived class not be able to
        /// successfully describe the given display item.
        /// </summary>
        /// <param name="displayItem">The display item </param>
        /// <returns>A string that describes the given display item
        /// </returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 12/07/06 mah 8.00.00  N/A   Created
        /// </remarks>
        virtual internal string GetDisplayItemDescription(SCSDisplayItem displayItem)
        {
            String strDescription;

            // The following list are special case display items that are common to all SCS devices

            if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.FixedBCD && displayItem.RegisterType == 0)
            {
                strDescription = "Segment Test";
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.DateValue && displayItem.LowerAddress == 0)
            {
                strDescription = "Current Date";
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.TimeValue && displayItem.LowerAddress == 0x06)
            {
                strDescription = "Current Time";
            }
            else
            {
                strDescription = "Class = " + displayItem.RegisterClass.ToString() +
                                 " Type = " + displayItem.RegisterType.ToString(CultureInfo.InvariantCulture) +
                                 " @ 0x" + TranslateDisplayAddress(displayItem).ToString("X", CultureInfo.InvariantCulture);
            }

            return(strDescription);
        }
Exemplo n.º 3
0
        /// <summary>
        /// This method returns a user viewable description for a given display item.
        /// </summary>
        /// <param name="displayItem">The display item </param>
        /// <returns>A string that describes the given display item
        /// </returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 12/07/06 mah 8.00.00  N/A   Created
        /// 03/09/07 mah 8.00.17           Added support for prs kW and prv kW even though they do not exist in a MT200
        /// 03/26/07 mah 8.00.21  2769  Added support for time remaining in demand subinterval - again this is not supported
        ///											   by the 200 series but could be in the display list
        /// </remarks>
        override internal string GetDisplayItemDescription(SCSDisplayItem displayItem)
        {
            String strDescription = "";

            if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.DemandValue)
            {
                if (displayItem.RegisterType == 1)
                {
                    strDescription = "prv kW";
                }
                else
                {
                    strDescription = "prs kW";
                }
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.TotalContinuousCumulativeValue)
            {
                if (displayItem.RegisterType == 0x07)
                {
                    strDescription = "Last Season ";
                }

                strDescription += "ccum " + DemandQuantity;

                // Add the TOU rate indeicator

                switch (displayItem.TOURate)
                {
                case 1: strDescription += " Rate A"; break;

                case 2: strDescription += " Rate B"; break;

                case 3: strDescription += " Rate C"; break;

                case 4: strDescription += " Rate D"; break;

                default: break;
                }
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.TimeValue && 0x48 == displayItem.LowerAddress)              // Time remaining in sub interval
            {
                strDescription = "Time Rem in Demand Subint";
            }
            else
            {
                strDescription = GetDisplayItemDescription(TranslateDisplayAddress(displayItem));
            }

            if (strDescription.Length == 0)
            {
                strDescription = base.GetDisplayItemDescription(displayItem);
            }

            return(strDescription);
        }
Exemplo n.º 4
0
        /// <summary>
        /// This method is responsible for either retrieving or calculating the continuous
        /// cummulative demand value associated with the given display item.  Note
        /// that in the CENTRON this value is simply read from the meter.
        /// </summary>
        /// <param name="displayItem">The display item to look up</param>
        /// <returns>A string representing the ccum value
        /// </returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 01/03/07 mah 8.00.00  N/A   Created
        /// </remarks>
        override internal String RetrieveCCumValue(SCSDisplayItem displayItem)
        {
            String strCCum = "";

            if (displayItem.RegisterType == 0) // current season
            {
                strCCum = ReadFloatingBCDValue(TranslateDisplayAddress(displayItem), 4);
            }
            else if (displayItem.RegisterType == 7) // last season
            {
                strCCum = ReadFloatingBCDValue(TranslateDisplayAddress(displayItem), 3);
            }

            return(strCCum);
        }
Exemplo n.º 5
0
        /// <summary>
        /// This method is responsible for retrieving the basepage address of any given
        /// meter display item - normal, alternate, or test mode
        /// </summary>
        /// <param name="displayItem">The display item to look up</param>
        /// <returns>An integer representing the associated basepage address
        /// </returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 12/07/06 mah 8.00.00  N/A   Created
        /// 03/26/07 mah 8.00.21  2769  Added support for time remaining in demand subinterval - this is not supported
        ///											   by the 200 series but could be in the display list
        /// </remarks>
        override internal int TranslateDisplayAddress(SCSDisplayItem displayItem)
        {
            int nAddress;

            if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.InstantaneousValue)
            {
                nAddress = 0;                                                                                                   // Instantaneous values apply to CENTRONs only - don't try to retrieve them
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.TimeValue && 0x48 == displayItem.LowerAddress) // Time remaining in sub interval
            {
                nAddress = 0x00;                                                                                                // This is a CENTRON only item - don't try to retrieve it either
            }
            else
            {
                switch (displayItem.UpperAddress)
                {
                case 0x01:
                    if (displayItem.LowerAddress == 0x0C)
                    {
                        nAddress = 0x00FF;                                 // Current day of week
                    }
                    else
                    {
                        nAddress = displayItem.LowerAddress;
                    }
                    break;

                case 0x08: nAddress = (0x0100 | displayItem.LowerAddress);
                    break;

                case 0x09: nAddress = (0x0200 | displayItem.LowerAddress);
                    break;

                case 0x0A: nAddress = (0x0300 | displayItem.LowerAddress);
                    break;

                case 0x0B: nAddress = (0x0400 | displayItem.LowerAddress);
                    break;

                default:
                    nAddress = displayItem.LowerAddress;
                    break;
                }
            }

            return(nAddress);
        }
Exemplo n.º 6
0
 /// <summary>
 /// This method is responsible for either retrieving or calculating the continuous
 /// cummulative demand value associated with the given display item.  Note
 /// that this method is not currently implemented and will throw an exception
 /// </summary>
 /// <param name="displayItem">The display item to look up</param>
 /// <returns>A string representing the ccum value
 /// </returns>
 /// <remarks >
 /// MM/DD/YY who Version Issue# Description
 /// -------- --- ------- ------ ---------------------------------------
 /// 01/03/07 mah 8.00.00  N/A   Created
 /// </remarks>
 override internal String RetrieveCCumValue(SCSDisplayItem displayItem)
 {
     throw (new NotImplementedException("Continuous cumulative display items are yet not implemented for this device"));
 }
Exemplo n.º 7
0
        /// <summary>
        /// This method is responsible for retrieving the basepage address of any given
        /// meter display item - normal, alternate, or test mode
        /// </summary>
        /// <param name="displayItem"></param>
        /// <returns></returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 12/07/06 mah 8.00.00  N/A   Created
        /// </remarks>
        override internal int TranslateDisplayAddress(SCSDisplayItem displayItem)
        {
            int nAddress = 0;

            // Handle present and previous demands separately

            if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.EnergyValue && displayItem.DisplayType == DisplayMode.TEST_MODE)
            {
                nAddress = 0x0119;
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.MaxDemandValue && displayItem.DisplayType == DisplayMode.TEST_MODE)
            {
                nAddress = 0x0124;
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.DemandValue)
            {
                if (displayItem.RegisterType == 0) // present demand
                {
                    nAddress = 0x0561;
                }
                else // Previous demand
                {
                    nAddress = 0x0565;
                }
            }
            else if (displayItem.RegisterClass == SCSDisplayItem.SCSDisplayClass.TotalContinuousCumulativeValue)
            {
                if (displayItem.RegisterType == 0) // current season
                {
                    switch (displayItem.TOURate)
                    {
                    case SCSDisplayItem.DISP_RATE_E: nAddress = 0x558; break;

                    case SCSDisplayItem.DISP_RATE_A: nAddress = 0x533; break;

                    case SCSDisplayItem.DISP_RATE_B: nAddress = 0x537; break;

                    case SCSDisplayItem.DISP_RATE_C: nAddress = 0x53B; break;

                    case SCSDisplayItem.DISP_RATE_D: nAddress = 0x53F; break;
                    }
                }
                else // last season
                {
                    switch (displayItem.TOURate)
                    {
                    case SCSDisplayItem.DISP_RATE_E: nAddress = 0x55C; break;

                    case SCSDisplayItem.DISP_RATE_A: nAddress = 0x543; break;

                    case SCSDisplayItem.DISP_RATE_B: nAddress = 0x546; break;

                    case SCSDisplayItem.DISP_RATE_C: nAddress = 0x549; break;

                    case SCSDisplayItem.DISP_RATE_D: nAddress = 0x54C; break;
                    }
                }
            }
            else if (0x0C == displayItem.UpperAddress)
            {
                nAddress = (0x0500 | displayItem.LowerAddress);
            }

            // If we were unable to determine the address at this point, the display item
            // must represent an item that is common to both the MT200 and the CENTRON
            // registers - call the base class to get its address

            if (0 == nAddress)
            {
                nAddress = base.TranslateDisplayAddress(displayItem);
            }

            return(nAddress);
        }
Exemplo n.º 8
0
        /// <summary>
        /// This method is responsible for calculating the continuous
        /// cummulative demand value associated with the given display item.  Note
        /// that the MT200 does not store this value so it must be calculated manually
        /// </summary>
        /// <param name="displayItem">The display item to look up</param>
        /// <returns>A string representing the ccum value
        /// </returns>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 01/03/07 mah 8.00.00  N/A   Created
        /// 03/07/07 mah 8.00.17  Implemented the method
        /// </remarks>
        override internal String RetrieveCCumValue(SCSDisplayItem displayItem)
        {
            // We need to calculate the ccum value ourselves and return it.

            int    nBCDLength;
            double dblCumDemand = 0.0;
            double dblMaxDemand = 0.0;
            int    nCumDemandRegisterAddress;
            int    nMaxDemandRegisterAddress;

            // Before reading the registers we have to take note of what type of register we are looking up
            // because last season registers are shorter than the current season registers - that's in addition
            // to being stored in completely different basepage addresses

            if (displayItem.RegisterType == 0x00)
            {
                switch (displayItem.TOURate)
                {
                case 1: nMaxDemandRegisterAddress = (int)MT2Addresses.RATEA_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.RATEA_CUM_KW;
                    break;

                case 2: nMaxDemandRegisterAddress = (int)MT2Addresses.RATEB_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.RATEB_CUM_KW;
                    break;

                case 3: nMaxDemandRegisterAddress = (int)MT2Addresses.RATEC_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.RATEC_CUM_KW;
                    break;

                case 4: nMaxDemandRegisterAddress = (int)MT2Addresses.RATED_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.RATED_CUM_KW;
                    break;

                default: nMaxDemandRegisterAddress = (int)MT2Addresses.RATEE_KW;
                    nCumDemandRegisterAddress      = (int)MT2Addresses.RATEE_CUM_KW;
                    break;
                }

                nBCDLength = 4;                 // All current registers are 4 bytes long
            }
            else
            {
                switch (displayItem.TOURate)
                {
                case 1: nMaxDemandRegisterAddress = (int)MT2Addresses.LAST_SEASON_RATEA_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.LAST_SEASON_CUM_RATEA;
                    break;

                case 2: nMaxDemandRegisterAddress = (int)MT2Addresses.LAST_SEASON_RATEB_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.LAST_SEASON_CUM_RATEB;
                    break;

                case 3: nMaxDemandRegisterAddress = (int)MT2Addresses.LAST_SEASON_RATEC_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.LAST_SEASON_CUM_RATEC;
                    break;

                case 4: nMaxDemandRegisterAddress = (int)MT2Addresses.LAST_SEASON_RATED_KW;
                    nCumDemandRegisterAddress     = (int)MT2Addresses.LAST_SEASON_CUM_RATED;
                    break;

                default: nMaxDemandRegisterAddress = (int)MT2Addresses.LAST_SEASON_RATEE_KW;
                    nCumDemandRegisterAddress      = (int)MT2Addresses.LAST_SEASON_CUM_RATEE;
                    break;
                }

                nBCDLength = 3;                 // All last season registers are 3 bytes long
            }

            // Now that we have the addresses of both the cummulative demand register and the maximum demand
            // register we can calculate continuous cummulative demand

            if (nCumDemandRegisterAddress != 0)
            {
                dblCumDemand = double.Parse(ReadFloatingBCDValue(nCumDemandRegisterAddress, nBCDLength), CultureInfo.CurrentCulture);
            }

            if (nMaxDemandRegisterAddress != 0)
            {
                dblMaxDemand = double.Parse(ReadFloatingBCDValue(nMaxDemandRegisterAddress, nBCDLength), CultureInfo.CurrentCulture);
            }

            double dblCCumDemand = dblCumDemand + dblMaxDemand;

            return(dblCCumDemand.ToString(CultureInfo.CurrentCulture));
        }
Exemplo n.º 9
0
 /// <summary>
 /// The MT200 does not have any previous demand values - however the CENTRON does and it
 /// is possible to program an MT200 with a CENTRON's display list.  This method must be overriden
 /// to prevent attempts to read memory locations that simply are not present in the 200.
 /// </summary>
 /// <returns></returns>
 /// <remarks >
 /// MM/DD/YY who Version Issue# Description
 /// -------- --- ------- ------ ---------------------------------------
 /// 03/09/07 mah 8.00.00  N/A   Created
 /// </remarks>
 override internal string ReadPreviousDemandValue(SCSDisplayItem displayItem)
 {
     return("");
 }
Exemplo n.º 10
0
        /// <summary>
        /// Returns a list of values currently shown on the meter's normal mode display
        /// </summary>
        /// <remarks >
        /// MM/DD/YY who Version Issue# Description
        /// -------- --- ------- ------ ---------------------------------------
        /// 12/05/06 mah 8.00.00  N/A   Created
        /// </remarks>
        virtual protected void ReadDisplayConfigurations()
        {
            byte[] byDisplayItem;
            SCSProtocolResponse ProtocolResponse;

            m_NormalDisplayList    = new List <DisplayItem>();
            m_AlternateDisplayList = new List <DisplayItem>();
            m_TestDisplayList      = new List <DisplayItem>();

            // All SCS devices MUST have at least one item in the normal display
            // list.  Read each of the items in the list until we reach either an end
            // of table indicator or we find the first item in the alternate display list

            int     nDisplayItemAddress = DisplayTableAddress;
            Boolean boolEndOfList       = false;

            m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Reading display table");

            while (!boolEndOfList)
            {
                // Read the entire display item from the meter

                ProtocolResponse = m_SCSProtocol.Upload(nDisplayItemAddress, SCS_DISPLAYITEM_LENGTH, out byDisplayItem);

                if (SCSProtocolResponse.SCS_ACK == ProtocolResponse)
                {
                    SCSDisplayItem displayItem = CreateDisplayItem(ref byDisplayItem, 0, false);

                    if (!displayItem.EndOfFIle)
                    {
                        if (displayItem.DisplayType == ItronDevice.DisplayMode.NORMAL_MODE)
                        {
                            m_NormalDisplayList.Add(displayItem);
                        }
                        else
                        {
                            m_AlternateDisplayList.Add(displayItem);
                        }

                        // set the address of the next item

                        nDisplayItemAddress += SCS_DISPLAYITEM_LENGTH;
                    }
                    else
                    {
                        boolEndOfList        = true;
                        nDisplayItemAddress += 1;  // The end of list is only one byte long - reset the address to point to the next item
                    }
                }
                else
                {
                    SCSException scsException = new SCSException(SCSCommands.SCS_U,
                                                                 ProtocolResponse, nDisplayItemAddress, "Display table item");

                    throw scsException;
                }
            }

            // The test mode list immediately follows the normal and alternate mode lists and has the same
            // format

            boolEndOfList = false;
            m_Logger.WriteLine(Logger.LoggingLevel.Detailed, "Reading test mode display table");

            while (!boolEndOfList)
            {
                // Read the entire display item from the meter

                ProtocolResponse = m_SCSProtocol.Upload(nDisplayItemAddress, SCS_DISPLAYITEM_LENGTH, out byDisplayItem);

                if (SCSProtocolResponse.SCS_ACK == ProtocolResponse)
                {
                    SCSDisplayItem displayItem = new SCSDisplayItem(ref byDisplayItem, 0, true);

                    if (!displayItem.EndOfFIle)
                    {
                        m_TestDisplayList.Add(displayItem);

                        // set the address of the next item

                        nDisplayItemAddress += SCS_DISPLAYITEM_LENGTH;
                    }
                    else
                    {
                        boolEndOfList = true;
                    }
                }
                else
                {
                    SCSException scsException = new SCSException(SCSCommands.SCS_U,
                                                                 ProtocolResponse, nDisplayItemAddress, "Test Mode display item");

                    throw scsException;
                }
            }
        }
Exemplo n.º 11
0
 /// <summary>
 ///
 /// </summary>
 /// <returns></returns>
 /// <remarks >
 /// MM/DD/YY who Version Issue# Description
 /// -------- --- ------- ------ ---------------------------------------
 /// 12/13/06 mah 8.00.00  N/A   Created
 /// </remarks>
 virtual internal string ReadPreviousDemandValue(SCSDisplayItem displayItem)
 {
     return(ReadFloatingBCDValue(TranslateDisplayAddress(displayItem), 4));
 }
Exemplo n.º 12
0
 /// <summary>
 /// This method is responsible for either retrieving or calculating the continuous
 /// cummulative demand value associated with the given display item.  Note
 /// that in some SCS devices this value is simply read from the meter yet in
 /// other cases, the value must be calculated from the cummulative and max
 /// demand values.  Since the actual implementation differs per device type, this
 /// method must be overriden for each derived device type
 /// </summary>
 /// <param name="displayItem">The display item to look up</param>
 /// <returns>A string representing the ccum value
 /// </returns>
 /// <remarks >
 /// MM/DD/YY who Version Issue# Description
 /// -------- --- ------- ------ ---------------------------------------
 /// 01/03/07 mah 8.00.00  N/A   Created
 /// </remarks>
 abstract internal String RetrieveCCumValue(SCSDisplayItem displayItem);
Exemplo n.º 13
0
 /// <summary>
 /// This method is responsible for retrieving the basepage address of any given
 /// meter display item - normal, alternate, or test mode.  SInce all basepage addresses
 /// are unique per meter type, this method is a pure abstract method.  Each
 /// derived meter class will have its own implementation
 /// </summary>
 /// <param name="displayItem">The display item to look up</param>
 /// <returns>An integer representing the associated basepage address
 /// </returns>
 /// <remarks >
 /// MM/DD/YY who Version Issue# Description
 /// -------- --- ------- ------ ---------------------------------------
 /// 12/07/06 mah 8.00.00  N/A   Created
 /// </remarks>
 abstract internal int TranslateDisplayAddress(SCSDisplayItem displayItem);