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); }
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(); }
/// <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); } }
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); }
/// <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); } }
//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 } }
/// <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"); }
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)); }
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); }
//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); }
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); }
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)); } }
//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); }
/// <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); } }
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); }
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); } } } }
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; } }
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); } }
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); } }
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; } }
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); }
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); } }
//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)); }
/// <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); }
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) { }
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; } }