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["locations"].ToArray(); var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Imported_UnderReview);//imported and under review var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50); var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == 0); var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == 1); var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == 2); var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1); int itemCount = 0; foreach (var item in dataList) { ChargePoint cp = new ChargePoint(); cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //carstations.com cp.DataProvidersReference = item["post_id"].ToString(); cp.DateLastStatusUpdate = DateTime.UtcNow; cp.AddressInfo = new AddressInfo(); //carstations.com have requested we not use the station names from their data, so we use address //cp.AddressInfo.Title = item["name"] != null ? item["name"].ToString() : item["address"].ToString(); cp.AddressInfo.Title = item["address"] != null ? item["address"].ToString() : item["post_id"].ToString(); cp.AddressInfo.Title = cp.AddressInfo.Title.Trim().Replace("&", "&"); cp.AddressInfo.RelatedURL = "http://carstations.com/" + cp.DataProvidersReference; cp.DateLastStatusUpdate = DateTime.UtcNow; cp.AddressInfo.AddressLine1 = item["address"].ToString().Trim(); cp.AddressInfo.Town = item["city"].ToString().Trim(); cp.AddressInfo.StateOrProvince = item["region"].ToString().Trim(); cp.AddressInfo.Postcode = item["postal_code"].ToString().Trim(); cp.AddressInfo.Latitude = double.Parse(item["latitude"].ToString().Trim()); cp.AddressInfo.Longitude = double.Parse(item["longitude"].ToString().Trim()); cp.AddressInfo.ContactTelephone1 = item["phone"].ToString(); if (!String.IsNullOrEmpty(item["country"].ToString())) { string country = item["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 == "UNITED STATES" || 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.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == countryID); } } else { //default to US if no country identified //cp.AddressInfo.Country = cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == 2); } //System.Diagnostics.Debug.WriteLine(item.ToString()); string publicCount = item["public"].ToString(); string privateCount = item["private"].ToString(); if (!String.IsNullOrEmpty(publicCount) && publicCount != "0") { try { cp.NumberOfPoints = int.Parse(publicCount); } catch (Exception) { } cp.UsageType = usageTypePublic; } else { if (!String.IsNullOrEmpty(privateCount) && privateCount != "0") { try { cp.NumberOfPoints = int.Parse(privateCount); } catch (Exception) { } cp.UsageType = usageTypePrivate; } } string verifiedFlag = item["verified_flag"].ToString(); if (!string.IsNullOrEmpty(verifiedFlag) && verifiedFlag != "0") { cp.StatusType = operationalStatus; } else { cp.StatusType = unknownStatus; } //TODO: allow for multiple operators? var operatorsNames = item["brands"].ToArray(); if (operatorsNames.Count() > 0) { var operatorName = operatorsNames[0].ToString(); var opDetails = coreRefData.Operators.FirstOrDefault(op => op.Title.ToLower().Contains(operatorName.ToString().ToLower())); if (opDetails != null) { cp.OperatorInfo = opDetails; } else { Log("Operator not matched:" + operatorName); } } else { cp.OperatorInfo = operatorUnknown; } var connectorTypes = item["techs"].ToArray(); foreach (var conn in connectorTypes) { ConnectionInfo cinfo = new ConnectionInfo() { }; ConnectionType cType = new ConnectionType { ID = 0 }; ChargerType level = null; cinfo.Reference = conn.ToString(); if (conn.ToString().ToUpper() == "J1772") { cType = new ConnectionType(); cType.ID = 1; //J1772 level = new ChargerType { ID = 2 };//default to level 2 } if (conn.ToString().ToUpper() == "CHADEMO") { cType = new ConnectionType(); cType.ID = 2; //CHadeMO level = new ChargerType { ID = 3 };//default to level 3 } if (conn.ToString().ToUpper() == "NEMA5") { cType = new ConnectionType(); cType.ID = 9; //NEMA5-20R level = new ChargerType { ID = 1 };//default to level 1 } if (cType.ID == 0) { var conType = coreRefData.ConnectionTypes.FirstOrDefault(ct => ct.Title.ToLower().Contains(conn.ToString().ToLower())); if (conType != null) cType = conType; } cinfo.ConnectionType = cType; cinfo.Level = level; if (cp.Connections == null) { cp.Connections = new List<ConnectionInfo>(); if (!IsConnectionInfoBlank(cinfo)) { cp.Connections.Add(cinfo); } } } if (cp.DataQualityLevel == null) cp.DataQualityLevel = 2; cp.SubmissionStatus = submissionStatus; if (IsPOIValidForImport(cp)) { outputList.Add(cp); } itemCount++; } return outputList; }
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(); var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Imported_UnderReview);//imported and under review var submissionStatusDelistedPrivate = coreRefData.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Delisted_NotPublicInformation);//delisted not public var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50); var nonoperationalStatus = coreRefData.StatusTypes.First(os => os.ID == 100); var unknownStatus = coreRefData.StatusTypes.First(os => os.ID == (int)StandardStatusTypes.Unknown); var usageTypeUnknown = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Unknown); var usageTypePublic = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public); var usageTypePublicPayAtLocation = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public_PayAtLocation); var usageTypePrivate = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.PrivateRestricted); var usageTypePublicMembershipRequired = coreRefData.UsageTypes.First(u => u.ID == (int)StandardUsageTypes.Public_MembershipRequired); var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == (int)StandardOperators.UnknownOperator); int itemCount = 0; foreach (var dataItem in dataList) { bool skipPOI = false; var item = dataItem; ChargePoint cp = new ChargePoint(); var deviceName = item["ChargeDeviceName"].ToString(); //private addresses are skipped from import if (!String.IsNullOrEmpty(deviceName) && deviceName.ToLower().Contains("parkatmyhouse")) { //skipPOI = true; skipPOI = true; } var locationType = item["LocationType"].ToString(); if (!String.IsNullOrEmpty(locationType)) { if (locationType.ToLower().Contains("home")) { skipPOI = true; } } //parse reset of POI data cp.DataProvider = new DataProvider() { ID = 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 = addressDetails["Street"].ToString().Replace("<br>", ", "); 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>", ", "); 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(!String.IsNullOrEmpty(cp.AddressInfo.Postcode)) //{ //cp.AddressInfo.Postcode = this.NormalizePostcode(cp.AddressInfo.Postcode); //} //TODO: if address wasn't provide in address details try to parse from "LocationLongDescription": /*if (String.IsNullOrEmpty(cp.AddressInfo.AddressLine1) && string.IsNullOrEmpty(cp.AddressInfo.AddressLine2) && string.IsNullOrEmpty(cp.AddressInfo.Town) && string.IsNullOrEmpty(cp.AddressInfo.Postcode)) { }*/ //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; } else { cp.AddressInfo.Title = cp.AddressInfo.Postcode; } } //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.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == 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.OperatorInfo = deviceOperator; } else { //operator from device owner var devOwner = item["DeviceOwner"]; deviceOperator = coreRefData.Operators.FirstOrDefault(devOp => devOp.Title.Contains(devOwner["OrganisationName"].ToString())); if (deviceOperator != null) { cp.OperatorInfo = deviceOperator; } } //determine most likely usage type cp.UsageType = usageTypeUnknown; if (item["SubscriptionRequiredFlag"].ToString().ToUpper() == "TRUE") { //membership required cp.UsageType = usageTypePublicMembershipRequired; } else { if (item["PaymentRequiredFlag"].ToString().ToUpper() == "TRUE") { //payment required cp.UsageType = usageTypePublicPayAtLocation; } else { //accessible 24 hours, payment not required and membership not required, assume public if (item["Accessible24Hours"].ToString().ToUpper() == "TRUE") { cp.UsageType = usageTypePublic; } } } //special usage cases detected from text if (cp.AddressInfo.ToString().ToLower().Contains("no public access")) { cp.UsageType = usageTypePrivate; } //add connections var connectorList = item["Connector"].ToArray(); foreach (var conn in connectorList) { string connectorType = conn["ConnectorType"].ToString(); if (!String.IsNullOrEmpty(connectorType)) { ConnectionInfo cinfo = new ConnectionInfo() { }; ConnectionType cType = new ConnectionType { ID = 0 }; ChargerType level = null; cinfo.Reference = conn["ConnectorId"].ToString(); if (connectorType.ToUpper().Contains("BS 1363") || connectorType.ToUpper().Contains("3-PIN TYPE G (BS1363)")) { cType = new ConnectionType(); cType.ID = 3; //UK 13 amp plug level = new ChargerType { ID = 2 };//default to level 2 } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 1 (SAE J1772)" || connectorType.ToUpper() == "TYPE 1 SAEJ1772 (IEC 62196)") { cType = new ConnectionType(); cType.ID = 1; //J1772 level = new ChargerType { ID = 2 };//default to level 2 } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 2" || connectorType.ToUpper().Contains("TYPE 2 MENNEKES (IEC62196)")) { cType = new ConnectionType(); cType.ID = 25; //Mennkes Type 2 level = new ChargerType { ID = 2 };//default to level 2 } if (connectorType.ToUpper() == "JEVS G 105 (CHADEMO)" || connectorType.ToUpper() == "JEVS G105 (CHADEMO) DC") { cType = new ConnectionType(); cType.ID = 2; //CHadeMO level = new ChargerType { ID = 3 };//default to level 3 } if (connectorType.ToUpper() == "IEC 62196-2 TYPE 3") { cType = new ConnectionType(); cType.ID = 26; //IEC 62196-2 type 3 level = new ChargerType { ID = 2 };//default to level 2 } if (connectorType.ToUpper() == "TYPE 2 COMBO (IEC62196) DC") { cType = new ConnectionType(); cType.ID = 33; //CCS with Type 2 level = new ChargerType { ID = 3 };//default to level 3 } if (cType.ID == 0) { var conType = coreRefData.ConnectionTypes.FirstOrDefault(ct => ct.Title.ToLower().Contains(conn.ToString().ToLower())); if (conType != null) cType = conType; } if (!String.IsNullOrEmpty(conn["RatedOutputVoltage"].ToString())) cinfo.Voltage = int.Parse(conn["RatedOutputVoltage"].ToString()); if (!String.IsNullOrEmpty(conn["RatedOutputCurrent"].ToString())) cinfo.Amps = int.Parse(conn["RatedOutputCurrent"].ToString()); //TODO: use AC/DC/3 Phase data if (conn["ChargePointStatus"] != null) { cinfo.StatusType = operationalStatus; if (conn["ChargePointStatus"].ToString() == "Out of service") cinfo.StatusType = nonoperationalStatus; } 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; } } 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; } cinfo.ConnectionType = cType; cinfo.Level = level; if ((cinfo.ConnectionType == null && cinfo.ConnectionTypeID == null) || cinfo.ConnectionType != null && cinfo.ConnectionType.ID == 0) { 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.SubmissionStatus == null) cp.SubmissionStatus = submissionStatus; if (!skipPOI) { outputList.Add(cp); itemCount++; } } return outputList; }