예제 #1
0
    void Start()
    {
        //get the renderer
        lineRenderer            = GetComponent <LineRenderer>();
        lineRenderer.startWidth = 0.1f;


        //calculate boundary constants
        ROne = h / 2;
        RTwo = (N * h) / 2;

        //spawn initial charge
        collisionPositions.Add(new Vector3(0, 0, 0));
        ChargePoint startingCharge = Instantiate(lightningNode, transform).GetComponent <ChargePoint>();


        startingCharge.potential = 26;//according to the reference material, 26 for the spawned charge, -1 for the other charges
        //changed to 17 to prevent upwards lightning

        if ((debugNodeType == DebugNodeTypes.ShowSpawned) || (debugNodeType == DebugNodeTypes.ShowAll))
        {
            startingCharge.mRenderer.enabled = true;
        }

        spawnedCharges.Add(startingCharge);
        //add surrounding candidate charges
        SpawnStartingOctantPreset(startingCharge);
    }
예제 #2
0
        public async Task Update(string locationId, IEnumerable <ChargePoint> chargePoints)
        {
            var requestIds = chargePoints.Select(x => x.ChargePointId);

            var existingIds = context.ChargePoints
                              .Where(x => x.LocationId == locationId)
                              .Select(x => x.ChargePointId)
                              .ToList();
            var newChargePoints    = chargePoints.Where(x => !existingIds.Contains(x.ChargePointId));
            var newChargePointsIds = newChargePoints.Select(x => x.ChargePointId);

            requestIds = requestIds.Where(x => !newChargePointsIds.Contains(x));

            var idsToDelete = existingIds.Where(x => !requestIds.Contains(x));

            foreach (var id in idsToDelete)
            {
                var chargePoint = new ChargePoint()
                {
                    ChargePointId = id, Status = "Deleted"
                };
                context.Attach(chargePoint);
                context.Entry(chargePoint).Property(x => x.Status).IsModified = true;
            }

            foreach (var chargePoint in chargePoints.Where(x => !idsToDelete.Contains(x.ChargePointId) &&
                                                           !newChargePointsIds.Contains(x.ChargePointId)))
            {
                context.Entry(chargePoint).State = EntityState.Modified;
            }

            await context.AddRangeAsync(newChargePoints);

            await context.SaveChangesAsync();
        }
예제 #3
0
        /// <summary>
        /// Determine if 2 CPs have the same location details or very close lat/lng
        /// </summary>
        /// <param name="current">  </param>
        /// <param name="previous">  </param>
        /// <returns>  </returns>
        public bool IsDuplicateLocation(ChargePoint current, ChargePoint previous, bool compareTitle)
        {
            //is duplicate item if latlon is exact match for previous item or latlon is within few meters of previous item
            if (
                (GeoManager.IsClose(current.AddressInfo.Latitude, current.AddressInfo.Longitude, previous.AddressInfo.Latitude, previous.AddressInfo.Longitude) && new System.Device.Location.GeoCoordinate(current.AddressInfo.Latitude, current.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(previous.AddressInfo.Latitude, previous.AddressInfo.Longitude)) < DUPLICATE_DISTANCE_METERS) || //meters distance apart
                (compareTitle && (previous.AddressInfo.Title == current.AddressInfo.Title))
                //&& previous.AddressInfo.AddressLine1 == current.AddressInfo.AddressLine1
                || (previous.AddressInfo.Latitude == current.AddressInfo.Latitude && previous.AddressInfo.Longitude == current.AddressInfo.Longitude) ||
                (current.DataProvidersReference != null && current.DataProvidersReference.Length > 0 && previous.DataProvidersReference == current.DataProvidersReference) ||
                (previous.AddressInfo.ToString() == current.AddressInfo.ToString())

                )
            {
                int dataProviderId = (previous.DataProvider != null ? previous.DataProvider.ID : (int)previous.DataProviderID);
                if (previous.AddressInfo.Latitude == current.AddressInfo.Latitude && previous.AddressInfo.Longitude == current.AddressInfo.Longitude)
                {
                    Log(current.AddressInfo.ToString() + " is Duplicate due to exact equal latlon to [Data Provider " + dataProviderId + "]" + previous.AddressInfo.ToString());
                }
                else if (new System.Device.Location.GeoCoordinate(current.AddressInfo.Latitude, current.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(previous.AddressInfo.Latitude, previous.AddressInfo.Longitude)) < DUPLICATE_DISTANCE_METERS)
                {
                    Log(current.AddressInfo.ToString() + " is Duplicate due to close proximity to [Data Provider " + dataProviderId + "]" + previous.AddressInfo.ToString());
                }
                else if (previous.AddressInfo.Title == current.AddressInfo.Title && previous.AddressInfo.AddressLine1 == current.AddressInfo.AddressLine1 && previous.AddressInfo.Postcode == current.AddressInfo.Postcode)
                {
                    Log(current.AddressInfo.ToString() + " is Duplicate due to same Title and matching AddressLine1 and Postcode  [Data Provider " + dataProviderId + "]" + previous.AddressInfo.ToString());
                }
                return(true);
            }
            else
            {
                return(false);
            }
        }
예제 #4
0
        private string FormatPOIHeading(ChargePoint poi)
        {
            string siteUrl = "https://openchargemap.org/site";
            var    html    = "<h3><a href='" + siteUrl + "/poi/details/" + poi.ID + "'>OCM-" + poi.ID + ": " + poi.AddressInfo.Title + " : " + poi.AddressInfo.ToString().Replace(",", ", ") + "</a></h3>";

            return(html);
        }
예제 #5
0
 /// <summary>
 /// Determine if 2 CPs have the same location details or very close lat/lng
 /// </summary>
 /// <param name="current"></param>
 /// <param name="previous"></param>
 /// <returns></returns>
 public bool IsDuplicateLocation(ChargePoint current, ChargePoint previous, bool compareTitle)
 {
     //is duplicate item if latlon is exact match for previous item or latlon is within few meters of previous item
     if (
         (compareTitle && (previous.AddressInfo.Title == current.AddressInfo.Title))
         //&& previous.AddressInfo.AddressLine1 == current.AddressInfo.AddressLine1
         || (previous.AddressInfo.Latitude == current.AddressInfo.Latitude && previous.AddressInfo.Longitude == current.AddressInfo.Longitude) ||
         (current.DataProvidersReference != null && current.DataProvidersReference.Length > 0 && previous.DataProvidersReference == current.DataProvidersReference) ||
         new System.Device.Location.GeoCoordinate(current.AddressInfo.Latitude, current.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(previous.AddressInfo.Latitude, previous.AddressInfo.Longitude)) < DUPLICATE_DISTANCE_METERS    //meters distance apart
         )
     {
         if (previous.AddressInfo.Latitude == current.AddressInfo.Latitude && previous.AddressInfo.Longitude == current.AddressInfo.Longitude)
         {
             System.Diagnostics.Debug.WriteLine(current.AddressInfo.ToString() + " is Duplicate due to exact equal latlon to " + previous.AddressInfo.ToString());
         }
         else if (new System.Device.Location.GeoCoordinate(current.AddressInfo.Latitude, current.AddressInfo.Longitude).GetDistanceTo(new System.Device.Location.GeoCoordinate(previous.AddressInfo.Latitude, previous.AddressInfo.Longitude)) < DUPLICATE_DISTANCE_METERS)
         {
             System.Diagnostics.Debug.WriteLine(current.AddressInfo.ToString() + " is Duplicate due to close proximity to " + previous.AddressInfo.ToString());
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }
예제 #6
0
 //Update the potential at all the candidate sites accordingto Eqn. 11.
 void StepThree(ChargePoint recentCharge)
 {
     foreach (ChargePoint i in candidateCharges)
     {
         i.potential = i.potential + (1 - (ROne / (recentCharge.potential)));///r = the potential from the point charge at step one
     }
 }
예제 #7
0
        /// <summary>
        /// Verifica el estado del medidor eléctrico y retorna una cadena con el ID del estado.
        /// </summary>
        /// <returns>
        ///     <list type="bullet">
        ///         <item>
        ///             <term>"-1"</term>
        ///             <description>Error de lectura.</description>
        ///         </item>
        ///         <item>
        ///             <term>"1"</term>
        ///             <description>Punto de carga lleno.</description>
        ///         </item>
        ///         <item>
        ///             <term>"2"</term>
        ///             <description>Requiere mantención.</description>
        ///         </item>
        ///         <item>
        ///             <term>"0"</term>
        ///             <description>Todo correcto.</description>
        ///         </item>
        ///     </list>
        /// </returns>
        private static string GetMeterState()
        {
            ElectricMeter _meter       = meter as ElectricMeter;
            ChargePoint   _chargePoint = station.ChargePoints[0];

            /* Los errores de lectura ocurren cuando hay más autos de los
             * que la estación permite tener, o  cuando está ocupando más
             * kw/h de los que tiene capacidad */
            if (_meter.CarsParked > _chargePoint.CarCapacity)
            {
                return("-1");
            }
            else if (_meter.KwhInUse > _chargePoint.KwhCapacity)
            {
                return("-1");
            }
            else if (_meter.RequiresMaintenance)
            {
                return("2");
            }
            else if (_meter.CarsParked == _chargePoint.CarCapacity)
            {
                return("1");
            }

            return("0");
        }
예제 #8
0
        public override void ParseBasicDetails(ChargePoint cp, XmlNode item)
        {
            //parse address info
            string[] loctitle = RemoveFormattingCharacters(item["name"].InnerText).Replace(" - ", "~").Replace(",", "~").Split('~');

            if (loctitle.Length == 1 && loctitle[0].Contains("-"))
            {
                loctitle = RemoveFormattingCharacters(item["name"].InnerText).Replace("-", "~").Replace(",", "~").Split('~');
            }
            cp.AddressInfo.Town = loctitle[0].Trim();

            if (loctitle[1].Contains(","))
            {
                string[] addressinfo = loctitle[1].Split(',');
                cp.AddressInfo.Title = addressinfo[0].Trim();
            }
            else
            {
                cp.AddressInfo.Title = loctitle[1].Trim();
            }

            if (loctitle.Length > 2)
            {
                cp.AddressInfo.AddressLine1 = loctitle[2].Trim();
                if (loctitle.Length > 4)
                {
                    cp.AddressInfo.StateOrProvince = loctitle[4].Trim();
                    cp.AddressInfo.AddressLine2    = loctitle[3].Trim();
                }
                else if (loctitle.Length > 3)
                {
                    cp.AddressInfo.StateOrProvince = loctitle[3].Trim();
                }
            }


            //parse description
            string descriptionText = item["description"].InnerText;

            cp.StatusType = ImportRefData.Status_Unknown;

            if (descriptionText.Contains("<p>Operational</p>"))
            {
                cp.StatusType = ImportRefData.Status_Operational;
            }

            if (descriptionText.Contains("<p>Undergoing engineering design</p>"))
            {
                cp.StatusType = ImportRefData.Status_PlannedForFuture;
            }

            if (descriptionText.Contains("<p>Out of Service</p>"))
            {
                cp.StatusType = ImportRefData.Status_NonOperational;
            }
            //cp.AddressInfo.AddressLine1 = ConvertUppercaseToTitleCase(RemoveFormattingCharacters(item["description"].InnerText));
        }
 public override void SetDataProviderDetails(ChargePoint cp, XmlNode item)
 {
     cp.DataProvider = new DataProvider()
     {
         ID = 22
     };                                                //CHAdeMO.com
     //invent unique id by hashing location title
     cp.DataProvidersReference = CalculateMD5Hash(RemoveFormattingCharacters(item["name"].InnerText));
 }
예제 #10
0
        public EVSE GetEVSEFromCP(ChargePoint cp)
        {
            EVSE e = new EVSE();

            e.Title     = cp.AddressInfo.Title;
            e.Latitude  = cp.AddressInfo.Latitude;
            e.Longitude = cp.AddressInfo.Longitude;

            return(e);
        }
예제 #11
0
    //Step 4 - Add the new candidate sites surrounding the growth site.
    void StepFour(ChargePoint chosenNode)
    {
        //get the recent spawned charge position
        Vector3 newPointPosition = chosenNode.transform.localPosition;

        Debug.Log(newPointPosition);

        //add charges based on a 3x3x3 octant
        List <ChargePoint> newCharges = new List <ChargePoint>();

        int jNum = 3;

        if (genType == GenerationTypes.SemiSphere)
        {
            jNum = 2;
        }

        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < jNum; j++)
            {
                for (int k = 0; k < 3; k++)
                {
                    Vector3 checkPos = newPointPosition + new Vector3(i - 1, j - 1, k - 1);
                    if (!collisionPositions.Contains(checkPos))
                    {
                        Vector3     pos       = checkPos + gameObject.transform.position;
                        ChargePoint newCharge = Instantiate(lightningNode, pos, Quaternion.identity, transform).GetComponent <ChargePoint>();
                        newCharge.chargePointRelativePosition = checkPos;
                        collisionPositions.Add(new Vector3(i - 1, j - 1, k - 1) + newPointPosition);
                        newCharges.Add(newCharge);
                        newCharge.parentCharge = chosenNode;

                        //visualisation
                        if (debugDrawnLineType == DrawnLineTypes.DrawAll)
                        {
                            Debug.DrawLine(chosenNode.transform.position, pos, Color.black, 999.0f);
                        }
                        if (debugNodeType == DebugNodeTypes.ShowAll)
                        {
                            newCharge.mRenderer.enabled = true;
                        }
                    }
                    else
                    {
                        //Debug.Log("NodeOverlap");
                    }
                }
            }
        }


        StepFive(newCharges);
    }
예제 #12
0
    void SpawnStartingOctantPreset(ChargePoint spawnCharge)
    {
        //get the recent spawned charge position
        Vector3 newPointPosition = new Vector3(0, 0, 0);

        //add charges based on a 3x3x3 octant
        List <ChargePoint> newCharges = new List <ChargePoint>();

        int jNum = 3;

        if (genType == GenerationTypes.SemiSphere)
        {
            jNum = 2;
        }

        for (int i = 0; i < 3; i++)         //x
        {
            for (int j = 0; j < jNum; j++)  //y
            {
                for (int k = 0; k < 3; k++) //z
                {
                    Vector3 checkPos = newPointPosition + new Vector3(i - 1, j - 1, k - 1);
                    if (newPointPosition != checkPos)
                    {
                        Vector3     pos       = checkPos + gameObject.transform.position;
                        ChargePoint newCharge = Instantiate(lightningNode, pos, Quaternion.identity, transform).GetComponent <ChargePoint>();
                        newCharge.chargePointRelativePosition = checkPos;
                        collisionPositions.Add(new Vector3(i - 1, j - 1, k - 1));
                        newCharges.Add(newCharge);
                        newCharge.potential    = -1;
                        newCharge.parentCharge = spawnCharge;

                        if (genType == GenerationTypes.BranchingRotation)
                        {
                        }

                        //visualisation
                        if (debugDrawnLineType == DrawnLineTypes.DrawAll)
                        {
                            Debug.DrawLine(gameObject.transform.position, pos, Color.black, 999.0f);
                        }

                        if (debugNodeType == DebugNodeTypes.ShowAll)
                        {
                            newCharge.mRenderer.enabled = true;
                        }
                    }
                }
            }
        }
        StepFive(newCharges);
    }
예제 #13
0
        public async Task <ActionResult> Edit(int?id, bool createCopy = false)
        {
            ViewBag.IsReadOnlyMode = this.IsReadOnlyMode;

            if (id > 0)
            {
                ChargePoint poi = null;

                if (createCopy)
                {
                    //get version of POI with location details removed, copying equipment etc
                    poi = await new POIManager().GetCopy((int)id, true);
                }
                else
                {
                    poi = await new POIManager().Get((int)id);
                }

                if (poi != null)
                {
                    InitEditReferenceData(poi);

                    var refData = new POIBrowseModel(GetCoreReferenceData());
                    ViewBag.ReferenceData    = refData;
                    ViewBag.HideAdvancedInfo = true;

                    if (!createCopy)
                    {
                        try
                        {
                            var user = new UserManager().GetUser((int)UserID);
                            if (POIManager.CanUserEditPOI(poi, user))
                            {
                                ViewBag.HideAdvancedInfo = false;
                            }
                        }
                        catch (Exception)
                        {
                            ;;  //user not signed in
                        }
                    }

                    //enable advanced edit options for full editors/admin
                    return(View(poi));
                }
            }

            //no applicable poi, jump back to browse
            return(RedirectToAction("Index", "POI"));
        }
        public override void ParseBasicDetails(ChargePoint cp, XmlNode item)
        {
            cp.AddressInfo.Title = RemoveFormattingCharacters(item["name"].InnerText);
            string sourcetext = item["description"].InnerText;

            if (ImportType == ChademoImportType.Japan)
            {
                int indexOfTelephone = sourcetext.IndexOf("[");
                cp.AddressInfo.AddressLine1      = sourcetext.Substring(0, indexOfTelephone).Trim();
                cp.AddressInfo.ContactTelephone1 = sourcetext.Substring(indexOfTelephone + 5, sourcetext.IndexOf("]") - (indexOfTelephone + 5));
            }
            else
            {
                cp.AddressInfo.AddressLine1 = ConvertUppercaseToTitleCase(RemoveFormattingCharacters(item["description"].InnerText));
            }
        }
예제 #15
0
    //returns a path from a selected node to the first lightning spawned
    List <ChargePoint> getLightningPathFromNode(ChargePoint aNode)
    {
        List <ChargePoint> lightningList = new List <ChargePoint>();

        lightningList.Add(aNode);

        ChargePoint currentNode;

        currentNode = aNode;
        while (currentNode.parentCharge != null)
        {
            currentNode = currentNode.parentCharge;
            lightningList.Add(currentNode);
        }
        return(lightningList);
    }
예제 #16
0
        /// <summary>
        /// PutLocation method
        /// </summary>
        /// <param name="entity"></param>
        /// <returns></returns>
        public async Task <ChargePoint> PutLocation(ChargePointRequestModel entity)
        {
            var stationsById = await _chargingStationsDbContext.ChargePoints
                               .Where(x => x.LocationId == entity.LocationId)
                               .ToListAsync();

            if (!stationsById.Any() || !entity.ChargePoints.Any())
            {
                return(new ChargePoint());
            }
            {
                ChargePoint updatedStation = null;
                updatedStation = await UpdateStation(entity, stationsById, updatedStation);

                return(updatedStation);
            }
        }
예제 #17
0
        public static bool IsPOIValidForImport(ChargePoint poi, bool includeCountryValidation = false)
        {
            if (poi == null)
            {
                return(false);
            }
            if (poi.AddressInfo == null)
            {
                return(false);
            }
            if (String.IsNullOrEmpty(poi.AddressInfo.Title))
            {
                return(false);
            }
            if (String.IsNullOrEmpty(poi.AddressInfo.AddressLine1) && String.IsNullOrEmpty(poi.AddressInfo.Postcode))
            {
                return(false);
            }
            if (poi.AddressInfo.Latitude == 0 || poi.AddressInfo.Longitude == 0)
            {
                return(false);
            }

            if (poi.AddressInfo.Latitude < -90 || poi.AddressInfo.Latitude > 90)
            {
                return(false);
            }
            if (poi.AddressInfo.Longitude < -180 || poi.AddressInfo.Longitude > 180)
            {
                return(false);
            }

            if (poi.Connections == null || !poi.Connections.Any())
            {
                return(false);
            }
            if (poi.AddressInfo.Title.Contains("????"))
            {
                return(false);                                        //imports with invalid character encoding
            }
            if (includeCountryValidation && (poi.AddressInfo.CountryID == null && poi.AddressInfo.Country == null))
            {
                return(false);
            }
            return(true);
        }
예제 #18
0
    void DrawBranches(ChargePoint p, int branchDepth)
    {
        int renderNode = renderedBranchesPerNode;

        foreach (ChargePoint ps in p.childSpawnedCharges)
        {
            if (renderNode > 0)
            {
                renderNode--;
                Debug.DrawLine(p.transform.position, ps.transform.position, Color.black, 999.0f);
                if (branchDepth > 0)
                {
                    branchDepth--;
                    DrawBranches(p, branchDepth);
                }
            }
        }
    }
예제 #19
0
        private void InitEditReferenceData(ChargePoint poi)
        {
            //edit/preview may not have some basic info we need for further edits such as a default connectioninfo object
            if (poi.Connections == null)
            {
                poi.Connections = new List <OCM.API.Common.Model.ConnectionInfo>();
            }

            if (poi.Connections.Count == 0)
            {
                poi.Connections.Add(new OCM.API.Common.Model.ConnectionInfo());
            }

            //urls require at least http:// prefix
            if (poi.AddressInfo.RelatedURL != null && poi.AddressInfo.RelatedURL.Trim().Length > 0 && !poi.AddressInfo.RelatedURL.Trim().StartsWith("http"))
            {
                poi.AddressInfo.RelatedURL = "http://" + poi.AddressInfo.RelatedURL;
            }
        }
예제 #20
0
        public bool UpdatePOI(ChargePoint cp, APICredentials credentials)
        {
            //TODO: implement batch update based on item list?
            try
            {
                string url = ServiceBaseURL + "?action=cp_submission&format=json";
                url += "&Identifier=" + credentials.Identifier;
                url += "&SessionToken=" + credentials.SessionToken;

                string json   = JsonConvert.SerializeObject(cp);
                string result = PostDataToURL(url, json);
                return(true);
            }
            catch (Exception)
            {
                //update failed
                System.Diagnostics.Debug.WriteLine("Update Item Failed: {" + cp.ID + ": " + cp.AddressInfo.Title + "}");
                return(false);
            }
        }
예제 #21
0
        public List <ChargePoint> FindSimilar(ChargePoint cp, int MinimumPercentageSimilarity)
        {
            List <ChargePoint> results = new List <ChargePoint>();

            try
            {
                string url = ServiceBaseURL + "?output=json&action=getsimilarchargepoints";

                string             json       = JsonConvert.SerializeObject(cp);
                string             resultJSON = PostDataToURL(url, json);
                JObject            o          = JObject.Parse("{\"root\": " + resultJSON + "}");
                JsonSerializer     serializer = new JsonSerializer();
                List <ChargePoint> c          = (List <ChargePoint>)serializer.Deserialize(new JTokenReader(o["root"]), typeof(List <ChargePoint>));
                return(c);
            }
            catch (Exception)
            {
                //failed!
                return(null);
            }
        }
예제 #22
0
        public override void ParseAdditionalData(ChargePoint cp, XmlNode item, CoreReferenceData coreRefData)
        {
            string descriptionText = item["description"].InnerText;

            if (descriptionText.Contains("<p>24 hour access</p>"))
            {
                cp.AddressInfo.AccessComments = "24 Hour Access";
            }
            if (descriptionText.Contains("Business hours only"))
            {
                cp.AddressInfo.AccessComments = "Business Hours Only";
            }

            if (descriptionText.Contains("Please contact the host premises"))
            {
                cp.UsageType = ImportRefData.UsageType_PublicNoticeRequired;
            }

            //attempt country match for locations which commonly have geocoding issues
            switch (cp.AddressInfo.Town.Trim())
            {
            case "Cork":
            case "Dublin":
            case "Meath":
            case "Waterford":
            case "Wicklow":
            case "Clare":
            case "Galway":
            case "Kerry":
            case "Wexford":
                cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode == "IE");
                break;

            case "Antrim":
            case "Derry":
                cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode == "GB");
                break;
            }
        }
예제 #23
0
        public IEnumerable <OCM.API.Common.Model.ChargePoint> FromOCPI(IEnumerable <OCM.Model.OCPI.Location> source)
        {
            var output = new List <ChargePoint>();

            foreach (var i in source)
            {
                var iso2Code = GetCountryCodeFromISO3(i.Country);

                var cp = new ChargePoint
                {
                    DataProvidersReference = i.Id,
                    AddressInfo            = new AddressInfo
                    {
                        Title        = i.Name,
                        AddressLine1 = i.Address,
                        Town         = i.City,
                        // i.Charging_when_closed
                        //i.AdditionalProperties
                        Latitude       = double.Parse(i.Coordinates.Latitude),
                        Longitude      = double.Parse(i.Coordinates.Longitude),
                        CountryID      = _coreReferenceData.Countries.FirstOrDefault(c => c.ISOCode == iso2Code)?.ID,
                        AccessComments = i.Directions?.Select(d => d.Text).ToString()
                    }
                };

                if (i.AdditionalProperties.ContainsKey("evses"))
                {
                    List <OCM.Model.OCPI.EVSE> evse = (List <OCM.Model.OCPI.EVSE>)(i.AdditionalProperties["evses"]);

                    foreach (var e in evse)
                    {
                        //TODO:
                    }
                }
                output.Add(cp);
            }
            return(output);
        }
예제 #24
0
    void Laplace()
    {
        //Step 1
        //weigh all nodes, then randomly select one according to a weighting
        //http://gamma.cs.unc.edu/FRAC/laplacian_large.pdf
        //Step 2
        //Add a new point charge at the growth site.
        //Step 3
        //Update the potential at all the candidate sites accordingto Eqn. 11.
        //Step 4 -> 5
        //Add the new candidate sites surrounding the growth site.
        //Calculate the potential at new candidate sites  Eqn. 10
        if (numberspawned < maxNumberspawned)
        {
            Debug.Log(candidateCharges.Count);

            ChargePoint chosenNode = StepOne();
            StepTwo(chosenNode);
            StepThree(chosenNode);
            numberspawned++;
            Debug.Log(chosenNode.transform.localPosition);
            StepFour(chosenNode);
        }
    }
예제 #25
0
    //add the selected node to the spawned category
    ChargePoint StepTwo(ChargePoint newNode)
    {
        candidateCharges.Remove(newNode);

        newNode.parentCharge.childSpawnedCharges.Add(newNode);

        //change the node to completed node
        newNode.mRenderer.material.color = Color.yellow;
        newNode.transform.localScale     = Vector3.one;
        spawnedCharges.Add(newNode);

        //visualisation
        if (debugDrawnLineType == DrawnLineTypes.DrawSpawned)
        {
            Debug.DrawLine(newNode.transform.position, newNode.parentCharge.transform.position, Color.black, 999.0f);
        }

        if (debugNodeType == DebugNodeTypes.ShowSpawned)
        {
            newNode.mRenderer.enabled = true;
        }

        return(newNode);
    }
        /// <summary>
        /// Crea una estación y un punto de carga de prueba para testear el medidor.
        /// </summary>
        private static void CreateStation()
        {
            int          _id          = Convert.ToInt32(ConfigurationManager.AppSettings["default-station-id"]);
            int          _carCapacity = Convert.ToInt32(ConfigurationManager.AppSettings["default-station-car-capacity"]);
            float        _kwhCapacity = float.Parse(ConfigurationManager.AppSettings["default-station-kwh-capacity"]);
            ConsoleColor _listColor   = ConsoleColor.Cyan;

            ChargePoint cp = new ChargePoint()
            {
                Id          = 0,
                CarCapacity = _carCapacity,
                KwhCapacity = _kwhCapacity,
                Type        = ChargePointType.ELECTRICO,
            };

            List <ChargePoint> cpList = new List <ChargePoint>();

            cpList.Add(cp);

            station = new Station()
            {
                Id = _id,
                ChargePointCapacity = 1,
                ChargePoints        = cpList,
            };

            Console.WriteLine("Por defecto, se crea una estación de pruebas.");
            Console.WriteLine("Estos son sus propiedades:");
            ConsoleUtils.WriteWithColor("ID: ", _listColor);
            Console.WriteLine(station.Id);
            ConsoleUtils.WriteWithColor("Capacidad: ", _listColor);
            Console.WriteLine(string.Format("{0} punto/s de carga\n", station.ChargePointCapacity));
            Console.WriteLine("Propiedades del punto de carga:");
            ConsoleUtils.WriteWithColor("Capacidad: ", _listColor);
            Console.WriteLine(string.Format("{0} autos y {1} kw/h \n", cp.CarCapacity, cp.KwhCapacity));
        }
예제 #27
0
        /// <summary>
        /// UpdateStation method
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="stationsById"></param>
        /// <param name="updatedStation"></param>
        /// <returns></returns>
        private async Task <ChargePoint> UpdateStation(ChargePointRequestModel entity, List <ChargePoint> stationsById, ChargePoint updatedStation)
        {
            foreach (var item in stationsById)
            {
                var currentStation = entity.ChargePoints.FirstOrDefault(x => x.ChargePointId == item.ChargePointId);
                if (currentStation == null)
                {
                    updatedStation        = item;
                    updatedStation.Status = "Removed";
                }
                else
                {
                    updatedStation = new ChargePoint
                    {
                        ChargePointId = currentStation.ChargePointId,
                        FloorLevel    = currentStation.FloorLevel,
                        Status        = currentStation.Status,
                        LastUpdated   = DateTime.Now,
                        LocationId    = entity.LocationId
                    };
                }

                var local = _chargingStationsDbContext.Set <ChargePoint>().Local
                            .FirstOrDefault(entry => entry.ChargePointId.Equals(updatedStation.ChargePointId));

                if (local != null)
                {
                    _chargingStationsDbContext.Entry(local).State = EntityState.Detached;
                }

                _chargingStationsDbContext.Entry(updatedStation).State = EntityState.Modified;
                await _chargingStationsDbContext.SaveChangesAsync();
            }

            return(updatedStation);
        }
예제 #28
0
        public List <API.Common.Model.ChargePoint> Process(API.Common.Model.CoreReferenceData coreRefData)
        {
            List <ChargePoint> outputList = new List <ChargePoint>();

            string importMappingJSON = "{ID:0,LocationTitle:1, AddressLine1:2,	AddressLine2:3,	Town:4,	StateOrProvince:5,	Postcode:6,	Country:7,	Latitude:8,	Longitude:9,Addr_ContactTelephone1:10,	Addr_ContactTelephone2:11,	Addr_ContactEmail:12,	Addr_AccessComments:13,	Addr_GeneralComments:14,	Addr_RelatedURL:15,	UsageType:16,	NumberOfPoints:17,	GeneralComments:18,	DateLastConfirmed:19,	StatusType:20,	DateLastStatusUpdate:21,	UsageCost:22,	Connection1_Type:23,	Connection1_Amps:24,	Connection1_Volts:25,	Connection1_Level:26,	Connection1_Quantity:27,	Connection2_Type:28,	Connection2_Amps:29,	Connection2_Volts:30,	Connection2_Level:31,	Connection2_Quantity:32,	Connection3_Type:33,	Connection3_Amps:34,	Connection3_Volts:35,	Connection3_Level:36,	Connection3_Quantity:37}";

            if (ImportFormat == ExcelTemplateFormat.FormatV2)
            {
                importMappingJSON = "{ID:0,LocationTitle:1, AddressLine1:2,	AddressLine2:3,	Town:4,	StateOrProvince:5,	Postcode:6,	Country:7,	Latitude:8,	Longitude:9,Addr_ContactTelephone1:10,	Addr_ContactTelephone2:11,	Addr_ContactEmail:12,	Addr_AccessComments:13,	Addr_GeneralComments:14,	Addr_RelatedURL:15,	UsageType:16,	NumberOfPoints:17,	GeneralComments:18,	DateLastConfirmed:19,	StatusType:20,	DateLastStatusUpdate:21,	UsageCost:22, Operator:23, 	Connection1_Type:24,	Connection1_kW:25, Connection1_Amps:26,	Connection1_Volts:27,	Connection1_Level:28,	Connection1_Quantity:29,	Connection2_Type:30,	Connection2_kW:31, Connection2_Amps:32,	Connection2_Volts:33,	Connection2_Level:34,	Connection2_Quantity:35,	Connection3_Type:36,  Connection3_kW:37,	Connection3_Amps:38,	Connection3_Volts:39,	Connection3_Level:40,	Connection3_Quantity:41,Connection4_Type:42,  Connection4_kW:43,	Connection4_Amps:44,	Connection4_Volts:45,	Connection4_Level:46,	Connection4_Quantity:47,Connection5_Type:48,  Connection5_kW:49,	Connection5_Amps:50,	Connection5_Volts:51,	Connection5_Level:52,	Connection5_Quantity:53,Connection6_Type:54,  Connection6_kW:55,	Connection6_Amps:56,	Connection6_Volts:57,	Connection6_Level:58,	Connection6_Quantity:58, POI_Types:59}";
            }
            //get import column mappings from JSON format config item into a Dictionary
            IDictionary <string, JToken> tmpMap = JObject.Parse(importMappingJSON);
            Dictionary <string, int>     lookup = tmpMap.ToDictionary(pair => pair.Key, pair => (int)pair.Value);

            try
            {
                //Open the Excel workbook.
                //example: http://msdn.microsoft.com/library/dd920313.aspx
                using (SpreadsheetDocument document = SpreadsheetDocument.Open(this.InputPath, false))
                {
                    //References to the workbook and Shared String Table.
                    var workBook      = document.WorkbookPart.Workbook;
                    var workSheets    = workBook.Descendants <Sheet>();
                    var sharedStrings = document.WorkbookPart.SharedStringTablePart.SharedStringTable;

                    var docProperties = document.PackageProperties;

                    //fetch first sheet in workbook
                    var importSheetID = workSheets.First().Id;
                    var importSheet   = (WorksheetPart)document.WorkbookPart.GetPartById(importSheetID);

                    Row         headerRow   = importSheet.RootElement.Descendants <Row>().First(r => r.RowIndex == 1);
                    List <Cell> headerCells = headerRow.Descendants <Cell>().ToList();

                    //LINQ query to skip first row with column names.
                    IEnumerable <Row> dataRows =
                        from row in importSheet.RootElement.Descendants <Row>()
                        where row.RowIndex > 1
                        select row;

                    int sourceRowIndex = 0;
                    foreach (Row row in dataRows)
                    {
                        sourceRowIndex++;
                        ChargePoint import = new ChargePoint();
                        try
                        {
                            List <Cell> cellList = row.Elements <Cell>().ToList();

                            var col = new string[headerCells.Count];
                            for (int i = 0; i < col.Length; i++)
                            {
                                string headerCellref = Regex.Replace(headerCells[i].CellReference.Value, @"[\d-]", string.Empty);
                                //if cell has value, populate array position
                                var cell = cellList.FirstOrDefault(c => c.CellReference.Value == (headerCellref + (sourceRowIndex + 1)));
                                if (cell != null)
                                {
                                    col[i] = (cell.DataType != null && cell.DataType.HasValue && cell.DataType == CellValues.SharedString ? sharedStrings.ChildElements[int.Parse(cell.CellValue.InnerText)].InnerText : (cell.CellValue != null ? cell.CellValue.InnerText : null));
                                }
                                else
                                {
                                    //empty cell
                                }
                            }

                            if (col.Any(t => t != null))
                            {
                                //load import row values from value in worksheet row
                                import.DataProvidersReference = col[lookup["ID"]];
                                import.DataQualityLevel       = 3;

                                if (this.DefaultDataProvider != null)
                                {
                                    import.DataProvider = DefaultDataProvider;
                                }

                                /*try
                                 * {
                                 *  importRow.DateLastConfirmed = DateTime.FromOADate(
                                 *      Double.Parse(
                                 *          textArray[importMappings["DateLastConfirmed"]]
                                 *      )
                                 *      ); //excel date is a double value (from OLE Automation) in days since 1900/1/1
                                 * }
                                 */

                                import.DataProviderID              = (int)StandardDataProviders.OpenChargeMapContrib;
                                import.AddressInfo                 = new AddressInfo();
                                import.AddressInfo.Title           = col[lookup["LocationTitle"]];
                                import.AddressInfo.AddressLine1    = col[lookup["AddressLine1"]];
                                import.AddressInfo.AddressLine2    = col[lookup["AddressLine2"]];
                                import.AddressInfo.Town            = col[lookup["Town"]];
                                import.AddressInfo.StateOrProvince = col[lookup["StateOrProvince"]];
                                import.AddressInfo.Postcode        = col[lookup["Postcode"]];

                                if (string.IsNullOrEmpty(import.AddressInfo.AddressLine1) && string.IsNullOrEmpty(import.AddressInfo.Postcode))
                                {
                                    import.AddressCleaningRequired = true;
                                }

                                var country = col[lookup["Country"]];
                                import.AddressInfo.CountryID = coreRefData.Countries.FirstOrDefault(c => c.Title.Equals(country, StringComparison.InvariantCultureIgnoreCase))?.ID;

                                import.AddressInfo.ContactTelephone1 = col[lookup["Addr_ContactTelephone1"]];
                                import.AddressInfo.ContactTelephone2 = col[lookup["Addr_ContactTelephone2"]];
                                import.AddressInfo.ContactEmail      = col[lookup["Addr_ContactEmail"]];
                                import.AddressInfo.RelatedURL        = col[lookup["Addr_RelatedURL"]];

                                import.GeneralComments = col[lookup["GeneralComments"]];

                                if (!String.IsNullOrEmpty(import.AddressInfo.RelatedURL) && !import.AddressInfo.RelatedURL.StartsWith("http"))
                                {
                                    import.AddressInfo.RelatedURL = "http://" + import.AddressInfo.RelatedURL;
                                }

                                string countryName = col[lookup["Country"]];
                                import.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.Title == countryName);

                                //latitude
                                try
                                {
                                    import.AddressInfo.Latitude = double.Parse(col[lookup["Latitude"]]);
                                }
                                catch (Exception exp)
                                {
                                    //failed to parse value
                                    throw exp;
                                }

                                //longitude
                                try
                                {
                                    import.AddressInfo.Longitude = double.Parse(col[lookup["Longitude"]]);
                                }
                                catch (Exception exp)
                                {
                                    //failed to parse value
                                    throw exp;
                                }

                                //Usage type
                                var usageCol = col[lookup["UsageType"]];
                                if (!String.IsNullOrWhiteSpace(usageCol))
                                {
                                    var usageType = coreRefData.UsageTypes.FirstOrDefault(u => u.Title == usageCol);
                                    if (usageType != null)
                                    {
                                        import.UsageTypeID = usageType.ID;
                                    }
                                    else
                                    {
                                        Log("Unknown usage type: " + usageCol);
                                    }
                                }

                                //status type
                                var statusCol = col[lookup["StatusType"]];
                                if (!String.IsNullOrWhiteSpace(statusCol))
                                {
                                    var statusType = coreRefData.StatusTypes.FirstOrDefault(u => u.Title == statusCol);
                                    if (statusType != null)
                                    {
                                        import.StatusTypeID = statusType.ID;
                                    }
                                    else
                                    {
                                        Log("Unknown status type: " + statusCol);
                                    }
                                }

                                //number of points
                                if (!String.IsNullOrWhiteSpace(col[lookup["NumberOfPoints"]]))
                                {
                                    import.NumberOfPoints = int.Parse(col[lookup["NumberOfPoints"]]);
                                }

                                // Operator
                                var operatorCol = col[lookup["Operator"]];
                                if (!String.IsNullOrWhiteSpace(operatorCol))
                                {
                                    var operatorInfo = coreRefData.Operators.FirstOrDefault(u => u.Title.StartsWith(operatorCol, StringComparison.InvariantCultureIgnoreCase));
                                    if (operatorInfo != null)
                                    {
                                        import.OperatorID = operatorInfo.ID;
                                    }
                                    else
                                    {
                                        Log("Unknown Operator: " + operatorCol);
                                    }
                                }

                                //TODO: parse POI_Types (Parking Lot)
                                //poi type metadata:
                                var poiCol = lookup["POI_Types"];

                                if (col.Length >= poiCol)
                                {
                                    var poiTypeCol = col[poiCol];
                                    if (!String.IsNullOrWhiteSpace(poiTypeCol))
                                    {
                                        import.MetadataValues = new List <MetadataValue>();

                                        var vals = poiTypeCol.Split(',');
                                        foreach (var p in vals)
                                        {
                                            if (p == "Parking Lot")
                                            {
                                                import.MetadataValues.Add(new MetadataValue {
                                                    MetadataFieldID = (int)StandardMetadataFields.POIType, MetadataFieldOptionID = (int)StandardMetadataFieldOptions.Parking
                                                });
                                            }
                                            else
                                            {
                                                Log("Unknown POI type:" + p);
                                            }
                                        }
                                    }
                                }
                                if (import.Connections == null)
                                {
                                    import.Connections = new List <ConnectionInfo>();
                                }

                                //connection info 1
                                int maxConnections = 6;
                                for (int i = 1; i <= maxConnections; i++)
                                {
                                    try
                                    {
                                        var conn = new ConnectionInfo();
                                        var connectionTypeCol = col[lookup["Connection" + i + "_Type"]];
                                        if (!String.IsNullOrWhiteSpace(connectionTypeCol))
                                        {
                                            connectionTypeCol = connectionTypeCol.Trim();
                                            if (connectionTypeCol == "Mennekes")
                                            {
                                                conn.ConnectionTypeID = (int)StandardConnectionTypes.MennekesType2;
                                                conn.CurrentTypeID    = (int)StandardCurrentTypes.SinglePhaseAC;
                                            }
                                            else if (connectionTypeCol == "CCS2")
                                            {
                                                conn.ConnectionTypeID = (int)StandardConnectionTypes.CCSComboType2;
                                                conn.CurrentTypeID    = (int)StandardCurrentTypes.DC;
                                            }
                                            else if (connectionTypeCol == "CEE 7/4 - Schuko - Type F")
                                            {
                                                conn.ConnectionTypeID = (int)StandardConnectionTypes.Schuko;
                                                conn.CurrentTypeID    = (int)StandardCurrentTypes.SinglePhaseAC;
                                            }
                                            else
                                            {
                                                var connectiontype = coreRefData.ConnectionTypes.FirstOrDefault(c => c.Title == col[lookup["Connection1_Type"]]);
                                                if (connectiontype != null)
                                                {
                                                    conn.ConnectionTypeID = connectiontype.ID;
                                                }
                                                else
                                                {
                                                    Log("Failed to match connection type:" + col[lookup["Connection" + i + "_Type"]]);
                                                }
                                            }
                                        }

                                        if (!String.IsNullOrWhiteSpace(col[lookup["Connection" + i + "_kW"]]))
                                        {
                                            conn.PowerKW = double.Parse(col[lookup["Connection" + i + "_kW"]]);
                                        }

                                        if (!String.IsNullOrWhiteSpace(col[lookup["Connection" + i + "_Amps"]]))
                                        {
                                            conn.Amps = int.Parse(col[lookup["Connection" + i + "_Amps"]]);
                                        }

                                        if (!String.IsNullOrWhiteSpace(col[lookup["Connection" + i + "_Volts"]]))
                                        {
                                            conn.Voltage = int.Parse(col[lookup["Connection" + i + "_Volts"]]);
                                        }

                                        if (!String.IsNullOrWhiteSpace(col[lookup["Connection" + i + "_Level"]]))
                                        {
                                            conn.LevelID = int.Parse(col[lookup["Connection" + i + "_Level"]]);
                                        }

                                        if (!String.IsNullOrWhiteSpace(col[lookup["Connection" + i + "_Quantity"]]))
                                        {
                                            conn.Quantity = int.Parse(col[lookup["Connection" + i + "_Quantity"]]);
                                        }

                                        if (!IsConnectionInfoBlank(conn))
                                        {
                                            import.Connections.Add(conn);
                                        }
                                    }
                                    catch
                                    {
                                    }
                                }
                            }
                            else
                            {
                                //blank row
                                import = null;
                            }
                        }
                        catch (Exception exp)
                        {
                            //exception parsing current row
                            System.Diagnostics.Debug.WriteLine("Excel Import: " + exp.Message);
                        }
                        finally
                        {
                            if (import != null)
                            {
                                outputList.Add(import);
                            }
                        }
                    }
                }
            }
            catch (Exception exp)
            {
                //could not read from file
                throw (exp);
            }

            return(outputList);
        }
 public override void ParseAdditionalData(ChargePoint cp, XmlNode item, CoreReferenceData coreRefData)
 {
 }
예제 #30
0
        public async Task Invoke(HttpContext context)
        {
            _logger.LogTrace("OCPPMiddleware => Websocket request: Path='{0}'", context.Request.Path);

            ChargePointStatus chargePointStatus = null;

            if (context.Request.Path.StartsWithSegments("/OCPP"))
            {
                string   chargepointIdentifier;
                string[] parts = context.Request.Path.Value.Split('/');
                if (string.IsNullOrWhiteSpace(parts[parts.Length - 1]))
                {
                    // (Last part - 1) is chargepoint identifier
                    chargepointIdentifier = parts[parts.Length - 2];
                }
                else
                {
                    // Last part is chargepoint identifier
                    chargepointIdentifier = parts[parts.Length - 1];
                }
                _logger.LogInformation("OCPPMiddleware => Connection request with chargepoint identifier = '{0}'", chargepointIdentifier);

                // Known chargepoint?
                if (!string.IsNullOrWhiteSpace(chargepointIdentifier))
                {
                    using (OCPPCoreContext dbContext = new OCPPCoreContext(_configuration))
                    {
                        ChargePoint chargePoint = dbContext.Find <ChargePoint>(chargepointIdentifier);
                        if (chargePoint != null)
                        {
                            _logger.LogInformation("OCPPMiddleware => SUCCESS: Found chargepoint with identifier={0}", chargePoint.ChargePointId);

                            // Check optional chargepoint authentication
                            if (!string.IsNullOrWhiteSpace(chargePoint.Username))
                            {
                                // Chargepoint MUST send basic authentication header

                                bool   basicAuthSuccess = false;
                                string authHeader       = context.Request.Headers["Authorization"];
                                if (!string.IsNullOrEmpty(authHeader))
                                {
                                    string[] cred = System.Text.ASCIIEncoding.ASCII.GetString(Convert.FromBase64String(authHeader.Substring(6))).Split(':');
                                    if (cred.Length == 2 && chargePoint.Username == cred[0] && chargePoint.Password == cred[1])
                                    {
                                        // Authentication match => OK
                                        _logger.LogInformation("OCPPMiddleware => SUCCESS: Basic authentication for chargepoint '{0}' match", chargePoint.ChargePointId);
                                        basicAuthSuccess = true;
                                    }
                                    else
                                    {
                                        // Authentication does NOT match => Failure
                                        _logger.LogWarning("OCPPMiddleware => FAILURE: Basic authentication for chargepoint '{0}' does NOT match", chargePoint.ChargePointId);
                                    }
                                }
                                if (basicAuthSuccess == false)
                                {
                                    context.Response.Headers.Add("WWW-Authenticate", "Basic realm=\"OCPP.Core\"");
                                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                                    return;
                                }
                            }
                            else if (!string.IsNullOrWhiteSpace(chargePoint.ClientCertThumb))
                            {
                                // Chargepoint MUST send basic authentication header

                                bool             certAuthSuccess = false;
                                X509Certificate2 clientCert      = context.Connection.ClientCertificate;
                                if (clientCert != null)
                                {
                                    if (clientCert.Thumbprint.Equals(chargePoint.ClientCertThumb, StringComparison.InvariantCultureIgnoreCase))
                                    {
                                        // Authentication match => OK
                                        _logger.LogInformation("OCPPMiddleware => SUCCESS: Certificate authentication for chargepoint '{0}' match", chargePoint.ChargePointId);
                                        certAuthSuccess = true;
                                    }
                                    else
                                    {
                                        // Authentication does NOT match => Failure
                                        _logger.LogWarning("OCPPMiddleware => FAILURE: Certificate authentication for chargepoint '{0}' does NOT match", chargePoint.ChargePointId);
                                    }
                                }
                                if (certAuthSuccess == false)
                                {
                                    context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                                    return;
                                }
                            }
                            else
                            {
                                _logger.LogInformation("OCPPMiddleware => No authentication for chargepoint '{0}' configured", chargePoint.ChargePointId);
                            }

                            // Store chargepoint data
                            chargePointStatus = new ChargePointStatus(chargePoint);
                        }
                        else
                        {
                            _logger.LogWarning("OCPPMiddleware => FAILURE: Found no chargepoint with identifier={0}", chargepointIdentifier);
                        }
                    }
                }

                if (chargePointStatus != null)
                {
                    if (context.WebSockets.IsWebSocketRequest)
                    {
                        // Match supported sub protocols
                        string subProtocol = null;
                        foreach (string supportedProtocol in SupportedProtocols)
                        {
                            if (context.WebSockets.WebSocketRequestedProtocols.Contains(supportedProtocol))
                            {
                                subProtocol = supportedProtocol;
                                break;
                            }
                        }
                        if (string.IsNullOrEmpty(subProtocol))
                        {
                            // Not matching protocol! => failure
                            string protocols = string.Empty;
                            foreach (string p in context.WebSockets.WebSocketRequestedProtocols)
                            {
                                if (string.IsNullOrEmpty(protocols))
                                {
                                    protocols += ",";
                                }
                                protocols += p;
                            }
                            _logger.LogWarning("OCPPMiddleware => No supported sub-protocol in '{0}' from charge station '{1}'", protocols, chargepointIdentifier);
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        }
                        else
                        {
                            chargePointStatus.Protocol = subProtocol;

                            bool statusSuccess = false;
                            try
                            {
                                _logger.LogTrace("OCPPMiddleware => Store/Update status object");

                                lock (_chargePointStatusDict)
                                {
                                    // Check if this chargepoint already/still hat a status object
                                    if (_chargePointStatusDict.ContainsKey(chargepointIdentifier))
                                    {
                                        // exists => check status
                                        if (_chargePointStatusDict[chargepointIdentifier].WebSocket.State != WebSocketState.Open)
                                        {
                                            // Closed or aborted => remove
                                            _chargePointStatusDict.Remove(chargepointIdentifier);
                                        }
                                    }

                                    _chargePointStatusDict.Add(chargepointIdentifier, chargePointStatus);
                                    statusSuccess = true;
                                }
                            }
                            catch (Exception exp)
                            {
                                _logger.LogError(exp, "OCPPMiddleware => Error storing status object in dictionary => refuse connection");
                                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                            }

                            if (statusSuccess)
                            {
                                // Handle socket communication
                                _logger.LogTrace("OCPPMiddleware => Waiting for message...");

                                using (WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(subProtocol))
                                {
                                    _logger.LogTrace("OCPPMiddleware => WebSocket connection with charge point '{0}'", chargepointIdentifier);
                                    chargePointStatus.WebSocket = webSocket;

                                    if (subProtocol == Protocol_OCPP20)
                                    {
                                        // OCPP V2.0
                                        await Receive20(chargePointStatus, context);
                                    }
                                    else
                                    {
                                        // OCPP V1.6
                                        await Receive16(chargePointStatus, context);
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        // no websocket request => failure
                        _logger.LogWarning("OCPPMiddleware => Non-Websocket request");
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    }
                }
                else
                {
                    // unknown chargepoint
                    _logger.LogTrace("OCPPMiddleware => no chargepoint: http 412");
                    context.Response.StatusCode = (int)HttpStatusCode.PreconditionFailed;
                }
            }
            else if (context.Request.Path.StartsWithSegments("/API"))
            {
                // Check authentication (X-API-Key)
                string apiKeyConfig = _configuration.GetValue <string>("ApiKey");
                if (!string.IsNullOrWhiteSpace(apiKeyConfig))
                {
                    // ApiKey specified => check request
                    string apiKeyCaller = context.Request.Headers["X-API-Key"].FirstOrDefault();
                    if (apiKeyConfig == apiKeyCaller)
                    {
                        // API-Key matches
                        _logger.LogInformation("OCPPMiddleware => Success: X-API-Key matches");
                    }
                    else
                    {
                        // API-Key does NOT matches => authentication failure!!!
                        _logger.LogWarning("OCPPMiddleware => Failure: Wrong X-API-Key! Caller='{0}'", apiKeyCaller);
                        context.Response.StatusCode = (int)HttpStatusCode.Unauthorized;
                        return;
                    }
                }
                else
                {
                    // No API-Key configured => no authenticatiuon
                    _logger.LogWarning("OCPPMiddleware => No X-API-Key configured!");
                }

                // format: /API/<command>[/chargepointId]
                string[] urlParts = context.Request.Path.Value.Split('/');

                if (urlParts.Length >= 3)
                {
                    string cmd = urlParts[2];
                    string urlChargePointId = (urlParts.Length >= 4) ? urlParts[3] : null;
                    _logger.LogTrace("OCPPMiddleware => cmd='{0}' / id='{1}' / FullPath='{2}')", cmd, urlChargePointId, context.Request.Path.Value);

                    if (cmd == "Status")
                    {
                        try
                        {
                            List <ChargePointStatus> statusList = new List <ChargePointStatus>();
                            foreach (ChargePointStatus status in _chargePointStatusDict.Values)
                            {
                                statusList.Add(status);
                            }
                            string jsonStatus = JsonConvert.SerializeObject(statusList);
                            context.Response.ContentType = "application/json";
                            await context.Response.WriteAsync(jsonStatus);
                        }
                        catch (Exception exp)
                        {
                            _logger.LogError(exp, "OCPPMiddleware => Error: {0}", exp.Message);
                            context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                        }
                    }
                    else if (cmd == "Reset")
                    {
                        if (!string.IsNullOrEmpty(urlChargePointId))
                        {
                            try
                            {
                                ChargePointStatus status = null;
                                if (_chargePointStatusDict.TryGetValue(urlChargePointId, out status))
                                {
                                    // Send message to chargepoint
                                    if (status.Protocol == Protocol_OCPP20)
                                    {
                                        // OCPP V2.0
                                        await Reset20(status, context);
                                    }
                                    else
                                    {
                                        // OCPP V1.6
                                        await Reset16(status, context);
                                    }
                                }
                                else
                                {
                                    // Chargepoint offline
                                    _logger.LogError("OCPPMiddleware SoftReset => Chargepoint offline: {0}", urlChargePointId);
                                    context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                                }
                            }
                            catch (Exception exp)
                            {
                                _logger.LogError(exp, "OCPPMiddleware SoftReset => Error: {0}", exp.Message);
                                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                            }
                        }
                        else
                        {
                            _logger.LogError("OCPPMiddleware SoftReset => Missing chargepoint ID");
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        }
                    }
                    else if (cmd == "UnlockConnector")
                    {
                        if (!string.IsNullOrEmpty(urlChargePointId))
                        {
                            try
                            {
                                ChargePointStatus status = null;
                                if (_chargePointStatusDict.TryGetValue(urlChargePointId, out status))
                                {
                                    // Send message to chargepoint
                                    if (status.Protocol == Protocol_OCPP20)
                                    {
                                        // OCPP V2.0
                                        await UnlockConnector20(status, context);
                                    }
                                    else
                                    {
                                        // OCPP V1.6
                                        await UnlockConnector16(status, context);
                                    }
                                }
                                else
                                {
                                    // Chargepoint offline
                                    _logger.LogError("OCPPMiddleware UnlockConnector => Chargepoint offline: {0}", urlChargePointId);
                                    context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                                }
                            }
                            catch (Exception exp)
                            {
                                _logger.LogError(exp, "OCPPMiddleware UnlockConnector => Error: {0}", exp.Message);
                                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                            }
                        }
                        else
                        {
                            _logger.LogError("OCPPMiddleware UnlockConnector => Missing chargepoint ID");
                            context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                        }
                    }
                    else
                    {
                        // Unknown action/function
                        _logger.LogWarning("OCPPMiddleware => action/function: {0}", cmd);
                        context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    }
                }
            }
            else if (context.Request.Path.StartsWithSegments("/"))
            {
                try
                {
                    bool showIndexInfo = _configuration.GetValue <bool>("ShowIndexInfo");
                    if (showIndexInfo)
                    {
                        _logger.LogTrace("OCPPMiddleware => Index status page");

                        context.Response.ContentType = "text/plain";
                        await context.Response.WriteAsync(string.Format("Running...\r\n\r\n{0} chargepoints connected", _chargePointStatusDict.Values.Count));
                    }
                    else
                    {
                        _logger.LogInformation("OCPPMiddleware => Root path with deactivated index page");
                        context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
                    }
                }
                catch (Exception exp)
                {
                    _logger.LogError(exp, "OCPPMiddleware => Error: {0}", exp.Message);
                    context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                }
            }
            else
            {
                _logger.LogWarning("OCPPMiddleware => Bad path request");
                context.Response.StatusCode = (int)HttpStatusCode.BadRequest;
            }
        }