public List <API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData) { List <ChargePoint> outputList = new List <ChargePoint>(); string source = InputData; JObject o = JObject.Parse(source); var dataList = o["features"].ToArray(); int itemCount = 0; // address, operator, chargepoint var dataMap = new Dictionary <Tuple <String, int?>, ChargePoint>(); var unknownOperators = new Dictionary <String, int>(); foreach (var dataItem in dataList) { var item = dataItem["attributes"]; var cp = new POIDetails(); cp.DataProviderID = this.DataProviderID; //Bundesnetzagentur ///cp.DataProvidersReference = item["OBJECTID"].ToString(); // - Note: There is no unique reference in this data source. The ObjectID seems to be a dynamic row id and using it results in unrelated data being overwritten between imports cp.DateLastStatusUpdate = DateTime.UtcNow; cp.AddressInfo = new AddressInfo(); var locationStr = item["Standort_"].ToString(); var address = locationStr.Split(", "); cp.AddressInfo.AddressLine1 = address[0]; cp.AddressInfo.Title = address[0]; var postcodeAndTown = address[1].Split(" "); cp.AddressInfo.Postcode = postcodeAndTown[0]; cp.AddressInfo.Town = String.Join(" ", postcodeAndTown[1..]);
public List <API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData) { List <ChargePoint> outputList = new List <ChargePoint>(); string source = InputData; JObject o = JObject.Parse(source); var dataList = o["ChargeDevice"].ToArray(); int itemCount = 0; foreach (var dataItem in dataList) { bool skipPOI = false; var item = dataItem; var cp = new POIDetails(); var deviceName = item["ChargeDeviceName"].ToString(); //private addresses are skipped from import if (!String.IsNullOrEmpty(deviceName) && deviceName.ToLower().Contains("parkatmyhouse")) { skipPOI = true; } var locationType = item["LocationType"].ToString(); if (!String.IsNullOrEmpty(locationType)) { if (locationType.ToLower().Contains("home")) { skipPOI = true; } } //parse reset of POI data cp.DataProviderID = this.DataProviderID; //UK National Charge Point Registry cp.DataProvidersReference = item["ChargeDeviceId"].ToString(); cp.DateLastStatusUpdate = DateTime.UtcNow; cp.AddressInfo = new AddressInfo(); var locationDetails = item["ChargeDeviceLocation"]; var addressDetails = locationDetails["Address"]; cp.AddressInfo.RelatedURL = ""; cp.DateLastStatusUpdate = DateTime.UtcNow; cp.AddressInfo.AddressLine1 = (String.IsNullOrEmpty(addressDetails["Street"].ToString()) ? addressDetails["BuildingNumber"].ToString() + " " + addressDetails["Thoroughfare"].ToString() : addressDetails["Street"].ToString().Replace("<br>", ", ")).Trim(); cp.AddressInfo.Title = String.IsNullOrEmpty(locationDetails["LocationShortDescription"].ToString()) ? cp.AddressInfo.AddressLine1 : locationDetails["LocationShortDescription"].ToString(); cp.AddressInfo.Title = cp.AddressInfo.Title.Replace("&", "&"); cp.AddressInfo.Title = cp.AddressInfo.Title.Replace("<br>", ", ").Trim(); if (cp.AddressInfo.Title.Length > 100) { cp.AddressInfo.Title = cp.AddressInfo.Title.Substring(0, 64) + ".."; } cp.AddressInfo.Town = addressDetails["PostTown"].ToString(); string dependantLocality = addressDetails["DependantLocality"].ToString(); if (!String.IsNullOrEmpty(dependantLocality) && dependantLocality.ToLower() != cp.AddressInfo.Town.ToLower()) { //use depenendantLocality if provided and is not same as town cp.AddressInfo.AddressLine2 = dependantLocality; } cp.AddressInfo.Postcode = addressDetails["PostCode"].ToString(); cp.AddressInfo.Latitude = double.Parse(locationDetails["Latitude"].ToString()); cp.AddressInfo.Longitude = double.Parse(locationDetails["Longitude"].ToString()); cp.AddressInfo.AccessComments = locationDetails["LocationLongDescription"].ToString().Replace("<br>", ", ").Replace("\r\n", ", ").Replace("\n", ", "); //if title is empty, attempt to add a suitable replacement if (String.IsNullOrEmpty(cp.AddressInfo.Title)) { if (!String.IsNullOrEmpty(cp.AddressInfo.AddressLine1)) { cp.AddressInfo.Title = cp.AddressInfo.AddressLine1.Trim(); } else { cp.AddressInfo.Title = cp.AddressInfo.Postcode; } } if (cp.AddressInfo.Title == "NA" && cp.AddressInfo.AddressLine1 == "NA") { // item needs an address resolved cp.AddressInfo.Title = ""; cp.AddressCleaningRequired = true; cp.SubmissionStatusTypeID = (int)StandardSubmissionStatusTypes.Imported_UnderReview; } if (cp.AddressInfo.Title.ToLower().StartsWith("asset no.") && cp.AddressInfo.AddressLine1.ToLower().StartsWith("asset no.")) { // item needs an address resolved cp.AddressInfo.Title = ""; cp.AddressCleaningRequired = true; cp.SubmissionStatusTypeID = (int)StandardSubmissionStatusTypes.Imported_UnderReview; } //cp.AddressInfo.ContactTelephone1 = item["phone"].ToString(); if (!String.IsNullOrEmpty(addressDetails["Country"].ToString())) { string country = addressDetails["Country"].ToString(); int? countryID = null; var countryVal = coreRefData.Countries.FirstOrDefault(c => c.Title.ToLower() == country.Trim().ToLower()); if (countryVal == null) { country = country.ToUpper(); //match country if (country == "GB" || country == "US" || country == "USA" || country == "U.S." || country == "U.S.A.") { countryID = 2; } if (country == "UK" || country == "GB" || country == "GREAT BRITAIN" || country == "UNITED KINGDOM") { countryID = 1; } } else { countryID = countryVal.ID; } if (countryID == null) { this.Log("Country Not Matched, will require Geolocation:" + item["country"].ToString()); } else { cp.AddressInfo.CountryID = countryID; } } else { //default to US if no country identified //cp.AddressInfo.Country = cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == 2); } //operator from DeviceController var deviceController = item["DeviceController"]; cp.AddressInfo.RelatedURL = deviceController["Website"].ToString(); var deviceOperator = coreRefData.Operators.FirstOrDefault(devOp => devOp.Title.Contains(deviceController["OrganisationName"].ToString())); if (deviceOperator != null) { cp.OperatorID = deviceOperator.ID; } else { //operator from device owner var devOwner = item["DeviceOwner"]; deviceOperator = coreRefData.Operators.FirstOrDefault(devOp => devOp.Title.Contains(devOwner["OrganisationName"].ToString())); if (deviceOperator != null) { cp.OperatorID = deviceOperator.ID; } } if (cp.OperatorID == null) { string operatorName = deviceController["OrganisationName"]?.ToString() ?? item["DeviceOwner"]["OrganisationName"]?.ToString(); // match specific operators switch (operatorName) { case "Chargemaster (POLAR)": cp.OperatorID = 8; break; case "Ecotricity (Electric Highway)": cp.OperatorID = 24; break; case "ecar NI": cp.OperatorID = 91; break; case "eo Charging": cp.OperatorID = 3298; break; case "Alfa Power": cp.OperatorID = 3326; break; case "InCharge - an initiative by Vattenfall": cp.OperatorID = 3343; break; case "APT": cp.OperatorID = 3341; break; } if (cp.OperatorID == null) { Log("Unknown Operator: " + deviceController["OrganisationName"]?.ToString() ?? item["DeviceOwner"]["OrganisationName"]?.ToString()); } } //determine most likely usage type cp.UsageTypeID = (int)StandardUsageTypes.Public; if (item["SubscriptionRequiredFlag"].ToString().ToUpper() == "TRUE") { //membership required cp.UsageTypeID = (int)StandardUsageTypes.Public_MembershipRequired; } else { if (item["PaymentRequiredFlag"].ToString().ToUpper() == "TRUE") { //payment required cp.UsageTypeID = (int)StandardUsageTypes.Public_PayAtLocation; } else { //accessible 24 hours, payment not required and membership not required, assume public if (item["Accessible24Hours"].ToString().ToUpper() == "TRUE") { cp.UsageTypeID = (int)StandardUsageTypes.Public; } } } //special usage cases detected from text if (cp.AddressInfo.ToString().ToLower().Contains("no public access")) { cp.UsageTypeID = (int)StandardUsageTypes.PrivateRestricted; } //add connections var connectorList = item["Connector"].ToArray(); foreach (var conn in connectorList) { ConnectionInfo cinfo = new ConnectionInfo() { }; if (conn["RatedOutputkW"] != null) { double tmpKw = 0; if (double.TryParse(conn["RatedOutputkW"].ToString(), out tmpKw)) { cinfo.PowerKW = tmpKw; } } if (conn["RatedOutputVoltage"] != null) { int tmpV = 0; if (int.TryParse(conn["RatedOutputVoltage"].ToString(), out tmpV)) { cinfo.Voltage = tmpV; } } if (conn["RatedOutputCurrent"] != null) { int tmpA = 0; if (int.TryParse(conn["RatedOutputCurrent"].ToString(), out tmpA)) { cinfo.Amps = tmpA; } } string connectorType = conn["ConnectorType"].ToString(); if (!String.IsNullOrEmpty(connectorType)) { cinfo.Reference = conn["ConnectorId"].ToString(); if (connectorType.ToUpper().Contains("BS 1363") || connectorType.ToUpper().Contains("3-PIN TYPE G (BS1363)")) { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.BS1363TypeG; //UK 13 amp plug cinfo.LevelID = 2; // default to level 2 } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 1 (SAE J1772)" || connectorType.ToUpper() == "TYPE 1 SAEJ1772 (IEC 62196)") { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.J1772; cinfo.LevelID = 2; // default to level 2 } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 2" || connectorType.ToUpper().Contains("(IEC62196)")) { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.MennekesType2; cinfo.LevelID = 2; if (cinfo.Amps > 32) { // assume connector is tethered due to high current cinfo.ConnectionTypeID = (int)StandardConnectionTypes.MennekesType2Tethered; } // handle Type 2 Tesla (IEC62196) DC which are Type 2 but tesla access only if (connectorType.ToUpper() == "TYPE 2 TESLA (IEC62196) DC") { cinfo.Comments = "Tesla Only"; } } if (connectorType.ToUpper() == "JEVS G 105 (CHADEMO)" || connectorType.ToUpper() == "JEVS G105 (CHADEMO) DC") { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.CHAdeMO; cinfo.LevelID = 3; } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 3") { cinfo.ConnectionTypeID = 26; //IEC 62196-2 type 3 cinfo.LevelID = 2; } if (connectorType.ToUpper() == "TYPE 2 COMBO (IEC62196) DC") { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.CCSComboType2; cinfo.LevelID = 3; } if (connectorType.ToUpper() == "TYPE 2 COMBO (IEC62196) DC") { cinfo.ConnectionTypeID = (int)StandardConnectionTypes.CCSComboType2; cinfo.LevelID = 3; } if (conn["ChargePointStatus"] != null) { cinfo.StatusTypeID = (int)StandardStatusTypes.Operational; if (conn["ChargePointStatus"].ToString() == "Out of service") { cinfo.StatusTypeID = (int)StandardStatusTypes.NotOperational; } } if (conn["ChargeMethod"] != null && !String.IsNullOrEmpty(conn["ChargeMethod"].ToString())) { string method = conn["ChargeMethod"].ToString(); //Single Phase AC, Three Phase AC, DC if (method == "Single Phase AC") { cinfo.CurrentTypeID = (int)StandardCurrentTypes.SinglePhaseAC; } if (method == "Three Phase AC") { cinfo.CurrentTypeID = (int)StandardCurrentTypes.ThreePhaseAC; } if (method == "DC") { cinfo.CurrentTypeID = (int)StandardCurrentTypes.DC; } } if (cinfo.ConnectionTypeID == null) { if (!String.IsNullOrEmpty(connectorType)) { Log("Unknown connector type:" + connectorType); } } if (cp.Connections == null) { cp.Connections = new List <ConnectionInfo>(); } if (!IsConnectionInfoBlank(cinfo)) { //TODO: skip items with blank address info cp.Connections.Add(cinfo); } } } //apply data attribution metadata if (cp.MetadataValues == null) { cp.MetadataValues = new List <MetadataValue>(); } cp.MetadataValues.Add(new MetadataValue { MetadataFieldID = (int)StandardMetadataFields.Attribution, ItemValue = DataAttribution }); if (cp.DataQualityLevel == null) { cp.DataQualityLevel = 3; } if (cp.SubmissionStatusTypeID == null) { cp.SubmissionStatusTypeID = (int)StandardSubmissionStatusTypes.Imported_Published; } if (!skipPOI) { outputList.Add(new ChargePoint(cp)); itemCount++; } } return(outputList); }