Beispiel #1
0
        private static void SendEditSubmissionNotification(Model.ChargePoint poi, Model.User user)
        {
            try
            {
                string approvalStatus = "Edit Submitted for approval";

                //send notification
                var notification = new NotificationManager();
                var msgParams    = new Hashtable();
                msgParams.Add("Description", "OCM-" + poi.ID + " : " + poi.AddressInfo.Title);
                msgParams.Add("SubmissionStatusType", approvalStatus);
                msgParams.Add("ItemURL", "https://openchargemap.org/site/poi/details/" + poi.ID);
                msgParams.Add("ChargePointID", poi.ID);
                msgParams.Add("UserName", user != null ? user.Username : "******");
                msgParams.Add("MessageBody",
                              "Edit item for Approval: Location " + approvalStatus + " OCM-" + poi.ID + " Submitted: " +
                              poi.AddressInfo.Title);

                notification.PrepareNotification(NotificationType.LocationSubmitted, msgParams);

                //notify default system recipients
                notification.SendNotification(NotificationType.LocationSubmitted);
            }
            catch (Exception)
            {
                ;
                ; //failed to send notification
            }
        }
Beispiel #2
0
        public bool ProcessEquipmentSubmission(HttpContext context, ref OCM.API.Common.Model.ChargePoint cp)
        {
            System.IO.StreamReader sr = new System.IO.StreamReader(context.Request.InputStream);
            //TODO: handle encoding (UTF etc) correctly
            string responseContent = sr.ReadToEnd().Trim();

            string jsonString = responseContent;

            try
            {
                JObject o = JObject.Parse(jsonString);

                JsonSerializer serializer = new JsonSerializer();
                cp = (Common.Model.ChargePoint)serializer.Deserialize(new JTokenReader(o), typeof(Common.Model.ChargePoint));

                //validate cp submission

                if (POIManager.IsValid(cp))
                {
                    return(true);
                }
                else
                {
                    return(false);
                }
            }
            catch (Exception exp)
            {
                System.Diagnostics.Debug.WriteLine(exp);

                //submission failed
                return(false);
            }
        }
        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 DataQualityReport GetDataQualityReport(OCM.API.Common.Model.ChargePoint poi)
        {
            DataQualityReport report = new DataQualityReport();

            report.POIReports.Add(CheckPOIDataQuality(poi));
            return(report);
        }
        public static POIMongoDB FromChargePoint(OCM.API.Common.Model.ChargePoint cp, POIMongoDB poi = null)
        {
            if (poi == null)
            {
                poi = new POIMongoDB();
            }

            poi.AddressInfo            = cp.AddressInfo;
            poi.Chargers               = cp.Chargers;
            poi.Connections            = cp.Connections;
            poi.DataProvider           = cp.DataProvider;
            poi.DataProviderID         = cp.DataProviderID;
            poi.DataProvidersReference = cp.DataProvidersReference;
            poi.DataQualityLevel       = cp.DataQualityLevel;

            if (cp.DateCreated != null)
            {
                poi.DateCreated = (DateTime?)DateTime.SpecifyKind(cp.DateCreated.Value, DateTimeKind.Utc);
            }
            if (cp.DateLastConfirmed != null)
            {
                poi.DateLastConfirmed = (DateTime?)DateTime.SpecifyKind(cp.DateLastConfirmed.Value, DateTimeKind.Utc);
            }
            if (cp.DateLastStatusUpdate != null)
            {
                poi.DateLastStatusUpdate = (DateTime?)DateTime.SpecifyKind(cp.DateLastStatusUpdate.Value, DateTimeKind.Utc);
            }
            if (cp.DatePlanned != null)
            {
                poi.DatePlanned = (DateTime?)DateTime.SpecifyKind(cp.DatePlanned.Value, DateTimeKind.Utc);
            }

            poi.GeneralComments = cp.GeneralComments;
            poi.ID                     = cp.ID;
            poi.MediaItems             = cp.MediaItems;
            poi.MetadataTags           = cp.MetadataTags;
            poi.MetadataValues         = cp.MetadataValues;
            poi.NumberOfPoints         = cp.NumberOfPoints;
            poi.NumberOfPoints         = cp.NumberOfPoints;
            poi.OperatorID             = cp.OperatorID;
            poi.OperatorInfo           = cp.OperatorInfo;
            poi.OperatorsReference     = cp.OperatorsReference;
            poi.ParentChargePointID    = cp.ParentChargePointID;
            poi.StatusType             = cp.StatusType;
            poi.StatusTypeID           = cp.StatusTypeID;
            poi.SubmissionStatus       = cp.SubmissionStatus;
            poi.SubmissionStatusTypeID = cp.SubmissionStatusTypeID;
            poi.UsageCost              = cp.UsageCost;
            poi.UsageType              = cp.UsageType;
            poi.UsageTypeID            = cp.UsageTypeID;
            poi.UserComments           = cp.UserComments;
            poi.LevelOfDetail          = cp.LevelOfDetail;
            poi.UUID                   = cp.UUID;
            return(poi);
        }
        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 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));
     }
 }
Beispiel #8
0
        //convert a simple POI to data and back again to fully populate all related properties, as submission may only have simple IDs for ref data etc
        private Model.ChargePoint PopulateFullPOI(Model.ChargePoint poi, Model.CoreReferenceData refData)
        {
            OCMEntities tempDataModel = new OCMEntities();

            //convert simple poi to fully populated db version
            var poiData = new POIManager().PopulateChargePoint_SimpleToData(poi, tempDataModel);

            //convert back to simple POI
            var modelPOI = Model.Extensions.ChargePoint.FromDataModel(poiData, false, false, true, true, refData);

            //clear temp changes from the poi
            //dataModel.Entry(poiData).Reload();
            tempDataModel.Dispose();
            return(modelPOI);
        }
        public static Model.ChargePoint DeserializePOIFromJSON(string json)
        {
            Model.ChargePoint poi = null;
            try
            {
                if (json != null)
                {
                    poi = JsonConvert.DeserializeObject <Model.ChargePoint>(json);
                }
            }
            catch (Exception)
            {
                System.Diagnostics.Debug.WriteLine("Failed to parse json POI data");
            }

            return(poi);
        }
        public Model.EditQueueItem GetItemWithDifferences(Core.Data.EditQueueItem item, POIManager cpManager, bool loadCurrentItem)
        {
            var queueItem = Model.Extensions.EditQueueItem.FromDataModel(item);

            //get diff between previous and edit

            Model.ChargePoint poiA = DeserializePOIFromJSON(queueItem.PreviousData);

            if (loadCurrentItem && poiA != null)
            {
                poiA = new POIManager().Get(poiA.ID);
            }
            Model.ChargePoint poiB = DeserializePOIFromJSON(queueItem.EditData);

            queueItem.Differences = cpManager.CheckDifferences(poiA, poiB, useObjectCompare: true);

            return(queueItem);
        }
Beispiel #11
0
        //convert a simple POI to data and back again to fully populate all related properties, as submission may only have simple IDs for ref data etc
        private Model.ChargePoint PopulateFullPOI(Model.ChargePoint poi)
        {
            OCMEntities tempDataModel = new OCMEntities();
            var         poiData       = new Core.Data.ChargePoint();

            if (poi.ID > 0)
            {
                poiData = tempDataModel.ChargePoints.First(c => c.ID == poi.ID);
            }

            //convert simple poi to fully populated db version
            new POIManager().PopulateChargePoint_SimpleToData(poi, poiData, tempDataModel);

            //convert back to simple POI
            var modelPOI = Model.Extensions.ChargePoint.FromDataModel(poiData, false, false, true, true);

            //clear temp changes from the poi
            //dataModel.Entry(poiData).Reload();
            tempDataModel.Dispose();
            return(modelPOI);
        }
        List<ChargePoint> IImportProvider.Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var operationalMixedStatus = coreRefData.StatusTypes.First(os => os.ID == 75);
            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 networkOperator = coreRefData.Operators.First(op=>op.ID==5); //Coulomb Chargepoint Network

            CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
            TextInfo textInfo = cultureInfo.TextInfo;

            string jsString = "{ \"data\": " + InputData + "}";

            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
            dynamic parsedList = jss.Deserialize(jsString, typeof(object)) as dynamic;
            var dataList = parsedList.data;

            int itemCount = 0;
            foreach (var item in dataList)
            {
                try
                {
                    ChargePoint cp = new ChargePoint();
                    cp.AddressInfo = new AddressInfo();

                    cp.OperatorInfo = networkOperator;
                    cp.OperatorsReference = item["StationID"].ToString();
                    cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //couloumb
                    cp.DataProvidersReference = item["StationID"].ToString();
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    cp.AddressInfo.Title = item["Name"] != null ? item["Name"].ToString() : item["StationID"].ToString();
                    cp.AddressInfo.Title = textInfo.ToTitleCase(cp.AddressInfo.Title.ToLower());
                    cp.AddressInfo.RelatedURL = "http://www.chargepoint.net";
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    cp.AddressInfo.Latitude = double.Parse(item["Geo"]["lat"].ToString());
                    cp.AddressInfo.Longitude = double.Parse(item["Geo"]["long"].ToString());

                    cp.AddressInfo.AddressLine1 = item["Address"].ToString();
                    //cp.AddressInfo.AddressLine2 = item["address2"].ToString();
                    cp.AddressInfo.Town = item["City"].ToString();
                    cp.AddressInfo.StateOrProvince = item["State"].ToString();
                    cp.AddressInfo.Postcode = item["postalCode"].ToString();

                    //set country property
                    string countryRef = item["Country"].ToString();
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.Title == countryRef);

                    /*string usageTypeCode = item["type"].ToString();
                    if (usageTypeCode == "COMMERCIAL")
                    {
                        cp.UsageType = coreRefData.UsageTypes.FirstOrDefault(u => u.ID == 5); //pay at location
                    }
                    else
                    {
                        Log("Unmatched usage type:"+usageTypeCode);
                    }
                    */
                    cp.NumberOfPoints = int.Parse(item["Num_port"].ToString());
                    cp.GeneralComments = item["Description"].ToString();

                    /*int numOffline = int.Parse(item["offline"].ToString());
                    if (numOffline > 0)
                    {
                        cp.StatusType = operationalMixedStatus;
                    }
                    else
                    {
                        cp.StatusType = operationalStatus;
                    }

                    //populate connections
                    cp.Connections = new List<ConnectionInfo>();
                    var levelTypes = item["levels"].ToArray();
                    foreach (var level in levelTypes)
                    {
                        ConnectionInfo con = new ConnectionInfo();
                        if (level.ToString() == "1")
                        {
                            con.ConnectionType = new ConnectionType { ID = 1 };//J1772
                            con.Level = new ChargerType { ID = 1 };
                        }
                        if (level.ToString() == "2")
                        {
                            con.ConnectionType = new ConnectionType { ID = 1 };//J1772
                            con.Voltage = 220;
                            con.Level = new ChargerType { ID = 2 };
                        }
                        if (level.ToString() == "3")
                        {
                            con.ConnectionType = new ConnectionType { ID = 3 };//J1772
                            con.Voltage = 480;
                            con.Level = new ChargerType { ID = 3 };
                        }
                        cp.Connections.Add(con);
                    }
                     * */
                    cp.DataQualityLevel = 3; //avg, higher than default

                    cp.SubmissionStatus = submissionStatus;
                    outputList.Add(cp);
                }
                catch (Exception)
                {
                    Log("Error parsing item " + itemCount);
                }

                itemCount++;
            }

            return outputList;
        }
        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;
        }
        public bool ProcessEquipmentSubmission(HttpContext context, ref OCM.API.Common.Model.ChargePoint cp)
        {
            return(false); //html input provider no longer supported

            /*
             * //construct simple model view of new CP based on input, to then be used to contruct data model version
             * cp.AddressInfo = new Common.Model.AddressInfo();
             *
             * cp.AddressInfo.Title = ParseString(context.Request["ocm_loc_title"]);
             * cp.AddressInfo.AddressLine1 = ParseString(context.Request["ocm_loc_addressline1"]);
             * cp.AddressInfo.AddressLine2 = ParseString(context.Request["ocm_loc_addressline2"]);
             * cp.AddressInfo.Town = ParseString(context.Request["ocm_loc_town"]);
             * cp.AddressInfo.StateOrProvince = ParseString(context.Request["ocm_loc_stateorprovince"]);
             * cp.AddressInfo.Postcode = ParseString(context.Request["ocm_loc_postcode"]);
             *
             * cp.AddressInfo.Latitude = (double)ParseDouble(context.Request["ocm_loc_latitude"]);
             * cp.AddressInfo.Longitude = (double)ParseDouble(context.Request["ocm_loc_longitude"]);
             *
             * int? countryID = ParseInt(context.Request["ocm_loc_countryid"]);
             * if (countryID != null) cp.AddressInfo.Country = new Common.Model.Country() { ID = (int)countryID };
             *
             * cp.AddressInfo.AccessComments = ParseLongString(context.Request["ocm_loc_accesscomments"]);
             * cp.AddressInfo.ContactTelephone1 = ParseString(context.Request["ocm_loc_contacttelephone1"]);
             * cp.AddressInfo.ContactEmail = ParseString(context.Request["ocm_loc_contactemail"]);
             *
             * //build connection info list
             * //connection 1 to n
             *
             * cp.Connections = new List<Common.Model.ConnectionInfo>();
             * for (int i = 1; i <= 2; i++)
             * {
             *  var connectionInfo = new Common.Model.ConnectionInfo();
             *
             *  int? connectionTypeID = ParseInt(context.Request["ocm_cp_connection" + i + "_type"]);
             *  if (connectionTypeID != null)
             *  {
             *      //TODO: remove/retire or remove entity reference for reference data lookup
             *      var connectionType = new OCM.Core.Data.OCMEntities().ConnectionTypes.First(ct => ct.ID == (int)connectionTypeID);
             *      connectionInfo.ConnectionType = OCM.API.Common.Model.Extensions.ConnectionType.FromDataModel(connectionType);
             *  }
             *
             *  int? chargerLevelID = ParseInt(context.Request["ocm_cp_connection" + i + "_level"]);
             *  if (chargerLevelID != null)
             *  {
             *      connectionInfo.Level = new Common.Model.ChargerType() { ID = (int)chargerLevelID };
             *  }
             *
             *  connectionInfo.Amps = ParseInt(context.Request["ocm_cp_connection" + i + "_amps"]);
             *  connectionInfo.Voltage = ParseInt(context.Request["ocm_cp_connection" + i + "_volts"]);
             *
             *  if (connectionInfo != null)
             *  {
             *      cp.Connections.Add(connectionInfo);
             *  }
             * }
             *
             * cp.NumberOfPoints = ParseInt(context.Request["ocm_cp_numberofpoints"]);
             *
             * int? usageTypeID = ParseInt(context.Request["ocm_cp_usagetype"]);
             * if (usageTypeID != null)
             * {
             *  cp.UsageType = new Common.Model.UsageType() { ID = (int)usageTypeID };
             * }
             *
             * cp.UsageCost = ParseString(context.Request["ocm_cp_usagecost"]);
             *
             * int? statusTypeID = ParseInt(context.Request["ocm_cp_statustype"]);
             * if (statusTypeID != null)
             * {
             *  cp.StatusType = new Common.Model.StatusType() { ID = (int)statusTypeID };
             * }
             *
             * cp.GeneralComments = ParseLongString(context.Request["ocm_cp_generalcomments"]);
             *
             * return true;
             * */
        }
Beispiel #15
0
        private void PrepareDefaultsForBlankSelections(ChargePoint poi)
        {
            //Where -1 is supplied as dropdown value etc we need to revert to a default or null value;
            //FIXME: the binding method varies between hidden fields and dropdown values
            if (poi.DataProviderID >= 1 || (poi.DataProvider != null && poi.DataProvider.ID > 0))
            {
                int providerId = (poi.DataProvider != null ? poi.DataProvider.ID : (int)poi.DataProviderID);
                poi.DataProviderID = providerId;
            }
            else
            {
                poi.DataProvider = null;
                poi.DataProviderID = (int)StandardDataProviders.OpenChargeMapContrib;
            }

            if (poi.OperatorID >= 1 || poi.OperatorInfo != null)
            {
                int operatorId = poi.OperatorInfo != null ? poi.OperatorInfo.ID : (int)poi.OperatorID;
                poi.OperatorID = operatorId;
            }
            else
            {
                poi.OperatorID = (int)StandardOperators.UnknownOperator;
            }

            if (poi.UsageTypeID > 0 || poi.UsageType != null)
            {
                int usageTypeId = poi.UsageType != null ? poi.UsageType.ID : (int)poi.UsageTypeID;
                poi.UsageTypeID = usageTypeId;
            }
            else
            {
                poi.UsageTypeID = (int)StandardUsageTypes.Unknown;
            }

            if (poi.StatusTypeID >= 0 || (poi.StatusType != null && (poi.StatusTypeID == -1 || poi.StatusTypeID == null)))
            {
                int statusTypeId = poi.StatusType != null ? poi.StatusType.ID : (int)poi.StatusTypeID;
                poi.StatusTypeID = statusTypeId;
            }

            if (poi.StatusTypeID == -1 || poi.StatusTypeID == null)
            {
                poi.StatusType = null;
                poi.StatusTypeID = (int)StandardStatusTypes.Unknown;
            }

            if (poi.SubmissionStatusTypeID == -1)
            {
                poi.SubmissionStatus = null;
                poi.SubmissionStatusTypeID = null;
            }

            if (poi.Connections != null)
            {
                foreach (var connection in poi.Connections)
                {
                    if (connection.ConnectionTypeID == -1)
                    {
                        connection.ConnectionType = null;
                        connection.ConnectionTypeID = (int)StandardConnectionTypes.Unknown;
                    }

                    if (connection.CurrentTypeID == -1)
                    {
                        connection.CurrentType = null;
                        connection.CurrentTypeID = null;
                    }

                    if (connection.StatusTypeID == -1)
                    {
                        connection.StatusType = null;
                        connection.StatusTypeID = (int)StandardStatusTypes.Unknown;
                    }

                    if (connection.LevelID == -1)
                    {
                        connection.Level = null;
                        connection.LevelID = null;
                    }
                }
            }
        }
Beispiel #16
0
        public ActionResult Edit(ChargePoint poi)
        {
            var refData = new POIBrowseModel();
            refData.AllowOptionalCountrySelection = false;
            ViewBag.ReferenceData = refData;

            ViewBag.ConnectionIndex = 0; //connection counter shared by equipment details
            ViewBag.EnableEditView = true;

            if (Request["editoption"] == "addconnection")
            {
                //add a placeholder for new equipment details
                if (poi.Connections == null) poi.Connections = new List<ConnectionInfo>();
                //TODO: setup defaults
                poi.Connections.Add(new ConnectionInfo());
                return View(poi);
            }

            if (Request["editoption"].ToString().StartsWith("remove-equipment"))
            {
                //TODO:remove requested connection
                //poi.Connections.Remove();
                string[] equipmentElementIDs = Request["editoption"].ToString().Split('-');
                int itemIndex = int.Parse(equipmentElementIDs[2]);
                poi.Connections.RemoveAt(itemIndex);
                return View(poi);
            }

            if (Request["editoption"] == "preview")
            {
                //preview poi
                ViewBag.EnablePreviewMode = true;

                //reset any values provided as -1 to a standard default (unknown etc)
                PrepareDefaultsForBlankSelections(poi);

                //update preview of poi with fully populated reference data
                poi = new POIManager().PreviewPopulatedPOIFromModel(poi);

                InitEditReferenceData(poi);

                return View(poi);
            }

            if (ModelState.IsValid)
            {
                try
                {
                    User user = null;

                    if (IsUserSignedIn) user = new UserManager().GetUser((int)Session["UserID"]);

                    //reset any values provided as -1 to a standard default (unknown etc)
                    PrepareDefaultsForBlankSelections(poi);

                    if (poi.AddressInfo.Country == null || poi.AddressInfo.Country.ID == -1) ModelState.AddModelError("Country", "Required");

                    //perform actual POI submission, then redirect to POI details if we can
                    int poiSubmissionID = new SubmissionManager().PerformPOISubmission(poi, user);
                    if (poiSubmissionID > -1)
                    {
                        if (poiSubmissionID > 0)
                        {
                            return RedirectToAction("Details", "POI", new { id = poiSubmissionID, status = "editsubmitted" });
                        }
                        else
                        {
                            return RedirectToAction("Index");
                        }
                    }
                    else
                    {
                        ViewBag.ValidationFailed = true;
                    }
                }
                catch
                {
                    //return View(poi);
                }
            }
            else
            {
                foreach (ModelState modelState in ViewData.ModelState.Values)
                {
                    foreach (ModelError error in modelState.Errors)
                    {
                        System.Diagnostics.Debug.WriteLine(error.ToString());
                    }
                }
            }

            ViewBag.ReferenceData = new POIBrowseModel();

            return View(poi);
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            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 usageTypePrivateForStaffAndVisitors = coreRefData.UsageTypes.First(u => u.ID == 6); //staff and visitors
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;

            string jsonString = "{ \"data\": " + InputData + "}";

            JObject o = JObject.Parse(jsonString);
            var dataList = o.Values()["list"].Values().ToArray();

            foreach (var item in dataList)
            {
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //AddEnergie
                cp.DataProvidersReference = item["StationID"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;

                cp.AddressInfo = new AddressInfo();

                cp.AddressInfo.Title = item["ParkName"].ToString();
                cp.AddressInfo.AddressLine1 = item["Address"].ToString().Trim();
                cp.AddressInfo.Town = item["City"].ToString().Trim();
                cp.AddressInfo.StateOrProvince = item["StateOrProvince"].ToString().Trim();
                cp.AddressInfo.Postcode = item["PostalOrZipCode"].ToString().Trim();
                cp.AddressInfo.Latitude = double.Parse(item["Latitude"].ToString());
                cp.AddressInfo.Longitude = double.Parse(item["Longitude"].ToString());

                //default to canada
                cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "ca");
                //todo: detect country

                //set network operators
                if (this.SelectedNetworkType == NetworkType.ReseauVER)
                {
                    cp.OperatorInfo = new OperatorInfo { ID = 89 };
                }

                if (this.SelectedNetworkType == NetworkType.LeCircuitElectrique)
                {
                    cp.OperatorInfo = new OperatorInfo { ID = 90 };
                }

                bool isPublic = bool.Parse(item["IsPublic"].ToString());
                if (isPublic)
                {
                    cp.UsageType = usageTypePublic;
                }
                else
                {
                    cp.UsageType = usageTypePrivate;
                }

                cp.NumberOfPoints = int.Parse(item["NumPorts"].ToString());
                cp.StatusType = operationalStatus;

                //populate connectioninfo from Ports
                foreach (var port in item["Ports"].ToArray())
                {
                    ConnectionInfo cinfo = new ConnectionInfo() { };
                    ConnectionType cType = new ConnectionType { ID = 0 };

                    cinfo.Amps = int.Parse(port["Current"].ToString());
                    cinfo.Voltage = int.Parse(port["Voltage"].ToString());
                    cinfo.PowerKW = double.Parse(port["KiloWatts"].ToString());
                    cinfo.Level = new ChargerType() { ID = int.Parse(port["Level"].ToString()) };
                    //cinfo.Comments = (port["Make"]!=null?port["Make"].ToString()+" ":"") + (port["Model"]!=null?port["Model"].ToString():"");

                    if (port["ConnectorType"].ToString() == "J1772")
                    {
                        cType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.ID == 1);
                    }
                    else if (port["ConnectorType"].ToString().ToUpper() == "CHADEMO")
                    {
                        cType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.ID == 2);//CHADEMO
                    }
                    else
                    {
                        System.Diagnostics.Debug.WriteLine("Unmatched connector" + port["ConnectorType"].ToString());
                    }

                    cinfo.ConnectionType = cType;

                    if (cp.Connections == null)
                    {
                        cp.Connections = new List<ConnectionInfo>();
                        if (!IsConnectionInfoBlank(cinfo))
                        {
                            cp.Connections.Add(cinfo);
                        }
                    }
                }

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 4;

                cp.SubmissionStatus = submissionStatus;

                outputList.Add(cp);
                itemCount++;
            }

            return outputList;
        }
Beispiel #18
0
        public void ProcessEditQueueItem(int id, bool publishEdit, int userId)
        {
            //check current user is authorized to approve edits

            //prepare poi details

            var queueItem = DataModel.EditQueueItems.FirstOrDefault(e => e.ID == id);

            if (queueItem != null && queueItem.IsProcessed == false)
            {
                if (queueItem.EntityType.ID == (int)StandardEntityTypes.POI)
                {
                    //processing a POI add/edit

                    if (publishEdit)
                    {
                        //get diff between previous and edit

                        POIManager        poiManager = new POIManager();
                        Model.ChargePoint poiA       = DeserializePOIFromJSON(queueItem.PreviousData);
                        Model.ChargePoint poiB       = DeserializePOIFromJSON(queueItem.EditData);

                        bool poiUpdateRequired = false;

                        if (poiA != null)
                        {
                            //this is an edit, load the latest version of the POI as version 'A'
                            poiA = poiManager.Get(poiA.ID);
                            if (poiManager.HasDifferences(poiA, poiB))
                            {
                                poiUpdateRequired = true;
                            }
                        }

                        //save poi update
                        var poiData = new Core.Data.ChargePoint();

                        //if its an edit, load the original details before applying the change
                        if (poiUpdateRequired)
                        {
                            //updates to externally provided POIs require old version to be superseded (archived) first
                            if (poiA != null && poiA.DataProviderID != (int)StandardDataProviders.OpenChargeMapContrib)
                            {
                                poiManager.SupersedePOI(DataModel, poiA, poiB);
                            }
                            poiData = DataModel.ChargePoints.First(c => c.ID == poiB.ID);
                        }

                        //set/update cp properties
                        poiManager.PopulateChargePoint_SimpleToData(poiB, poiData, DataModel);

                        //set status type to published if previously unset
                        if (poiData.SubmissionStatusTypeID == null)
                        {
                            poiData.SubmissionStatusType = DataModel.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Submitted_Published);
                        }

                        poiData.DateLastStatusUpdate = DateTime.UtcNow;

                        //publish edit
                        DataModel.SaveChanges();

                        //attribute submitter with reputation points
                        if (queueItem.UserID != null)
                        {
                            new UserManager().AddReputationPoints((int)queueItem.UserID, 1);
                        }
                    }

                    //update edit queue item as processed
                    queueItem.IsProcessed     = true;
                    queueItem.ProcessedByUser = DataModel.Users.FirstOrDefault(u => u.ID == userId);
                    queueItem.DateProcessed   = DateTime.UtcNow;
                    DataModel.SaveChanges();

                    CacheManager.RefreshCachedPOIList();
                }
            }
        }
Beispiel #19
0
        /// <summary>
        /// Consumers should prepare a new/updated ChargePoint with as much info populated as possible
        /// </summary>
        /// <param name="submission">ChargePoint info for submission, if ID and UUID set will be treated as an update</param>
        /// <returns>false on error or not enough data supplied</returns>
        public async Task <ValidationResult> PerformPOISubmission(Model.ChargePoint updatedPOI, Model.User user, bool performCacheRefresh = true, bool disablePOISuperseding = false)
        {
            try
            {
                var  poiManager             = new POIManager();
                bool enableEditQueueLogging = bool.Parse(ConfigurationManager.AppSettings["EnableEditQueue"]);
                bool isUpdate = false;
                bool userCanEditWithoutApproval = false;
                bool isSystemUser = false;
                int? supersedesID = null;//POI from another data provider which has been superseded by an edit

                //if user signed in, check if they have required permission to perform an edit/approve (if required)
                if (user != null)
                {
                    if (user.ID == (int)StandardUsers.System)
                    {
                        isSystemUser = true;
                    }

                    //if user is system user, edits/updates are not recorded in edit queue
                    if (isSystemUser)
                    {
                        enableEditQueueLogging = false;
                    }

                    userCanEditWithoutApproval = POIManager.CanUserEditPOI(updatedPOI, user);
                }

                var dataModel = new Core.Data.OCMEntities();

                //if poi is an update, validate if update can be performed
                if (updatedPOI.ID > 0 && !String.IsNullOrEmpty(updatedPOI.UUID))
                {
                    if (dataModel.ChargePoints.Any(c => c.Id == updatedPOI.ID && c.Uuid == updatedPOI.UUID))
                    {
                        //update is valid poi, check if user has permission to perform an update
                        isUpdate = true;
                        if (userCanEditWithoutApproval)
                        {
                            AllowUpdates = true;
                        }
                        if (!AllowUpdates && !enableEditQueueLogging)
                        {
                            //valid update requested but updates not allowed
                            return(new ValidationResult {
                                IsValid = false, Message = "Updates are disabled"
                            });
                        }
                    }
                    else
                    {
                        //update does not correctly identify an existing poi
                        return(new ValidationResult {
                            IsValid = false, Message = "Update does not correctly match an existing POI"
                        });
                    }
                }

                //validate if minimal required data is present
                if (updatedPOI.AddressInfo.Title == null || (updatedPOI.AddressInfo.Country == null && updatedPOI.AddressInfo.CountryID == null))
                {
                    return(new ValidationResult {
                        IsValid = false, Message = "Update failed basic validation"
                    });
                }

                //convert to DB version of POI and back so that properties are fully populated
                using (var refDataManager = new ReferenceDataManager())
                {
                    var refData = await refDataManager.GetCoreReferenceDataAsync();

                    updatedPOI = PopulateFullPOI(updatedPOI, refData);
                }

                Model.ChargePoint oldPOI = null;

                if (updatedPOI.ID > 0)
                {
                    //get json snapshot of current cp data to store as 'previous'
                    oldPOI = await poiManager.Get(updatedPOI.ID);
                }

                //if user cannot edit directly, add to edit queue for approval
                var editQueueItem = new Core.Data.EditQueueItem {
                    DateSubmitted = DateTime.UtcNow
                };
                if (enableEditQueueLogging)
                {
                    editQueueItem.EntityId   = updatedPOI.ID;
                    editQueueItem.EntityType = dataModel.EntityTypes.FirstOrDefault(t => t.Id == 1);
                    //charging point location entity type id

                    //serialize cp as json

                    //null extra data we don't want to serialize/compare
                    updatedPOI.UserComments = null;
                    updatedPOI.MediaItems   = null;

                    string editData = PerformSerialisationToString(updatedPOI, new JsonSerializerSettings {
                        NullValueHandling = NullValueHandling.Ignore
                    });

                    editQueueItem.EditData = editData;

                    if (updatedPOI.ID > 0)
                    {
                        //check if poi will change with this edit, if not we discard it completely
                        if (!poiManager.HasDifferences(oldPOI, updatedPOI))
                        {
                            System.Diagnostics.Debug.WriteLine("POI Update has no changes, discarding change.");
                            return(new ValidationResult {
                                IsValid = true, ItemId = updatedPOI.ID, Message = "No POI changes detected"
                            });
                        }
                        else
                        {
                            editQueueItem.PreviousData = PerformSerialisationToString(oldPOI, new JsonSerializerSettings {
                                NullValueHandling = NullValueHandling.Ignore
                            });
                        }
                    }

                    if (user != null)
                    {
                        editQueueItem.User = dataModel.Users.FirstOrDefault(u => u.Id == user.ID);
                    }
                    var processedByUser = editQueueItem.User ?? dataModel.Users.FirstOrDefault(u => u.Id == (int)StandardUsers.System);

                    editQueueItem.IsProcessed = false;
                    dataModel.EditQueueItems.Add(editQueueItem);
                    //TODO: send notification of new item for approval

                    //save edit queue item
                    dataModel.SaveChanges();

                    //if previous edit queue item exists by same user for same POI, mark as processed
                    var previousEdits = dataModel.EditQueueItems.Where(e => e.UserId == editQueueItem.UserId && e.EntityId == editQueueItem.EntityId && e.EntityTypeId == editQueueItem.EntityTypeId && e.Id != editQueueItem.Id && e.IsProcessed != true);
                    foreach (var previousEdit in previousEdits)
                    {
                        previousEdit.IsProcessed     = true;
                        previousEdit.ProcessedByUser = processedByUser;

                        previousEdit.DateProcessed = DateTime.UtcNow;
                    }
                    //save updated edit queue items
                    dataModel.SaveChanges();
                }

                //prepare and save changes POI changes/addition
                if (isUpdate && !AllowUpdates)
                {
                    //user has submitted an edit but is not an approved editor
                    //SendEditSubmissionNotification(updatedPOI, user);

                    //user is not an editor, item is now pending in edit queue for approval.
                    return(new ValidationResult {
                        IsValid = true, ItemId = updatedPOI.ID, Message = "Update submitted for review"
                    });
                }

                if (isUpdate && updatedPOI.SubmissionStatusTypeID >= 1000)
                {
                    //update is a delisting, skip superseding poi
                    System.Diagnostics.Debug.WriteLine("skipping superseding of imported POI due to delisting");
                }
                else
                {
                    //if poi being updated exists from an imported source we supersede the old POI with the new version, unless we're doing a fresh import from same data provider
                    if (!disablePOISuperseding)
                    {
                        //if update by non-system user will change an imported/externally provided data, supersede old POI with new one (retain ID against new POI)
                        if (isUpdate && !isSystemUser && oldPOI.DataProviderID != (int)StandardDataProviders.OpenChargeMapContrib)
                        {
                            //move old poi to new id, set status of new item to superseded
                            supersedesID = poiManager.SupersedePOI(dataModel, oldPOI, updatedPOI);
                        }
                    }
                }

                //user is an editor, go ahead and store the addition/update
                //set/update cp properties
                var cpData = poiManager.PopulateChargePoint_SimpleToData(updatedPOI, dataModel);

                //if item has no submission status and user permitted to edit, set to published
                if (userCanEditWithoutApproval && cpData.SubmissionStatusTypeId == null)
                {
                    cpData.SubmissionStatusTypeId = (int)StandardSubmissionStatusTypes.Submitted_Published; //hack due to conflicting state change for SubmissionStatusType
                }
                else
                {
                    //no submission status, set to 'under review'
                    if (cpData.SubmissionStatusTypeId == null)
                    {
                        cpData.SubmissionStatusTypeId = (int)StandardSubmissionStatusTypes.Submitted_UnderReview;
                    }
                }

                cpData.DateLastStatusUpdate = DateTime.UtcNow;

                if (!isUpdate)
                {
                    //new data objects need added to data model before save
                    if (cpData.AddressInfo != null)
                    {
                        dataModel.AddressInfos.Add(cpData.AddressInfo);
                    }

                    dataModel.ChargePoints.Add(cpData);
                }

                //finally - save poi update
                dataModel.SaveChanges();

                //get id of update/new poi
                int newPoiID = cpData.Id;

                //this is an authorised update, reflect change in edit queue item
                if (enableEditQueueLogging && user != null && user.ID > 0)
                {
                    var editUser = dataModel.Users.FirstOrDefault(u => u.Id == user.ID);
                    editQueueItem.User = editUser;

                    if (newPoiID > 0)
                    {
                        editQueueItem.EntityId = newPoiID;
                    }

                    //if user is authorised to edit, process item automatically without review
                    if (userCanEditWithoutApproval)
                    {
                        editQueueItem.ProcessedByUser = editUser;
                        editQueueItem.DateProcessed   = DateTime.UtcNow;
                        editQueueItem.IsProcessed     = true;
                    }

                    //save edit queue item changes
                    dataModel.SaveChanges();
                }
                else
                {
                    //anonymous submission, update edit queue item
                    if (enableEditQueueLogging && user == null)
                    {
                        if (newPoiID > 0)
                        {
                            editQueueItem.EntityId = newPoiID;
                        }
                        dataModel.SaveChanges();
                    }
                }

                System.Diagnostics.Debug.WriteLine("Added/Updated CP:" + cpData.Id);

                //if user is not anonymous, log their submission and update their reputation points
                if (user != null)
                {
                    AuditLogManager.Log(user, isUpdate ? AuditEventType.UpdatedItem : AuditEventType.CreatedItem, "Modified OCM-" + cpData.Id, null);
                    //add reputation points
                    new UserManager().AddReputationPoints(user, 1);
                }

                //preserve new POI Id for caller
                updatedPOI.ID = cpData.Id;

                if (performCacheRefresh)
                {
                    if (supersedesID != null)
                    {
                        await CacheManager.RefreshCachedPOI((int)supersedesID);
                    }
                    await CacheManager.RefreshCachedPOI(updatedPOI.ID);
                }

                return(new ValidationResult {
                    IsValid = true, ItemId = updatedPOI.ID, Message = "Update submitted."
                });
            }
            catch (Exception exp)
            {
                System.Diagnostics.Debug.WriteLine(exp.ToString());
                AuditLogManager.ReportWebException(true, null, AuditEventType.SystemErrorWeb, "POI Submission Failed", exp);

                //error performing submission
                return(new ValidationResult {
                    IsValid = false, Message = "Submission Failed with an Exception: " + exp.Message
                });
            }
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            //TODO: operator not well matched, usage type not known, multiple connectors at same site not imported due to duplicate POI. Requires merge process.
            List<ChargePoint> outputList = new List<ChargePoint>();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            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 usageTypePrivateForStaffAndVisitors = coreRefData.UsageTypes.First(u => u.ID == 6); //staff and visitors
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;

            string jsonString = "{ \"data\": " + InputData + "}";

            JObject o = JObject.Parse(jsonString);
            var dataList = o.Values().First().ToArray();

            var distinctCountries = new List<string>();
            foreach (var item in dataList)
            {
                /*
                 * {
              "id": "5813",
              "lng": "5.14287",
              "lat": "52.07858",
              "name": "NewMotion NL-TNM-FC11",
              "address": "Herculesplein 300",
              "postalcode": "3584 AA",
              "city": "Utrecht",
              "country": "NL",
              "phone": "",
              "url": "",
              "owner": "BP",
              "email": "",
              "opentimes": "ma-vr:6:00-23.30 za-zo:8:00-23.30 ",
              "chargetype": "DC snellader",
              "connectortype": "chademo",
              "nroutlets": "2",
              "cards": [
            "contant"
              ],
              "pricemethod": "per laadbeurt",
              "price": "6.00",
              "power": "50kW",
              "vehicle": "auto",
              "facilities": [
            "wifi",
            "wc",
            "parkeer",
            "restaurant",
            "wachtruimte",
            "koffiecorner",
            "shop",
            "openbaar vervoer"
              ],
              "realtimestatus": false
            }*/
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //AddEnergie
                cp.DataProvidersReference = item["id"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;

                cp.AddressInfo = new AddressInfo();

                cp.AddressInfo.Title = item["address"].ToString();
                cp.OperatorsReference = item["name"].ToString();

                cp.AddressInfo.AddressLine1 = item["address"].ToString().Trim();
                cp.AddressInfo.Town = item["city"].ToString().Trim();
                //cp.AddressInfo.StateOrProvince = item["StateOrProvince"].ToString().Trim();
                cp.AddressInfo.Postcode = item["postalcode"].ToString().Trim();
                cp.AddressInfo.Latitude = double.Parse(item["lat"].ToString());
                cp.AddressInfo.Longitude = double.Parse(item["lng"].ToString());

                var countryCode = item["country"].ToString().ToLower();

                if (!distinctCountries.Exists(c=>c==countryCode)) distinctCountries.Add(countryCode);

                //fix incorrect country codes
                if (countryCode == "au") countryCode = "at"; //austria, not australia
                if (countryCode == "ml") countryCode = "mt"; //malta, not mali
                if (countryCode == "tu") countryCode = "tr"; //turkey
                if (countryCode == "ad") countryCode = "";// leave for geocoding, probably not andorra
                if (countryCode == "sv") countryCode = "si"; //slovenia, not el salvador
                if (countryCode == "ir") countryCode = "ie"; //ireland, not iran

                cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == countryCode);
                if (!String.IsNullOrEmpty(item["url"].ToString())) cp.AddressInfo.RelatedURL = item["url"].ToString();
                if (!String.IsNullOrEmpty(item["email"].ToString())) cp.AddressInfo.ContactEmail = item["email"].ToString();
                if (!String.IsNullOrEmpty(item["phone"].ToString())) cp.AddressInfo.ContactTelephone1 = item["phone"].ToString();

                var price = item["price"].ToString();
                var pricemethod = item["pricemethod"].ToString();

                cp.UsageCost = (!String.IsNullOrEmpty(price)?price+" ":"") + pricemethod;
                //set network operators
                //cp.OperatorInfo = new OperatorInfo { ID = 89 };

                //TODO: Operator, usage,price, power, connector type
                var owner = item["owner"].ToString().ToLower();
                var operatoInfo = coreRefData.Operators.FirstOrDefault(op=>op.Title.ToLower().Contains(owner));

                if (operatoInfo == null)
                {
                    Log("Unknown operator: "+owner);
                }
                else
                {
                    cp.OperatorID = operatoInfo.ID;
                }
                /*bool isPublic = bool.Parse(item["IsPublic"].ToString());
                if (isPublic)
                {
                    cp.UsageType = usageTypePublic;
                }
                else
                {
                    cp.UsageType = usageTypePrivate;
                }
                */

                cp.NumberOfPoints = int.Parse(item["nroutlets"].ToString());
                cp.StatusType = operationalStatus;

                //populate connectioninfo from Ports
                var connectorType = item["connectortype"].ToString();
                var chargetype = item["chargetype"].ToString();
                var power = item["power"].ToString();
                ConnectionInfo cinfo = new ConnectionInfo();

                try
                {
                    if (!String.IsNullOrEmpty(power))
                    {
                        cinfo.PowerKW = double.Parse(power.Replace("kW", ""));
                    }
                }
                catch (System.FormatException) { }

                if (connectorType.ToLower().Contains("j1772"))
                {
                    cinfo.ConnectionTypeID = (int)StandardConnectionTypes.J1772;
                    cinfo.LevelID = 2;
                } else  if (connectorType.ToLower().Contains("mennekes"))
                {
                    cinfo.ConnectionTypeID = (int)StandardConnectionTypes.MennekesType2;
                    cinfo.LevelID = 2;
                } else if (connectorType.ToLower().Contains("chademo"))
                {
                    cinfo.ConnectionTypeID = (int)StandardConnectionTypes.CHAdeMO;
                    cinfo.LevelID = 3;
                }
                else if (connectorType.ToLower().Contains("schuko"))
                {
                    cinfo.ConnectionTypeID = (int)StandardConnectionTypes.Schuko;
                    cinfo.LevelID = 2;
                }
                else {
                    Log("Unknown connectorType:" + connectorType);
                }

                if (cinfo.PowerKW >= 50)
                {
                    cinfo.LevelID = 3;
                }
                if (!String.IsNullOrEmpty(chargetype))
                {

                    if (chargetype.StartsWith("DC")) cinfo.CurrentTypeID = (int)StandardCurrentTypes.DC;
                    if (chargetype.StartsWith("AC simpel")) cinfo.CurrentTypeID = (int)StandardCurrentTypes.SinglePhaseAC;
                    //TODO: 3 phase?

                }

               // System.Diagnostics.Debug.WriteLine("Unknown chargetype:" + chargetype+ " "+power);

                if (cp.Connections == null)
                {
                    cp.Connections = new List<ConnectionInfo>();
                    if (!IsConnectionInfoBlank(cinfo))
                    {
                        cp.Connections.Add(cinfo);
                    }
                }

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 3;

                cp.SubmissionStatus = submissionStatus;

                outputList.Add(cp);
                itemCount++;
            }

            string temp = "";
            foreach (var countryCode in distinctCountries)
            {
                temp += ", " + countryCode;
            }
            Log("Countries in import:"+temp);

            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["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("&amp;", "&");
                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;
        }
        /// <summary>
        /// For given POI, return data quality report and supporting analysis results
        /// </summary>
        /// <param name="poi"></param>
        /// <returns></returns>
        public POIDataQualityReport CheckPOIDataQuality(OCM.API.Common.Model.ChargePoint poi)
        {
            var report = new POIDataQualityReport();

            report.POI = poi;

            DateTime recentUpdateThreshold = DateTime.UtcNow.AddMonths(-6);

            if (
                (poi.DateLastConfirmed.HasValue && !(poi.DateLastConfirmed.Value > recentUpdateThreshold))
                ||
                (poi.UserComments != null && poi.UserComments.Any(u => u.CheckinStatusType != null && u.CheckinStatusType.IsPositive == true && u.DateCreated > recentUpdateThreshold))
                ||
                (poi.MediaItems != null && poi.MediaItems.Any(u => u.DateCreated > recentUpdateThreshold))
                )
            {
                //has either a recent datelastconfirmed value or a recent positive checkin
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "User Feedback", Comment = "Has recent user verification", IsPositive = true
                });
            }
            else
            {
                //low quality score for date last confirmed
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 10, Category = "User Feedback", Comment = "No recent user verification.", IsPositive = false
                });
            }

            if (poi.UserComments == null || (poi.UserComments != null && !poi.UserComments.Any()))
            {
                //low quality score for comments
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 10, Category = "User Feedback", Comment = "No comments or check-ins", IsPositive = false
                });
            }
            else
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "User Feedback", Comment = "Has comments or check-ins", IsPositive = true
                });
            }

            if (poi.MediaItems == null || (poi.MediaItems != null && !poi.MediaItems.Any()))
            {
                //low quality score for photos
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 10, Category = "User Feedback", Comment = "No photos", IsPositive = false
                });
            }
            else
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "User Feedback", Comment = "Has photos", IsPositive = true
                });
            }

            if (poi.UsageTypeID == null || (poi.UsageTypeID != null && poi.UsageType.ID == 0))
            {
                //low quality score for usage type
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 10, Category = "Data Completeness", Comment = "Unknown Usage Type", IsPositive = false
                });
            }
            else
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "Data Completeness", Comment = "Usage Type Known", IsPositive = true
                });
            }
            if (poi.StatusType == null || (poi.StatusType != null && poi.StatusType.ID == 0))
            {
                //low quality score for status type
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 10, Category = "Data Completeness", Comment = "Unknown Operational Status", IsPositive = false
                });
            }
            else
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "Data Completeness", Comment = "Operational Status Known", IsPositive = true
                });
            }

            if (poi.Connections == null || !poi.Connections.Any())
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Weighting = 50, Category = "Data Completeness", Comment = "No Equipment Details", IsPositive = false
                });
            }
            else
            {
                report.ReportItems.Add(new DataQualityReportItem {
                    Category = "Data Completeness", Comment = "Equipment Details Present", IsPositive = true
                });
            }

            //data quality score starts at 5 (excellent) and is reduced towards 0 for each data issue

            double totalPoints = 100;

            foreach (var p in report.ReportItems.Where(r => r.IsPositive == false))
            {
                totalPoints -= p.Weighting;
            }
            if (totalPoints < 0)
            {
                totalPoints = 0;
            }
            report.DataQualityScore = totalPoints;

            return(report);
        }
        List<ChargePoint> IImportProvider.Process(CoreReferenceData coreRefData)
        {
            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            var status_operational = coreRefData.StatusTypes.First(os => os.ID == 50);
            var status_notoperational = coreRefData.StatusTypes.First(os => os.ID == 100);

            var status_operationalMixed = coreRefData.StatusTypes.First(os => os.ID == 75);
            var status_available = coreRefData.StatusTypes.First(os => os.ID == 10);
            var status_inuse = coreRefData.StatusTypes.First(os => os.ID == 20);
            var status_unknown = 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);

            JObject o = JObject.Parse(InputData);
            var dataList = o.Values()["ChargingStationList"].Values().ToArray();

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

            int itemCount = 0;

            foreach (var item in dataList)
            {
                try
                {
                    ChargePoint cp = new ChargePoint();
                    cp.AddressInfo = new AddressInfo();
                    var addressData = item["ChargingStationAddress"];
                    cp.AddressInfo.Title = addressData["Street"] != null ? addressData["Street"].ToString() : item["ChargingStationId"].ToString();
                    cp.AddressInfo.RelatedURL = "http://www.mobie.pt";

                    cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //mobie.pt
                    cp.DataProvidersReference = item["ChargingStationId"].ToString();
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    cp.AddressInfo.AddressLine1 = addressData["Street"].ToString();
                    if (addressData["Number"]!=null && addressData["Number"].ToString() != "-")
                    {
                        cp.AddressInfo.AddressLine1 += " " + addressData["Number"].ToString();
                    }

                    cp.AddressInfo.Town = addressData["City"].ToString();

                    cp.AddressInfo.Postcode = addressData["PostalCode"].ToString();
                    cp.AddressInfo.Latitude = double.Parse(item["Latitude"].ToString());
                    cp.AddressInfo.Longitude = double.Parse(item["Longitude"].ToString());
                    var countryCode = addressData["Country"].ToString();
                    var country = coreRefData.Countries.FirstOrDefault(ct => ct.ISOCode==countryCode);
                    cp.AddressInfo.Country = country;

                    cp.NumberOfPoints = int.Parse(item["TotalSattelites"].ToString());

                    cp.StatusType = status_operational;
                    string status = item["Status"].ToString().ToLower();

                    if (status == "unavailable" || status == "reserved" || status == "in use")
                    {
                        cp.StatusType = status_operational;
                    }

                    if (status == "disconnected" || status == "inactive" || status == "suspended")
                    {
                        cp.StatusType = status_notoperational;
                    }

                    string type = item["Type"].ToString();//fast or normal
                    if (type.ToLower() == "fast" || type.ToLower() == "normal")
                    {
                        //populate connections
                        cp.Connections = new List<ConnectionInfo>();

                        ConnectionInfo con = new ConnectionInfo();
                        if (String.Equals(type, "fast", StringComparison.CurrentCultureIgnoreCase))
                        {
                            con.Level = new ChargerType { ID = 3 };
                            con.Voltage = 400;
                            con.Amps = 75;
                            con.PowerKW = con.Voltage * con.Amps / 1000;
                            con.StatusType = cp.StatusType;
                            con.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                        }

                        if (String.Equals(type, "normal", StringComparison.CurrentCultureIgnoreCase))
                        {
                            con.Level = new ChargerType { ID = 2 };
                            //based on http://www.mobie.pt/en/o-carregamento
                            con.Voltage = 220;
                            con.Amps = 16;
                            con.PowerKW = con.Voltage * con.Amps / 1000;
                            con.StatusType = cp.StatusType;
                            con.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.SinglePhaseAC };
                        }
                        cp.Connections.Add(con);
                    }

                    //TODO: attempt to match operator
                    var operatorName = item["Operator"].ToString();
                    var operatorInfo = coreRefData.Operators.FirstOrDefault(op => op.Title.ToLower().StartsWith(operatorName.ToLower()));
                    if (operatorInfo != null)
                    {
                        cp.OperatorInfo = operatorInfo;
                    } else
                    {
                        this.Log("Unknown Operator:" + operatorName);
                    }
                    cp.DataQualityLevel = 3; //avg, higher than default

                    cp.SubmissionStatus = submissionStatus;

                    outputList.Add(cp);
                }
                catch (Exception exp)
                {
                    Log("Error parsing item " + itemCount+ " "+ exp.ToString());
                }

                itemCount++;
            }

            return outputList;
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            ImportCommonReferenceData importRefData = new ImportCommonReferenceData(coreRefData);
            List<ChargePoint> outputList = new List<ChargePoint>();

            string jsString = InputData;// "{ \"data\": " + InputData + "}";
            JavaScriptSerializer jss = new JavaScriptSerializer();
            jss.RegisterConverters(new JavaScriptConverter[] { new DynamicJsonConverter() });
            dynamic parsedList = jss.Deserialize(jsString, typeof(object)) as dynamic;

            var dataList = parsedList.chargingstations;

            int itemCount = 0;
            foreach (var item in dataList)
            {
                /*
                 * {
               "chargingstations":[
                  {
                     "id":"14249",
                     "oid":"EM-NL-00000363-06-00006",
                     "brand":"Station City of Amsterdam",
                     "location_name":null,
                     "location_name_lang":null,
                     "latitude":52.401097,
                     "longitude":4.932926,
                     "street":"Buikslotermeerplein",
                     "house_number":"2000",
                     "postal_code":"1025 XL",
                     "city":"Amsterdam",
                     "country":"Netherlands",
                     "country_iso":"NLD",
                     "phone":"00318003773683",
                     "ac":true,
                     "dc":false,
                     "free":true,
                     "occupied":false,
                     "spotIds":"BA-3665-1, BA-3066-8"
                  },
                 * */
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = 21 }; //rwe-mobility
                cp.DataProvidersReference = item["id"].ToString();
                cp.OperatorsReference = item["oid"].ToString();
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo = new AddressInfo();

                try
                {

                    cp.AddressInfo.Title = item["location_name"] != null ? item["location_name"].ToString() : (item["brand"] != null ? item["brand"].ToString() : item["street"]);
                    cp.AddressInfo.Title = cp.AddressInfo.Title.Trim().Replace("&amp;", "&");
                }
                catch (Exception)
                {
                    //could not get a location title
                    System.Diagnostics.Debug.WriteLine("No title for item: " + cp.DataProvidersReference);
                }
                //cp.AddressInfo.RelatedURL = item["url"].ToString();

                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo.AddressLine1 = item["house_number"] != null ? item["house_number"] + " " + item["street"].ToString() : item["street"].ToString().Trim();
                cp.AddressInfo.Town = item["city"].ToString().Trim();
                if (!String.IsNullOrEmpty(item["postal_code"])) cp.AddressInfo.Postcode = item["postal_code"].ToString().Trim();
                if (String.IsNullOrEmpty(cp.AddressInfo.Title)) cp.AddressInfo.Title = cp.AddressInfo.Town;

                cp.AddressInfo.Latitude = double.Parse(item["latitude"].ToString());
                cp.AddressInfo.Longitude = double.Parse(item["longitude"].ToString());

                if (item["phone"] != null)
                {
                    cp.AddressInfo.ContactTelephone1 = item["phone"].ToString();
                }

                //default to norway
                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);
                }

                cp.UsageType = null;
                //TODO:identify usage type, number of points, connections

                cp.NumberOfPoints = 1;
                cp.StatusType = importRefData.Status_Operational;

                if (cp.DataQualityLevel == null) cp.DataQualityLevel = 2;

                cp.SubmissionStatus = importRefData.SubmissionStatus_ImportedAndPublished;

                outputList.Add(cp);
                itemCount++;
            }

            return outputList;
        }
Beispiel #25
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;
            }
        }
Beispiel #26
0
        public bool MergeItemChanges(ChargePoint sourceItem, ChargePoint destItem, bool statusOnly)
        {
            //TODO: move to POIManager or a common base?
            bool hasDifferences = true;
            //var diffs = GetDifferingProperties(sourceItem, destItem);

            //merge changes in sourceItem into destItem, preserving destItem ID's
            if (!statusOnly)
            {
                //update addressinfo
                destItem.AddressInfo.Title = sourceItem.AddressInfo.Title;
                destItem.AddressInfo.AddressLine1 = sourceItem.AddressInfo.AddressLine1;
                destItem.AddressInfo.AddressLine2 = sourceItem.AddressInfo.AddressLine2;
                destItem.AddressInfo.Town = sourceItem.AddressInfo.Town;
                destItem.AddressInfo.StateOrProvince = sourceItem.AddressInfo.StateOrProvince;
                destItem.AddressInfo.Postcode = sourceItem.AddressInfo.Postcode;
                destItem.AddressInfo.RelatedURL = sourceItem.AddressInfo.RelatedURL;
                if (sourceItem.AddressInfo.Country != null) destItem.AddressInfo.Country = sourceItem.AddressInfo.Country;
                destItem.AddressInfo.CountryID = sourceItem.AddressInfo.CountryID;

                destItem.AddressInfo.AccessComments = sourceItem.AddressInfo.AccessComments;
                destItem.AddressInfo.ContactEmail = sourceItem.AddressInfo.ContactEmail;
                destItem.AddressInfo.ContactTelephone1 = sourceItem.AddressInfo.ContactTelephone1;
                destItem.AddressInfo.ContactTelephone2 = sourceItem.AddressInfo.ContactTelephone2;
#pragma warning disable 0612
                destItem.AddressInfo.GeneralComments = sourceItem.AddressInfo.GeneralComments;
#pragma warning restore 0612
                destItem.AddressInfo.Latitude = sourceItem.AddressInfo.Latitude;
                destItem.AddressInfo.Longitude = sourceItem.AddressInfo.Longitude;

                //update general
                destItem.DataProvider = sourceItem.DataProvider;
                destItem.DataProviderID = sourceItem.DataProviderID;
                destItem.DataProvidersReference = sourceItem.DataProvidersReference;
                destItem.OperatorID = sourceItem.OperatorID;
                destItem.OperatorInfo = sourceItem.OperatorInfo;
                destItem.OperatorsReference = sourceItem.OperatorsReference;
                destItem.UsageType = sourceItem.UsageType;
                destItem.UsageTypeID = sourceItem.UsageTypeID;
                destItem.UsageCost = sourceItem.UsageCost;
                destItem.NumberOfPoints = sourceItem.NumberOfPoints;
                destItem.GeneralComments = sourceItem.GeneralComments;
                destItem.DateLastConfirmed = sourceItem.DateLastConfirmed;
                //destItem.DateLastStatusUpdate = sourceItem.DateLastStatusUpdate;
                destItem.DatePlanned = sourceItem.DatePlanned;

                //update connections
                //TODO:: update connections
                var connDeleteList = new List<ConnectionInfo>();
                if (sourceItem.Connections != null)
                {
                    if (destItem.Connections == null)
                    {
                        destItem.Connections = sourceItem.Connections;
                    }
                    else
                    {
                        var equipmentIndex = 0;
                        foreach (var conn in sourceItem.Connections)
                        {
                            //imported equipment info is replaced in order they appear in the import
                            //TODO: if the connection type/power rating has changed we need to create new equipment
                            // rather than update existing as this is probably a physically different equipment installation

                            ConnectionInfo existingConnection = null;

                            existingConnection = destItem.Connections.FirstOrDefault(d => d.Reference == conn.Reference && !String.IsNullOrEmpty(conn.Reference));
                            if (existingConnection == null)
                            {
                                if (destItem.Connections != null && destItem.Connections.Count >= (equipmentIndex + 1))
                                {
                                    existingConnection = destItem.Connections[equipmentIndex];
                                }
                                equipmentIndex++;
                            }

                            if (existingConnection != null)
                            {
                                //update existing- updates can be either object base reference data or use ID values
                                existingConnection.ConnectionType = conn.ConnectionType;
                                existingConnection.ConnectionTypeID = conn.ConnectionTypeID;
                                existingConnection.Quantity = conn.Quantity;
                                existingConnection.LevelID = conn.LevelID;
                                existingConnection.Level = conn.Level;
                                existingConnection.Reference = conn.Reference;
                                existingConnection.StatusTypeID = conn.StatusTypeID;
                                existingConnection.StatusType = conn.StatusType;
                                existingConnection.Voltage = conn.Voltage;
                                existingConnection.Amps = conn.Amps;
                                existingConnection.PowerKW = conn.PowerKW;
                                existingConnection.Comments = conn.Comments;
                                existingConnection.CurrentType = conn.CurrentType;
                                existingConnection.CurrentTypeID = conn.CurrentTypeID;
                            }
                            else
                            {
                                //add new
                                destItem.Connections.Add(conn);
                            }
                        }
                    }
                }
            }
            if (sourceItem.StatusType != null) destItem.StatusType = sourceItem.StatusType;

            return hasDifferences;
        }
        public void ProcessEditQueueItem(int id, bool publishEdit, int userId)
        {
            //prepare poi details
            int updatePOIId = 0;
            var queueItem   = DataModel.EditQueueItems.FirstOrDefault(e => e.ID == id);

            if (queueItem != null && queueItem.IsProcessed == false)
            {
                if (queueItem.EntityType.ID == (int)StandardEntityTypes.POI)
                {
                    //check current user is authorized to approve edits for this POIs country
                    bool hasEditPermission = false;
                    var  editPOI           = DeserializePOIFromJSON(queueItem.EditData);
                    var  userProfile       = new UserManager().GetUser(userId);
                    if (userProfile != null)
                    {
                        if (UserManager.HasUserPermission(userProfile, editPOI.AddressInfo.CountryID, PermissionLevel.Editor))
                        {
                            hasEditPermission = true;
                        }
                    }

                    //processing a POI add/edit
                    if (hasEditPermission)
                    {
                        if (publishEdit)
                        {
                            //get diff between previous and edit

                            POIManager        poiManager = new POIManager();
                            Model.ChargePoint poiA       = DeserializePOIFromJSON(queueItem.PreviousData);
                            Model.ChargePoint poiB       = DeserializePOIFromJSON(queueItem.EditData);

                            bool poiUpdateRequired = false;

                            if (poiA != null)
                            {
                                //this is an edit, load the latest version of the POI as version 'A'
                                poiA = poiManager.Get(poiA.ID);
                                if (poiManager.HasDifferences(poiA, poiB))
                                {
                                    poiUpdateRequired = true;
                                }
                            }

                            //save poi update
                            //if its an edit, load the original details before applying the change
                            if (poiUpdateRequired)
                            {
                                //updates to externally provided POIs require old version to be superseded (archived) first
                                if (poiA != null && poiA.DataProviderID != (int)StandardDataProviders.OpenChargeMapContrib)
                                {
                                    poiManager.SupersedePOI(DataModel, poiA, poiB);
                                }
                            }

                            //set/update cp properties from simple model to data model
                            var poiData = poiManager.PopulateChargePoint_SimpleToData(poiB, DataModel);

                            //set status type to published if previously unset
                            if (poiData.SubmissionStatusTypeID == null)
                            {
                                poiData.SubmissionStatusType = DataModel.SubmissionStatusTypes.First(s => s.ID == (int)StandardSubmissionStatusTypes.Submitted_Published);
                            }

                            poiData.DateLastStatusUpdate = DateTime.UtcNow;

                            //publish edit
                            DataModel.SaveChanges();

                            updatePOIId = poiData.ID;

                            //attribute submitter with reputation points
                            if (queueItem.UserID != null)
                            {
                                new UserManager().AddReputationPoints((int)queueItem.UserID, 1);
                            }
                        }

                        //update edit queue item as processed
                        queueItem.IsProcessed     = true;
                        queueItem.ProcessedByUser = DataModel.Users.FirstOrDefault(u => u.ID == userId);
                        queueItem.DateProcessed   = DateTime.UtcNow;
                        DataModel.SaveChanges();

                        //TODO: also award processing editor with reputation points if they are approving someone elses edit and they are not Admin

                        //Refresh POI cache
                        Task cacheRefresh = CacheManager.RefreshCachedPOI(updatePOIId);
                    }
                }
            }
        }
        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}";

            //get import column mappings from JSON format config item into a Dictionary
            IDictionary<string, JToken> tmpMap = JObject.Parse(importMappingJSON);
            Dictionary<string, int> importMappings = 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;

                    //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 textArray = new string[headerCells.Count];
                            for (int i = 0; i < textArray.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)
                                {
                                    textArray[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 (textArray.Any(t=>t!=null))
                            {
                                //load import row values from value in worksheet row
                                import.DataProvidersReference = textArray[importMappings["ID"]];
                                import.DataQualityLevel = 3;

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

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

                                import.AddressInfo = new AddressInfo();
                                import.AddressInfo.Title = textArray[importMappings["LocationTitle"]];
                                import.AddressInfo.AddressLine1 = textArray[importMappings["AddressLine1"]];
                                import.AddressInfo.AddressLine2 = textArray[importMappings["AddressLine2"]];
                                import.AddressInfo.Town = textArray[importMappings["Town"]];
                                import.AddressInfo.StateOrProvince = textArray[importMappings["StateOrProvince"]];
                                import.AddressInfo.Postcode = textArray[importMappings["Postcode"]];

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

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

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

                                if (import.Connections == null) import.Connections = new List<ConnectionInfo>();

                                //connection info 1

                                if (textArray[importMappings["Connection1_Type"]] != null)
                                {
                                    var conn = new ConnectionInfo();
                                    conn.ConnectionType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.Title == textArray[importMappings["Connection1_Type"]]);
                                    import.Connections.Add(conn);
                                }
                                if (textArray[importMappings["Connection2_Type"]] != null)
                                {
                                    var conn = new ConnectionInfo();
                                    conn.ConnectionType = coreRefData.ConnectionTypes.FirstOrDefault(c => c.Title == textArray[importMappings["Connection2_Type"]]);
                                    import.Connections.Add(conn);
                                }

                            }
                            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;
        }
Beispiel #29
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;
            }
        }
Beispiel #30
0
        /// <summary>
        /// Handle input to API
        /// </summary>
        /// <param name="context"></param>
        private void PerformInput(HttpContext context)
        {
            OCM.API.InputProviders.IInputProvider inputProvider = null;
            bool performSubmissionCompletedRedirects = false;

            if (context.Request["format"] == "json")
            {
                inputProvider = new InputProviders.JSONInputProvider();
            }
            else
            {
                inputProvider = new InputProviders.HTMLFormInputProvider();
                performSubmissionCompletedRedirects = true;
            }
            SubmissionManager submissionManager = new SubmissionManager();

            //attempt to determine user from api call
            User user = inputProvider.GetUserFromAPICall(context);

            if (user != null && user.IsCurrentSessionTokenValid == false)
            {
                //session token provided didn't match latest in user details, reject user details.
                context.Response.StatusCode = 401;
            }
            else
            {
                //gather input variables
                if (context.Request["action"] == "cp_submission")
                {
                    //gather/process data for submission
                    OCM.API.Common.Model.ChargePoint cp = new Common.Model.ChargePoint();

                    bool processedOK = inputProvider.ProcessEquipmentSubmission(context, ref cp);
                    bool submittedOK = false;

                    if (processedOK == true)
                    {
                        //perform submission

                        int submissionId = submissionManager.PerformPOISubmission(cp, user);
                        if (submissionId > -1) submittedOK = true;
                    }

                    if (processedOK && submittedOK)
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            if (submittedOK)
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/complete.aspx", true);
                            }
                            else
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                            }
                        }
                        else
                        {
                            context.Response.StatusCode = 202;
                            //context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                        }
                    }
                    else
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                        }
                        else
                        {
                            context.Response.StatusCode = 500;
                            //context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                        }
                    }
                }

                if (context.Request["action"] == "comment_submission")
                {
                    UserComment comment = new UserComment();
                    bool processedOK = inputProvider.ProcessUserCommentSubmission(context, ref comment);
                    if (processedOK == true)
                    {
                        //perform submission
                        int result = submissionManager.PerformSubmission(comment, user);

                        if (result >= 0)
                        {
                            context.Response.Write("OK:" + result);
                        }
                        else
                        {
                            context.Response.Write("Error:" + result);
                        }
                    }
                    else
                    {
                        context.Response.Write("Error: Validation Failed");
                    }
                }

                if (context.Request["action"] == "contactus_submission")
                {
                    ContactSubmission contactSubmission = new ContactSubmission();
                    bool processedOK = inputProvider.ProcessContactUsSubmission(context, ref contactSubmission);

                    bool resultOK = submissionManager.SendContactUsMessage(contactSubmission.Name, contactSubmission.Email, contactSubmission.Comment);
                    if (resultOK == true)
                    {
                        context.Response.Write("OK");
                    }
                    else
                    {
                        context.Response.Write("Error");
                    }
                }

                if (context.Request["action"] == "mediaitem_submission")
                {
                    var p = inputProvider as OCM.API.InputProviders.HTMLFormInputProvider;
                    MediaItem m = new MediaItem();
                    bool accepted = false;
                    string msg = "";
                    try
                    {
                        accepted = p.ProcessMediaItemSubmission(context, ref m, user.ID);
                    }
                    catch (Exception exp)
                    {
                        msg += exp.ToString();
                    }
                    if (accepted)
                    {
                        submissionManager.PerformSubmission(m, user);
                        //OutputSubmissionReceivedMessage(context, "OK :" + m.ID, true);
                        context.Response.Write("OK");
                    }
                    else
                    {
                        //OutputBadRequestMessage(context, "Error, could not accept submission: " + msg);
                        context.Response.Write("Error");
                    }
                }
            }
        }
Beispiel #31
0
        /// <summary>
        /// Handle input to API
        /// </summary>
        /// <param name="context"></param>
        private void PerformInput(HttpContext context)
        {
            OCM.API.InputProviders.IInputProvider inputProvider = null;
            bool performSubmissionCompletedRedirects            = false;

            if (context.Request["format"] == "json")
            {
                inputProvider = new InputProviders.JSONInputProvider();
            }
            else
            {
                inputProvider = new InputProviders.HTMLFormInputProvider();
                performSubmissionCompletedRedirects = true;
            }
            SubmissionManager submissionManager = new SubmissionManager();

            //attempt to determine user from api call
            User user = inputProvider.GetUserFromAPICall(context);

            if (user != null && user.IsCurrentSessionTokenValid == false)
            {
                //session token provided didn't match latest in user details, reject user details.
                context.Response.StatusCode = 401;
            }
            else
            {
                //gather input variables
                if (context.Request["action"] == "cp_submission")
                {
                    //gather/process data for submission
                    OCM.API.Common.Model.ChargePoint cp = new Common.Model.ChargePoint();

                    bool processedOK = inputProvider.ProcessEquipmentSubmission(context, ref cp);
                    bool submittedOK = false;

                    if (processedOK == true)
                    {
                        //perform submission

                        int submissionId = submissionManager.PerformPOISubmission(cp, user);
                        if (submissionId > -1)
                        {
                            submittedOK = true;
                        }
                    }

                    if (processedOK && submittedOK)
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            if (submittedOK)
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/complete.aspx", true);
                            }
                            else
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                            }
                        }
                        else
                        {
                            context.Response.StatusCode = 202;
                            //context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                        }
                    }
                    else
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                        }
                        else
                        {
                            context.Response.StatusCode = 500;
                            //context.Response.AddHeader("Access-Control-Allow-Origin", "*");
                        }
                    }
                }

                if (context.Request["action"] == "comment_submission")
                {
                    UserComment comment     = new UserComment();
                    bool        processedOK = inputProvider.ProcessUserCommentSubmission(context, ref comment);
                    if (processedOK == true)
                    {
                        //perform submission
                        int result = submissionManager.PerformSubmission(comment, user);

                        if (result >= 0)
                        {
                            context.Response.Write("OK:" + result);
                        }
                        else
                        {
                            context.Response.Write("Error:" + result);
                        }
                    }
                    else
                    {
                        context.Response.Write("Error: Validation Failed");
                    }
                }

                if (context.Request["action"] == "contactus_submission")
                {
                    ContactSubmission contactSubmission = new ContactSubmission();
                    bool processedOK = inputProvider.ProcessContactUsSubmission(context, ref contactSubmission);

                    bool resultOK = submissionManager.SendContactUsMessage(contactSubmission.Name, contactSubmission.Email, contactSubmission.Comment);
                    if (resultOK == true)
                    {
                        context.Response.Write("OK");
                    }
                    else
                    {
                        context.Response.Write("Error");
                    }
                }

                if (context.Request["action"] == "mediaitem_submission")
                {
                    var       p        = inputProvider as OCM.API.InputProviders.HTMLFormInputProvider;
                    MediaItem m        = new MediaItem();
                    bool      accepted = false;
                    string    msg      = "";
                    try
                    {
                        accepted = p.ProcessMediaItemSubmission(context, ref m, user.ID);
                    }
                    catch (Exception exp)
                    {
                        msg += exp.ToString();
                    }
                    if (accepted)
                    {
                        submissionManager.PerformSubmission(m, user);
                        //OutputSubmissionReceivedMessage(context, "OK :" + m.ID, true);
                        context.Response.Write("OK");
                    }
                    else
                    {
                        //OutputBadRequestMessage(context, "Error, could not accept submission: " + msg);
                        context.Response.Write("Error");
                    }
                }
            }
        }
 public override void ParseAdditionalData(ChargePoint cp, XmlNode item, CoreReferenceData coreRefData)
 {
 }
        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;
        }
 public override void SetDataProviderDetails(ChargePoint cp, XmlNode item)
 {
     cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //CHAdeMO.com
     //invent unique id by hashing location title
     cp.DataProvidersReference = CalculateMD5Hash(RemoveFormattingCharacters(item["name"].InnerText));
 }
Beispiel #35
0
        public bool UpdateItem(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;
            }
        }
Beispiel #36
0
        /// <summary>
        /// Handle input to API
        /// </summary>
        /// <param name="context"></param>
        private void PerformInput(HttpContext context)
        {
            if (!bool.Parse(ConfigurationManager.AppSettings["EnableDataWrites"]))
            {
                OutputBadRequestMessage(context, "API is read only. Submissions not currently being accepted.");
                return;
            }
            OCM.API.InputProviders.IInputProvider inputProvider = null;

            var filter = new APIRequestParams();

            //set defaults
            filter.ParseParameters(context);

            //override ?v=2 etc if called via /api/v2/ or /api/v1
            if (APIBehaviourVersion > 0)
            {
                filter.APIVersion = APIBehaviourVersion;
            }
            if (APIBehaviourVersion >= 2)
            {
                filter.Action = DefaultAction;
            }

            if (context.Request.Url.Host.ToLower().StartsWith("api") && filter.APIVersion == null)
            {
                //API version is mandatory for api V2 onwards via api.openchargemap.* hostname
                OutputBadRequestMessage(context, "mandatory API Version not specified in request");
                return;
            }

            bool performSubmissionCompletedRedirects = false;

            //Use JSON format submission if explictly specified or by default if API v3
            if (context.Request["format"] == "json" || (String.IsNullOrEmpty(context.Request["format"]) && filter.APIVersion >= 3))
            {
                inputProvider = new InputProviders.JSONInputProvider();
            }
            else
            {
                inputProvider = new InputProviders.HTMLFormInputProvider();
                performSubmissionCompletedRedirects = true;
            }
            SubmissionManager submissionManager = new SubmissionManager();

            //attempt to determine user from api call
            User user = inputProvider.GetUserFromAPICall(context);

            if (user != null && user.IsCurrentSessionTokenValid == false)
            {
                //session token provided didn't match latest in user details, reject user details.
                context.Response.StatusCode = 401;
            }
            else
            {
                //allow contact us input whether use is authenticated or not
                if (context.Request["action"] == "contactus_submission" || filter.Action == "contact")
                {
                    ContactSubmission contactSubmission = new ContactSubmission();
                    bool processedOK = inputProvider.ProcessContactUsSubmission(context, ref contactSubmission);

                    bool resultOK = submissionManager.SendContactUsMessage(contactSubmission.Name, contactSubmission.Email, contactSubmission.Comment);
                    if (resultOK == true)
                    {
                        context.Response.Write("OK");
                    }
                    else
                    {
                        context.Response.Write("Error");
                    }
                }

                //if user not authenticated reject any other input
                if (user == null)
                {
                    context.Response.StatusCode = 401;
                    return;
                }

                //gather input variables
                if (context.Request["action"] == "cp_submission" || filter.Action == "poi")
                {
                    //gather/process data for submission
                    OCM.API.Common.Model.ChargePoint cp = new Common.Model.ChargePoint();

                    bool processedOK = inputProvider.ProcessEquipmentSubmission(context, ref cp);
                    bool submittedOK = false;

                    if (processedOK == true)
                    {
                        //perform submission

                        int submissionId = submissionManager.PerformPOISubmission(cp, user);
                        if (submissionId > -1)
                        {
                            submittedOK = true;
                        }
                    }

                    if (processedOK && submittedOK)
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            if (submittedOK)
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/complete.aspx", true);
                            }
                            else
                            {
                                context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                            }
                        }
                        else
                        {
                            context.Response.StatusCode = 202;
                        }
                    }
                    else
                    {
                        if (performSubmissionCompletedRedirects)
                        {
                            context.Response.Redirect("http://openchargemap.org/submissions/error.aspx", true);
                        }
                        else
                        {
                            context.Response.StatusCode = 500;
                        }
                    }
                }

                if (context.Request["action"] == "comment_submission" || filter.Action == "comment")
                {
                    UserComment comment     = new UserComment();
                    bool        processedOK = inputProvider.ProcessUserCommentSubmission(context, ref comment);
                    if (processedOK == true)
                    {
                        //perform submission
                        int result = submissionManager.PerformSubmission(comment, user);
                        if (filter.APIVersion >= 3)
                        {
                            if (result > 0)
                            {
                                OutputSubmissionReceivedMessage(context, "OK", true);
                            }
                            else
                            {
                                OutputBadRequestMessage(context, "Failed");
                            }
                        }
                        else
                        {
                            if (result >= 0)
                            {
                                context.Response.Write("OK:" + result);
                            }
                            else
                            {
                                context.Response.Write("Error:" + result);
                            }
                        }
                    }
                    else
                    {
                        context.Response.Write("Error: Validation Failed");
                    }
                }

                if (context.Request["action"] == "mediaitem_submission" || filter.Action == "mediaitem")
                {
                    var       p        = inputProvider;// as OCM.API.InputProviders.HTMLFormInputProvider;
                    MediaItem m        = new MediaItem();
                    bool      accepted = false;
                    string    msg      = "";
                    try
                    {
                        accepted = p.ProcessMediaItemSubmission(context, ref m, user.ID);
                    }
                    catch (Exception exp)
                    {
                        msg += exp.ToString();
                    }
                    if (accepted)
                    {
                        submissionManager.PerformSubmission(m, user);
                        //OutputSubmissionReceivedMessage(context, "OK :" + m.ID, true);

                        if (filter.APIVersion >= 3)
                        {
                            OutputSubmissionReceivedMessage(context, "OK", true);
                        }
                        else
                        {
                            context.Response.Write("OK");
                        }
                    }
                    else
                    {
                        if (filter.APIVersion >= 3)
                        {
                            OutputBadRequestMessage(context, "Failed");
                        }
                        else
                        {
                            context.Response.Write("Error");
                        }
                    }
                }
            }
        }
Beispiel #37
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;
            }
        }
        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("&amp;", "&");
                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;
        }
 public virtual void SetDataProviderDetails(ChargePoint cp, XmlNode item)
 {
     throw new Exception("SetDataProviderDetails not implemented");
 }
        public List<ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            string source = InputData;

            int startPos = source.IndexOf("*markers");
            int endPos = source.LastIndexOf("id=\"footer\"");
            DataProvider dataProvider = coreRefData.DataProviders.FirstOrDefault(d => d.ID == 16); //POD Point
            OperatorInfo operatorInfo = coreRefData.Operators.FirstOrDefault(op => op.ID == 3);

            string jsString = "/*" + source.Substring(startPos, endPos - startPos);

            jsString = jsString.Replace("makeMarker(", "");
            jsString = jsString.Replace(");", ",");

            jsString = jsString.Substring(0, jsString.LastIndexOf(","));
            jsString = jsString.Substring(0, jsString.LastIndexOf(","));

            jsString = jsString.Replace("/**markers", "");
            jsString = jsString.Replace("/**", "");
            jsString = jsString.Replace("*markers", "");

            jsString = jsString.Replace("**/", "");
            jsString = jsString.Replace("*/", "");
            jsString = jsString.Replace("\"", "|");
            jsString = jsString.Replace("new google.maps.LatLng(", "\"");
            jsString = jsString.Replace("),", "\",");
            jsString = jsString.Replace("'", "\"");
            jsString = jsString.Replace("|", "'");

            jsString = "{ \"data\":[ " + jsString + "]}";

            JObject o = JObject.Parse(jsString);
            var dataList = o.Values();

            int itemCount =0;
            foreach (var item in dataList.Values())
            {
                try
                {
                    ChargePoint cp  = new ChargePoint();
                    cp.DataProvider = dataProvider;
                    cp.OperatorInfo = operatorInfo;

                    cp.AddressInfo.Title = item["title"].ToString();
                    cp.AddressInfo.RelatedURL = "http://www.pod-point.com";
                    cp.DataProvidersReference = item["position"].ToString().Replace(", ", "@");
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    string content = item["content"].ToString();
                    content = content.Substring(content.LastIndexOf("<p>") + 3, content.LastIndexOf("</p>") - (content.LastIndexOf("<p>") + 3));
                    cp.GeneralComments = content;
                    string[] pos = item["position"].ToString().Split(',');
                    cp.AddressInfo.Latitude = double.Parse(pos[0]);
                    cp.AddressInfo.Longitude = double.Parse(pos[1]);

                    string status = "";
                    string itemIcon = item["icon"].ToString();
                    if (itemIcon.EndsWith("mappodpointblue.png")) status = "Available";
                    if (itemIcon.EndsWith("mappodpointgreen.png")) status = "In Use";
                    if (itemIcon.EndsWith("mappodpointbw.png")) status = "Planned";
                    if (itemIcon.EndsWith("mappodpointred.png")) status = "Not Operational";
                    if (!String.IsNullOrEmpty(status))
                    {
                        var statusType = coreRefData.StatusTypes.FirstOrDefault(s => s.Title.ToLower() == status.ToLower());
                        if (statusType != null)
                        {
                            cp.StatusType = statusType;
                        }
                    }
                    outputList.Add(cp);
                }
                catch (Exception)
                {
                    Log("Error parsing item "+itemCount);
                }

                itemCount++;
            }

            return outputList;
        }
 public virtual void ParseAdditionalData(ChargePoint cp, XmlNode item, CoreReferenceData coreRefData)
 {
     throw new Exception("ParseAdditionalData not implemented");
 }
 public virtual void ParseBasicDetails(ChargePoint cp, XmlNode item)
 {
     throw new Exception("ParseBasicDetails not implemented");
 }
        List<ChargePoint> IImportProvider.Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            var operationalStatus = coreRefData.StatusTypes.First(os => os.ID == 50);
            var operationalMixedStatus = coreRefData.StatusTypes.First(os => os.ID == 75);
            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 networkOperator = coreRefData.Operators.First(op=>op.ID==9); //blink/ecotality

            string jsString = InputData;
            jsString = "{ \"data\": " + jsString + "}"; //fix data by wrapping on container

            JObject o = JObject.Parse(jsString);

            var response = o.Values();
            var data = response.Values();
            var dataList = data.Values().ToArray();
            int itemCount = 0;

            foreach (var item in data)
            {
                bool skipItem = false;
                try
                {
                    ChargePoint cp = new ChargePoint();
                    cp.AddressInfo = new AddressInfo();

                    cp.OperatorInfo = networkOperator;
                    cp.OperatorsReference = item["encid"].ToString();
                    cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //blinknetwork.com
                    cp.DataProvidersReference = item["id"].ToString();
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    cp.AddressInfo.Title = item["name"] != null ? item["name"].ToString() : item["name"].ToString();
                    cp.AddressInfo.RelatedURL = "http://www.blinknetwork.com";
                    cp.DateLastStatusUpdate = DateTime.UtcNow;

                    cp.AddressInfo.Latitude = double.Parse(item["latitude"].ToString());
                    cp.AddressInfo.Longitude = double.Parse(item["longitude"].ToString());

                    cp.AddressInfo.AddressLine1 = item["address1"].ToString();
                    cp.AddressInfo.AddressLine2 = item["address2"].ToString();
                    cp.AddressInfo.Town = item["city"].ToString();
                    cp.AddressInfo.StateOrProvince = item["state"].ToString();
                    cp.AddressInfo.Postcode = item["zip"].ToString();

                    //set country property
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode == item["country"].ToString());

                    string usageTypeCode = item["type"].ToString();

                    switch (usageTypeCode) {
                        case "COMMERCIAL":  cp.UsageType = coreRefData.UsageTypes.FirstOrDefault(u => u.ID == 5); //pay at location
                            break;
                        case "RESIDENTIAL": skipItem=true;
                            break;
                        default:
                            Log("Unmatched usage type:"+usageTypeCode);
                            break;
                    }

                    cp.NumberOfPoints = int.Parse(item["chargers"].ToString());
                    int numOffline = int.Parse(item["offline"].ToString());
                    if (numOffline > 0)
                    {
                        cp.StatusType = operationalMixedStatus;
                    }
                    else
                    {
                        cp.StatusType = operationalStatus;
                    }

                    //populate connections
                    cp.Connections = new List<ConnectionInfo>();
                    var levelTypes = item["levels"].ToArray();
                    foreach (var level in levelTypes)
                    {
                        ConnectionInfo con = new ConnectionInfo();
                        if (level.ToString() == "1")
                        {
                            con.ConnectionType = new ConnectionType { ID = 1 };//J1772
                            con.Level = new ChargerType { ID = 1 };
                        }
                        if (level.ToString() == "2")
                        {
                            con.ConnectionType = new ConnectionType { ID = 1 };//J1772
                            con.Voltage = 220;
                            con.Level = new ChargerType { ID = 2 };
                        }
                        if (level.ToString() == "3")
                        {
                            con.ConnectionType = new ConnectionType { ID = 3 };//J1772
                            con.Voltage = 480;
                            con.Level = new ChargerType { ID = 3 };
                        }
                        cp.Connections.Add(con);
                    }
                    cp.DataQualityLevel = 3; //avg, higher than default

                    cp.SubmissionStatus = submissionStatus;
                    if (!skipItem) outputList.Add(cp);
                }
                catch (Exception)
                {
                    Log("Error parsing item " + itemCount);
                }

                itemCount++;
            }

            return outputList;
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            this.ImportRefData = new CommonImportRefData(coreRefData);

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

            XmlDocument xmlDoc = new XmlDocument();
            InputData = InputData.Replace(" xmlns=\"http://earth.google.com/kml/2.0\"", "");

            xmlDoc.LoadXml(InputData);

            XmlNodeList dataList = xmlDoc.SelectNodes("//Placemark");

            int itemCount = 0;

            foreach (XmlNode item in dataList)
            {
                bool skipItem = false;

                ChargePoint cp = new ChargePoint();
                cp.DateLastStatusUpdate = DateTime.UtcNow;

                SetDataProviderDetails(cp, item);

                cp.AddressInfo = new AddressInfo();

                ParseBasicDetails(cp, item);

                //parse coordinates
                string[] posString = item["Point"]["coordinates"].InnerText.Split(',');
                cp.AddressInfo.Latitude = double.Parse(posString[1]);
                cp.AddressInfo.Longitude = double.Parse(posString[0]);

                //determine country or leave for geolocation
                int? countryID = null;
                if (DefaultCountryID != null && countryID == null) countryID = DefaultCountryID;

                if (countryID == null)
                {
                    this.Log("Country Not Matched, will require Geolocation:" + cp.AddressInfo.ToString());
                }
                else
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(cy => cy.ID == countryID);
                }

                cp.Connections = ParseConnectionInfo(item);

                ParseAdditionalData(cp, item, coreRefData);

                cp.DataQualityLevel = 2; //lower than average quality due to spare data
                cp.SubmissionStatus = ImportRefData.SubmissionStatus_Imported;

                if (cp.StatusType == ImportRefData.Status_PlannedForFuture)
                {
                    skipItem = true;
                }

                if (!skipItem) outputList.Add(cp);

                itemCount++;
            }

            return outputList;
        }
        public string[] UploadPOIImageToStorage(string tempFolder, string sourceImageFile, Model.ChargePoint poi)
        {
            string extension = sourceImageFile.Substring(sourceImageFile.LastIndexOf('.'), sourceImageFile.Length - sourceImageFile.LastIndexOf('.')).ToLower();

            if (extension != ".jpg" && extension != ".jpeg" && extension != ".png" && extension != ".gif")
            {
                return(null);
            }
            var storage = new StorageManager();

            try
            {
                //TODO: allocate sequences properly
                string destFolderPrefix = poi.AddressInfo.Country.ISOCode + "/" + "OCM" + poi.ID + "/";
                string dateStamp        = String.Format("{0:yyyyMMddHHmmssff}", DateTime.UtcNow);
                string largeFileName    = "OCM-" + poi.ID + ".orig." + dateStamp + extension;
                string thumbFileName    = "OCM-" + poi.ID + ".thmb." + dateStamp + extension;
                string mediumFileName   = "OCM-" + poi.ID + ".medi." + dateStamp + extension;

                var metadataTags = new List <KeyValuePair <string, string> >();
                metadataTags.Add(new KeyValuePair <string, string>("OCM", poi.ID.ToString()));
                //metadataTags.Add(new KeyValuePair<string, string>("Title", poi.AddressInfo.Title));
                metadataTags.Add(new KeyValuePair <string, string>("Latitude", poi.AddressInfo.Latitude.ToString()));
                metadataTags.Add(new KeyValuePair <string, string>("Longitude", poi.AddressInfo.Longitude.ToString()));

                //TODO: generate thumbnail
                var urls = new string[3];

                //attempt thumbnails
                try
                {
                    //generate thumbnail max 100 wide
                    GenerateImageThumbnails(sourceImageFile, tempFolder + thumbFileName, 100);
                    //generate medium max 400 wide
                    GenerateImageThumbnails(sourceImageFile, tempFolder + mediumFileName, 400);
                    //resize original max 2048
                    GenerateImageThumbnails(sourceImageFile, tempFolder + largeFileName, 2048);
                }
                catch (Exception)
                {
                    AuditLogManager.Log(null, AuditEventType.SystemErrorAPI, "Failed to generate image upload thumbnails : OCM-" + poi.ID, "");
                    return(null);
                }

                //attempt upload
                bool success      = false;
                int  attemptCount = 0;
                while (success == false && attemptCount < 5)
                {
                    attemptCount++;
                    try
                    {
                        if (urls[0] == null)
                        {
                            urls[0] = storage.UploadImage(sourceImageFile, destFolderPrefix + largeFileName, metadataTags);
                        }

                        if (urls[1] == null)
                        {
                            urls[1] = storage.UploadImage(tempFolder + thumbFileName, destFolderPrefix + thumbFileName, metadataTags);
                        }

                        if (urls[2] == null)
                        {
                            urls[2] = storage.UploadImage(tempFolder + mediumFileName, destFolderPrefix + mediumFileName, metadataTags);
                        }
                        if (urls[0] != null && urls[1] != null && urls[2] != null)
                        {
                            success = true;
                        }
                    }
                    catch (Exception exp)
                    {
                        //failed to store blobs
                        AuditLogManager.Log(null, AuditEventType.SystemErrorAPI, "Failed to upload images to azure (attempt " + attemptCount + "): OCM-" + poi.ID, exp.ToString());
                        //return null;
                    }
                    attemptCount++;
                    Thread.Sleep(5000); //wait a bit then try again
                }

                Thread.Sleep(5000);
                //attempt to delete temp files
                try
                {
                    System.IO.File.Delete(sourceImageFile);
                    System.IO.File.Delete(tempFolder + thumbFileName);
                    System.IO.File.Delete(tempFolder + mediumFileName);
                    System.IO.File.Delete(tempFolder + largeFileName);
                }
                catch (Exception)
                {
                    ;
                }

                return(urls);
            }
            catch (Exception)
            {
                //failed to upload
                AuditLogManager.Log(null, AuditEventType.SystemErrorAPI, "Final attempt to upload images to azure failed: OCM-" + poi.ID, "");

                return(null);
            }
        }
        public List<API.Common.Model.ChargePoint> Process(CoreReferenceData coreRefData)
        {
            List<ChargePoint> outputList = new List<ChargePoint>();

            XmlDocument xmlDoc = new XmlDocument();
            xmlDoc.LoadXml(InputData);

            XmlNodeList dataList = xmlDoc.SelectNodes("//chargerstation");

            var submissionStatus = coreRefData.SubmissionStatusTypes.First(s => s.ID == 100);//imported and published
            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 usageTypePrivateForStaffAndVisitors = coreRefData.UsageTypes.First(u => u.ID == 6); //staff and visitors
            var operatorUnknown = coreRefData.Operators.First(opUnknown => opUnknown.ID == 1);

            int itemCount = 0;
            foreach (XmlNode chargerstation in dataList)
            {
                var item = chargerstation.SelectNodes("metadata").Item(0);
                ChargePoint cp = new ChargePoint();
                cp.DataProvider = new DataProvider() { ID = this.DataProviderID }; //nobil.no
                cp.DataProvidersReference = item["id"].InnerText; //is id unique across countries?
                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo = new AddressInfo();

                cp.AddressInfo.Title = item["name"].InnerText != null ? item["name"].InnerText : item["Street"].InnerText;
                cp.AddressInfo.Title = cp.AddressInfo.Title.Trim().Replace("&amp;", "&");
                //cp.AddressInfo.RelatedURL = item["url"].ToString();

                cp.DateLastStatusUpdate = DateTime.UtcNow;
                cp.AddressInfo.AddressLine1 = item["Street"].InnerText;
                if (item["House_number"] != null) cp.AddressInfo.AddressLine1 += " " + item["House_number"].InnerText;
                cp.AddressInfo.Town = item["City"].InnerText.Trim();
                cp.AddressInfo.StateOrProvince = item["County"].InnerText.Trim();
                cp.AddressInfo.Postcode = item["Zipcode"].InnerText.Trim();
                string posString = item["Position"].InnerText.Trim();

                int sepPos = posString.IndexOf(",") - 1;
                string lat = posString.Substring(1, sepPos);
                sepPos += 2;
                string lon = posString.Substring(sepPos, (posString.Length - sepPos) - 1);
                cp.AddressInfo.Latitude = double.Parse(lat);
                cp.AddressInfo.Longitude = double.Parse(lon);

                //default to norway
                var countryCode = item["Land_code"].InnerText;
                if (countryCode.ToUpper() == "NOR")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "no");
                }
                else if (countryCode.ToUpper() == "FIN")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "fi");
                }
                else if (countryCode.ToUpper() == "SWE")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "se");
                }
                else if (countryCode.ToUpper() == "DAN")
                {
                    cp.AddressInfo.Country = coreRefData.Countries.FirstOrDefault(c => c.ISOCode.ToLower() == "dk");
                }
                else
                {
                    System.Diagnostics.Debug.WriteLine("Unknown country code:" + countryCode);
                }

                cp.AddressInfo.AccessComments = item["Description_of_location"].InnerText;
                cp.AddressInfo.GeneralComments = item["Contact_info"].InnerText;

                cp.NumberOfPoints = int.Parse(item["Number_charging_points"].InnerText);

                var attributes = chargerstation.SelectNodes("attributes").Item(0);
                var connectors = attributes.SelectSingleNode("connectors").SelectNodes("connector");
                foreach (XmlNode connector in connectors)
                {
                    var connectorAttribs = connector.SelectSingleNode("attribute[attrtypeid=4]");
                    var chargingCapacityAttribs = connector.SelectSingleNode("attribute[attrtypeid=5]");
                    var chargingModeAttribs = connector.SelectSingleNode("attribute[attrtypeid=20]");
                    ConnectionInfo cinfo = new ConnectionInfo() { };
                    cinfo.Reference = connector.Attributes["id"].InnerText;

                    ConnectionType cType = new ConnectionType { ID = 0 };
                    if (connectorAttribs != null)
                    {
                        var connectorTypeVal = connectorAttribs.SelectSingleNode("attrvalid").InnerText;
                        if (connectorTypeVal == "14")
                        {
                            cType.ID = 28;// Schuko CEE 7/4
                        }
                        else if (connectorTypeVal == "40")
                        {
                            cType.ID = 27;// tesla supercharger connnector
                        }
                        else if (connectorTypeVal == "31")
                        {
                            //type 1 == J1772?
                            cType.ID = (int)StandardConnectionTypes.J1772;
                        }
                        else if (connectorTypeVal == "29")
                        {
                            cType.ID = 8;// tesla roadster
                        }
                        else if (connectorTypeVal == "32")
                        {
                            cType.ID = 25;// type 2 (mennekes)
                        }
                        else if (connectorTypeVal == "50")
                        {
                            cType.ID = 28;// type 2 + schuko both present?
                        }
                        else if (connectorTypeVal == "30")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;
                        }
                        else if (connectorTypeVal == "34")
                        {
                            cType.ID = 34;//IEC 60309 3 pin
                        }
                        else if (connectorTypeVal == "36")
                        {
                            cType.ID = 35;//IEC 60309 5 pin
                        }
                        else if (connectorTypeVal == "39")
                        {
                            cType.ID = 33;//Type 2 of CCS coupler
                        }
                        else if (connectorTypeVal == "41")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;//CCS combo + Chademo both present
                        }
                        else if (connectorTypeVal == "43")
                        {
                            cType.ID = (int)StandardConnectionTypes.CHAdeMO;//CHAdeMO + Combo + AC-Type2 all present
                        }
                        else if (connectorTypeVal == "0")
                        {
                            cType.ID = 0;//unknown
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("Unnknown connectorDetails: " + connectorAttribs.InnerText);
                        }
                    }

                    if (chargingCapacityAttribs != null)
                    {
                        //TODO: 3-Phase power calcs are wrong.
                        var connectorTypeVal = chargingCapacityAttribs.SelectSingleNode("attrvalid").InnerText;
                        if (connectorTypeVal == "7")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.SinglePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "8")
                        {
                            cinfo.Amps = 32;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.SinglePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "10")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 400;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "11")
                        {
                            //500V DC
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "12")
                        {
                            //400V AC (3 Phase) 63A
                            cinfo.Amps = 63;
                            cinfo.Voltage = 400;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "13")
                        {
                            //tesla super charger
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "16")
                        {
                            cinfo.Amps = 16;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "17")
                        {
                            cinfo.Amps = 32;
                            cinfo.Voltage = 230;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.ThreePhaseAC };
                            cinfo.Level = new ChargerType() { ID = 2 }; //default to lvl2
                        }
                        else if (connectorTypeVal == "19")
                        {
                            //500V DC MAX 50A
                            cinfo.Amps = 50;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "20")
                        {
                            //TODO: 500VDC max 200A + 400V 3-phase max 63A
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "22")
                        {
                            //480VDC max 270A
                            cinfo.Amps = 270;
                            cinfo.Voltage = 480;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "27")
                        {
                            //tesla super charger
                            cinfo.Amps = 200;
                            cinfo.Voltage = 500;
                            cinfo.CurrentType = new CurrentType { ID = (int)StandardCurrentTypes.DC };
                            cinfo.Level = new ChargerType() { ID = 3 };
                        }
                        else if (connectorTypeVal == "0")
                        {
                            //unknown power level
                        }
                        else
                        {
                            System.Diagnostics.Debug.WriteLine("unknown chargingCapacity: " + chargingCapacityAttribs.InnerText);
                        }
                    }

                    if (cinfo.Amps > 0 && cinfo.Voltage > 0)
                    {
                        cinfo.PowerKW = (cinfo.Amps * cinfo.Voltage / 1000);
                    }

                    cinfo.ConnectionType = cType;

                    if (chargingModeAttribs != null)
                    {
                        var chargeMode = chargingModeAttribs.SelectSingleNode("trans");
                        if (chargeMode != null)
                        {
                            cinfo.Comments = chargeMode.InnerText;
                        }
                    }
                    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;

                outputList.Add(cp);
                itemCount++;
            }

            return outputList;
        }