public void ResponseCreation_TemperatureSensor_Test()
        {
            SmartHomeRequest  request  = JsonConvert.DeserializeObject <SmartHomeRequest>(REPORT_STATE);
            SmartHomeResponse response = new SmartHomeResponse(request.Directive.Header);

            Assert.Null(response.Context);
            response.Context = new Context();
            Setpoint s = new Setpoint(24.0, Scale.CELSIUS);
            Property p = new Property(Namespaces.ALEXA_TEMPERATURESENSOR, PropertyNames.TEMPERATURE, 50,
                                      DateTime.Parse("2017-09-27T18:30:30.45Z").ToUniversalTime(), 200);
            ConnectivityPropertyValue value = new ConnectivityPropertyValue(ConnectivityModes.OK);
            Property p2 = new Property(Namespaces.ALEXA_ENDPOINTHEALTH, PropertyNames.CONNECTIVITY, value,
                                       DateTime.Parse("2017-09-27T18:30:30.45Z").ToUniversalTime(), 200);

            response.Context.Properties.Add(p);
            response.Context.Properties.Add(p2);
            Assert.NotNull(response.Event);
            Assert.Equal(typeof(Event), response.Event.GetType());
            Event e = response.Event as Event;

            TestFunctionsV3.CheckResponseCreatedBaseHeader(e.Header, request.Directive.Header, headerName: HeaderNames.STATE_REPORT);
            Assert.Null(e.Endpoint);
            e.Endpoint = new Endpoint("endpoint-001", new NET.JsonObjects.Scopes.BearerToken("access-token-from-Amazon"));
            Assert.NotNull(e.Payload);
            Assert.Equal(typeof(Payload), response.GetPayloadType());
            Assert.NotNull(JsonConvert.SerializeObject(response));
            Util.Util.WriteJsonToConsole("TemperatureSensor", response);
        }
        public void ResponseParse_TemperatureSensor_Test()
        {
            SmartHomeResponse responseFromString = JsonConvert.DeserializeObject <SmartHomeResponse>(TEMPERATURESENSOR_RESPONSE);

            //Context check
            Assert.NotNull(responseFromString.Context);
            Assert.NotNull(responseFromString.Context.Properties);
            Assert.Equal(2, responseFromString.Context.Properties.Count);
            // Property 1
            TestFunctionsV3.TestContextProperty(responseFromString.Context.Properties[0], PropertyNames.TEMPERATURE,
                                                Namespaces.ALEXA_TEMPERATURESENSOR, DateTime.Parse("2017-09-27T18:30:30.45Z"), 200, null);
            Assert.Equal(typeof(Setpoint), responseFromString.Context.Properties[0].Value.GetType());
            Setpoint s = responseFromString.Context.Properties[0].Value as Setpoint;

            Assert.Equal(24.0, s.Value);
            Assert.Equal(Scale.CELSIUS, s.Scale);
            // Property 2
            TestFunctionsV3.TestBasicHealthCheckProperty(responseFromString.Context.Properties[1], ConnectivityModes.OK, DateTime.Parse("2017-09-27T18:30:30.45Z"));
            //Event Check
            Assert.NotNull(responseFromString.Event);
            Assert.Equal(typeof(Event), responseFromString.Event.GetType());
            Event e = responseFromString.Event as Event;

            TestFunctionsV3.TestHeaderV3(e.Header, "5f8a426e-01e4-4cc9-8b79-65f8bd0fd8a4", Namespaces.ALEXA, HeaderNames.STATE_REPORT);
            Assert.Equal("dFMb0z+PgpgdDmluhJ1LddFvSqZ/jCc8ptlAKulUj90jSqg==", e.Header.CorrelationToken);
            TestFunctionsV3.TestEndpointV3(e.Endpoint, "endpoint-001");
            TestFunctionsV3.TestBearerTokenV3(e.Endpoint.Scope, "access-token-from-Amazon");
            Assert.NotNull(e.Payload);
            Assert.Equal(typeof(Payload), responseFromString.GetPayloadType());
        }
Exemple #3
0
        private void TestPropertySetpoint(Property p, string propertyName, string namespaceName, DateTime time, int uncertainty, string customname, double value, Scale scale)
        {
            TestFunctionsV3.TestContextProperty(p, propertyName, namespaceName, time, uncertainty, customname);
            Assert.Equal(typeof(Setpoint), p.Value.GetType());
            Setpoint s = p.Value as Setpoint;

            TestSetpoint(s, value, scale);
        }
Exemple #4
0
        public IFuture <CommandStatus> AcceptCommand(Setpoint command, uint index)
        {
            System.Console.WriteLine("Received Setpoint on index: " + index);
            var future = new Future <CommandStatus>();

            future.Set(CommandStatus.CS_NOT_SUPPORTED);
            return(future);
        }
Exemple #5
0
 public void ReceiveAndSetSetpoint(Setpoint setpoint)
 {
     foreach (var item in setpoint.PDistributionByAV)
     {
         AnalogValue av    = scadaModel.AnalogValues.Where(o => o.GlobalId.Equals(item.Key)).FirstOrDefault();
         float       value = RawValuesConverter.ConvertRange(item.Value, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX);
         //short value = floatToShort(RawValuesConverter.ConvertRange(item.Value, EGU_MIN, EGU_MAX, RAW_MIN, RAW_MAX));
         //client.WriteSingleHoldingRegister(av.Address, value);
         LogHelper.Log(LogTarget.File, LogService.SCADASetpoint, " INFO - SCADASetpoint.cs - Receiving and setting setpoint.");
         client.WriteSingleHoldingRegister2(av.Address, value);
     }
 }
        private void UpdateAnalogValuesList(AnalogValue analogValue, Setpoint setpoint)
        {
            long aValueGid = analogValue.GlobalId;

            if (setpoint.PDistributionByAV.ContainsKey(aValueGid))
            {
                setpoint.PDistributionByAV[aValueGid] = analogValue.Value;
            }
            else
            {
                setpoint.PDistributionByAV.Add(aValueGid, analogValue.Value);
            }
        }
Exemple #7
0
        public static InternalCondition ToSAM_InternalCondtion(this ProgramType programType)
        {
            if (programType == null)
            {
                return(null);
            }

            InternalCondition result = new InternalCondition(programType.DisplayName);

            People people = programType.People;

            if (people != null)
            {
                result.SetValue(Analytical.InternalConditionParameter.OccupancyProfileName, Core.LadybugTools.Query.Identifier(people.OccupancySchedule));
            }

            Lighting lighting = programType.Lighting;

            if (lighting != null)
            {
                result.SetValue(Analytical.InternalConditionParameter.LightingProfileName, Core.LadybugTools.Query.Identifier(lighting.Schedule));
            }

            ElectricEquipment electricEquipment = programType.ElectricEquipment;

            if (electricEquipment != null)
            {
                result.SetValue(Analytical.InternalConditionParameter.EquipmentSensibleProfileName, Core.LadybugTools.Query.Identifier(electricEquipment.Schedule));
            }

            Infiltration infiltration = programType.Infiltration;

            if (infiltration != null)
            {
                result.SetValue(Analytical.InternalConditionParameter.InfiltrationProfileName, Core.LadybugTools.Query.Identifier(infiltration.Schedule));
            }

            Setpoint setPoint = programType.Setpoint;

            if (setPoint != null)
            {
                result.SetValue(Analytical.InternalConditionParameter.CoolingProfileName, Core.LadybugTools.Query.Identifier(setPoint.CoolingSchedule));

                result.SetValue(Analytical.InternalConditionParameter.HeatingProfileName, Core.LadybugTools.Query.Identifier(setPoint.HeatingSchedule));
            }

            return(result);
        }
        public static List <Profile> ToSAM_Profiles(this ProgramType programType)
        {
            if (programType == null)
            {
                return(null);
            }

            List <Profile> result = new List <Profile>();

            People people = programType.People;

            if (people != null)
            {
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> occupancySchedule = people.OccupancySchedule;
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> activitySchedule  = people.ActivitySchedule;
            }

            Lighting lighting = programType.Lighting;

            if (lighting != null)
            {
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> schedule = lighting.Schedule;
            }

            ElectricEquipment electricEquipment = programType.ElectricEquipment;

            if (electricEquipment != null)
            {
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> schedule = electricEquipment.Schedule;
            }

            Infiltration infiltration = programType.Infiltration;

            if (infiltration != null)
            {
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> schedule = infiltration.Schedule;
            }

            Setpoint setPoint = programType.Setpoint;

            if (setPoint != null)
            {
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> coolingSchedule = setPoint.CoolingSchedule;
                AnyOf <ScheduleRuleset, ScheduleFixedInterval> heatingSchedule = setPoint.HeatingSchedule;
            }

            return(result);
        }
        /// <summary>
        /// Dobijanje set point-a za odredjenu komandu i merenja
        /// </summary>
        /// <param name="command"> Komanda</param>
        /// <param name="measurement"> Merenja sa SCADA-a ili forecast vrednosti </param>
        /// <returns></returns>
        private Setpoint GetSetPoint(Command command, List <AnalogValue> measurement)
        {
            Setpoint setPoint = null;

            switch (command.OptimizationType)
            {
            case OptimizationType.DerFlexibility:
                // SetPoint za optimizacioni metod raspodela prema raspolozivoj rezervi
                setPoint = AvailableReserveDistribution(command.GlobalId, command.DemandedPower, command.PowerType, measurement);
                break;

            case OptimizationType.NominalPower:
                // SetPoint za optimizacioni metod raspodela prema nominalnoj snazi
                setPoint = NominalPowerDistribution(command.GlobalId, command.DemandedPower, command.PowerType, measurement);
                break;
            }

            return(setPoint);
        }
        /// <summary>
        /// Funkcija koju UI poziva i vrsi resporedjivanje i upravljanje SetPoint-ima
        /// </summary>
        /// <param name="command"> Komanda </param>
        /// <returns> Da li je moguce primenit komandu</returns>
        public bool DistributePowerClient(Command command)
        {
            // Rezultat Proracuna ce biti smesten u dictionary. Kljuc je vreme a vrednost set point
            SortedDictionary <long, Setpoint> distributePowerResult = new SortedDictionary <long, Setpoint>();

            // Ako ako je vec komandovano, komanda se brise i pokusava se ponovo komandovati
            if (CommandExists(command.GlobalId, command.PowerType))
            {
                return(false);
            }

            // Lista sinhronih masina nad kojima se komanduje
            List <SynchronousMachine> ders = GetDERsForGlobalID(command.GlobalId);

            // Ako nema sinhronih masina -> kraj
            if (ders == null || ders.Count.Equals(0))
            {
                return(false);
            }

            // Podaci sa skade, prikupljeni iz SmartCache za sve der-ove koji pripadaju gid-u komande
            List <AnalogValue> currentMeasurement = GetSCADADataForDERs(ders, command.PowerType);

            // Ako nema merenja, ne mogu da se postave setPoint-i
            if (currentMeasurement == null || currentMeasurement.Count.Equals(0))
            {
                return(false);
            }

            // Prognoza za naredni period
            List <ForecastObject> forecastObjects = GetPowerForecastForDERs(ders);

            // Uradimo filter za samo ono vreme koje nam je klijent vratio i sortiramo po vremenu
            SortedDictionary <long, List <AnalogValue> > measurementDictionary = GroupAndFilterByTime(command.Duration, command.PowerType, forecastObjects);

            // Ubacimo i currentMeasurement u sva merenja
            measurementDictionary.Add(new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, DateTime.Now.Hour, 0, 0).Ticks, currentMeasurement);

            // Proracun SetPoint-a za svaki ForecastObject
            foreach (long key in measurementDictionary.Keys)
            {
                // Proracun SetPoint-a
                Setpoint setPoint = GetSetPoint(command, CopyList(measurementDictionary[key]));

                // Ako se ne mogu odrediti setPoint-i -> kraj
                if (setPoint == null)
                {
                    return(false);
                }

                distributePowerResult.Add(key, setPoint);
            }

            List <Command> commands = CreateCommands(measurementDictionary, distributePowerResult, command);

            // Pokretanje thread-a koji ce da primenjuje jedan po jedan SetPoint u tacno predefinisanom vremenu
            Thread coordinator = new Thread(() => ThreadCoordinator(distributePowerResult, commands));

            coordinator.Start();

            return(true);
        }
Exemple #11
0
 private void TestSetpoint(Setpoint s, double value, Scale scale)
 {
     Assert.NotNull(s);
     Assert.Equal(value, s.Value);
     Assert.Equal(scale, s.Scale);
 }
        public static ProgramType ToLadybugTools(this Space space, AdjacencyCluster adjacencyCluster, ProfileLibrary profileLibrary)
        {
            InternalCondition internalCondition = space.InternalCondition;

            if (internalCondition == null)
            {
                return(null);
            }

            string uniqueName = Core.LadybugTools.Query.UniqueName(internalCondition);

            if (string.IsNullOrWhiteSpace(uniqueName))
            {
                return(null);
            }

            People            people            = null;
            Lighting          lighting          = null;
            ElectricEquipment electricEquipment = null;
            Infiltration      infiltration      = null;
            Setpoint          setpoint          = null;

            if (profileLibrary != null)
            {
                double area = double.NaN;
                if (!space.TryGetValue(SpaceParameter.Area, out area))
                {
                    area = double.NaN;
                }

                Dictionary <ProfileType, Profile> dictionary = internalCondition.GetProfileDictionary(profileLibrary);

                if (dictionary.ContainsKey(ProfileType.Occupancy))
                {
                    Profile profile = dictionary[ProfileType.Occupancy];
                    if (profile != null)
                    {
                        double gain = Analytical.Query.OccupancyGain(space);
                        if (double.IsNaN(gain))
                        {
                            gain = 0;
                        }

                        ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                        if (scheduleRuleset != null)
                        {
                            double gainPerPeople = gain;
                            if (double.IsNaN(gainPerPeople))
                            {
                                gainPerPeople = 0;
                            }

                            double occupancy = Analytical.Query.CalculatedOccupancy(space);
                            if (!double.IsNaN(occupancy) && occupancy != 0)
                            {
                                gainPerPeople = gainPerPeople / occupancy;
                            }

                            ScheduleRuleset scheduleRuleset_ActivityLevel = profile.ToLadybugTools_ActivityLevel(gainPerPeople);
                            if (scheduleRuleset_ActivityLevel != null)
                            {
                                double peoplePerArea = Analytical.Query.CalculatedPeoplePerArea(space);
                                if (double.IsNaN(peoplePerArea))
                                {
                                    peoplePerArea = 0;
                                }

                                double latentFraction        = double.NaN;
                                double sensibleOccupancyGain = Analytical.Query.OccupancySensibleGain(space);
                                double latentOccupancyGain   = Analytical.Query.OccupancyLatentGain(space);
                                if (!double.IsNaN(sensibleOccupancyGain) || !double.IsNaN(latentOccupancyGain))
                                {
                                    latentFraction = latentOccupancyGain / (latentOccupancyGain + sensibleOccupancyGain);
                                }

                                if (!internalCondition.TryGetValue(Analytical.InternalConditionParameter.OccupancyRadiantProportion, out double occuplancyRadiantProportion))
                                {
                                    occuplancyRadiantProportion = 0.3;
                                }

                                if (double.IsNaN(latentFraction))
                                {
                                    latentFraction = 0;
                                }


                                people = new People(
                                    identifier: string.Format("{0}_People", uniqueName),
                                    peoplePerArea: peoplePerArea,
                                    occupancySchedule: scheduleRuleset,
                                    displayName: profile.Name,
                                    userData: null,
                                    activitySchedule: scheduleRuleset_ActivityLevel,
                                    radiantFraction: occuplancyRadiantProportion,
                                    latentFraction: latentFraction);
                            }
                        }
                    }
                }

                if (dictionary.ContainsKey(ProfileType.Lighting))
                {
                    Profile profile = dictionary[ProfileType.Lighting];
                    if (profile != null)
                    {
                        double gain = Analytical.Query.CalculatedLightingGain(space);
                        if (double.IsNaN(gain))
                        {
                            gain = 0;
                        }

                        ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                        if (scheduleRuleset != null)
                        {
                            double gainPerArea = gain;
                            if (double.IsNaN(gainPerArea))
                            {
                                gainPerArea = 0;
                            }

                            if (!double.IsNaN(area) && area != 0)
                            {
                                gainPerArea = gainPerArea / area;
                            }

                            if (!internalCondition.TryGetValue(Analytical.InternalConditionParameter.LightingRadiantProportion, out double lightingRadiantProportion))
                            {
                                lightingRadiantProportion = 0.32;
                            }

                            if (!internalCondition.TryGetValue(Analytical.InternalConditionParameter.LightingViewCoefficient, out double lightingViewCoefficient))
                            {
                                lightingViewCoefficient = 0.25;
                            }

                            lighting = new Lighting(
                                identifier: string.Format("{0}_Lighting", uniqueName),
                                wattsPerArea: gainPerArea,
                                schedule: scheduleRuleset,
                                visibleFraction: lightingViewCoefficient,
                                radiantFraction: lightingRadiantProportion,
                                displayName: profile.Name);
                        }
                    }
                }

                if (dictionary.ContainsKey(ProfileType.EquipmentSensible))
                {
                    double gain = Analytical.Query.CalculatedEquipmentSensibleGain(space);
                    if (double.IsNaN(gain))
                    {
                        gain = 0;
                    }

                    Profile profile = dictionary[ProfileType.EquipmentSensible];
                    if (profile != null)
                    {
                        ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                        if (scheduleRuleset != null)
                        {
                            double gainPerArea = gain;
                            if (double.IsNaN(gainPerArea))
                            {
                                gainPerArea = 0;
                            }

                            if (!double.IsNaN(area) && area != 0)
                            {
                                gainPerArea = gainPerArea / area;
                            }

                            if (!internalCondition.TryGetValue(Analytical.InternalConditionParameter.EquipmentRadiantProportion, out double equipmentRadiantProportion))
                            {
                                equipmentRadiantProportion = 0;
                            }

                            electricEquipment = new ElectricEquipment(
                                identifier: string.Format("{0}_ElectricEquipment", uniqueName),
                                wattsPerArea: gainPerArea,
                                schedule: scheduleRuleset,
                                radiantFraction: equipmentRadiantProportion,
                                displayName: profile.Name);
                        }
                    }
                }

                if (dictionary.ContainsKey(ProfileType.Infiltration))
                {
                    Profile profile = dictionary[ProfileType.Infiltration];
                    if (profile != null)
                    {
                        ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                        if (scheduleRuleset != null)
                        {
                            double airFlowPerExteriorArea = Query.InfiltrationAirFlowPerExteriorArea(adjacencyCluster, space);

                            infiltration = new Infiltration(
                                identifier: string.Format("{0}_Infiltration", uniqueName),
                                flowPerExteriorArea: airFlowPerExteriorArea,
                                schedule: scheduleRuleset,
                                displayName: profile.Name);
                        }
                    }
                }

                if (dictionary.ContainsKey(ProfileType.Cooling) && dictionary.ContainsKey(ProfileType.Heating))
                {
                    Profile profile_Cooling = dictionary[ProfileType.Cooling];
                    Profile profile_Heating = dictionary[ProfileType.Heating];
                    if (profile_Cooling != null && profile_Heating != null)
                    {
                        ScheduleRuleset scheduleRuleset_Cooling = profile_Cooling.ToLadybugTools();
                        ScheduleRuleset scheduleRuleset_Heating = profile_Heating.ToLadybugTools();
                        if (scheduleRuleset_Cooling != null && scheduleRuleset_Heating != null)
                        {
                            setpoint = new Setpoint(string.Format("{0}_Setpoint", uniqueName), scheduleRuleset_Cooling, scheduleRuleset_Heating, string.Format("Heating {0} Cooling {1}", profile_Heating.Name, profile_Cooling.Name));

                            Profile profile;

                            if (dictionary.TryGetValue(ProfileType.Humidification, out profile))
                            {
                                ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                                if (scheduleRuleset != null)
                                {
                                    setpoint.HumidifyingSchedule = scheduleRuleset;
                                }
                            }

                            if (dictionary.TryGetValue(ProfileType.Dehumidification, out profile))
                            {
                                ScheduleRuleset scheduleRuleset = profile.ToLadybugTools();
                                if (scheduleRuleset != null)
                                {
                                    setpoint.DehumidifyingSchedule = scheduleRuleset;
                                }
                            }
                        }
                    }
                }
            }

            ProgramType result = new ProgramType(
                identifier: uniqueName,
                displayName: internalCondition.Name,
                userData: null,
                people: people,
                lighting: lighting,
                electricEquipment: electricEquipment,
                infiltration: infiltration,
                setpoint: setpoint);

            return(result);
        }
 private void ThermostatSetpoint_Changed(object sender, ReportEventArgs<ThermostatSetpointReport> e)
 {
     var setpoint = new Setpoint(e.Report.Value, e.Report.Scale == 0 ? Unit.Celsius : Unit.Fahrenheit);
     OnSetPointChanged(new SetpointEventArgs(setpoint));
 }
 public void ReceiveAndSetSetpoint(Setpoint setpoint)
 {
     this.Channel.ReceiveAndSetSetpoint(setpoint);
 }
        /// <summary>
        /// Distributes demanded power to DERs associated to specific gid.
        /// </summary>
        /// <param name="gid">Region, subregion, or entire network </param>
        /// <param name="demandedValue">Demanded Value</param>
        /// <param name="powerType"> Power Type (Active/Reactive) </param>
        /// <param name="anaValues"> List of analog values </param>
        /// <returns></returns>
        public Setpoint NominalPowerDistribution(long gid, float demandedValue, PowerType powerType, List <AnalogValue> anaValues)
        {
            LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute demanded power to DERs associated to gid: " + gid);
            List <SynchronousMachine> syncMachines      = RDAdapter.GetDERs(gid); // Get all DERs from a region, subregion or substation
            List <AnalogValue>        analogValues      = anaValues;
            Dictionary <long, float>  PDistributionBySM = new Dictionary <long, float>(syncMachines.Count);
            SynchronousMachine        syncMachine       = null;

            Setpoint setpoint = new Setpoint();

            setpoint.PDistributionByAV = new Dictionary <long, float>(syncMachines.Count);

            long  smGid                  = 0;
            int   safetyCounter          = 0;
            float coefficient            = 0;
            float smNominalPower         = 0;
            float nominalPowerSum        = 0;
            float smDelta                = 0;
            float smFlexibility          = 0;
            float smMaxPower             = 0;
            float smMinPower             = 0;
            float smAvailableReserve     = 0;
            float smAvailableReserveUp   = 0;
            float smAvailableReserveDown = 0;
            float demandValue            = demandedValue;
            bool  isDeltaPositive        = false;

            isDeltaPositive = demandedValue >= 0;

            switch (powerType)
            {
            case PowerType.Active:
                nominalPowerSum = syncMachines.Sum(o => o.NominalP);
                break;

            case PowerType.Reactive:
                nominalPowerSum = syncMachines.Sum(o => o.NominalQ);
                break;

            default:
                break;
            }

            coefficient = demandedValue / nominalPowerSum;

            while (demandValue > 0 && isDeltaPositive == true ||
                   demandValue < 0 && isDeltaPositive == false)
            {
                foreach (AnalogValue aValue in analogValues.Where(p => p.PowerType == powerType))
                {
                    syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine);

                    switch (powerType)
                    {
                    case PowerType.Active:
                        smFlexibility          = syncMachine.DERFlexibilityP;
                        smMaxPower             = syncMachine.MaxP;
                        smMinPower             = syncMachine.MinP;
                        smNominalPower         = syncMachine.NominalP;
                        smAvailableReserveUp   = syncMachine.MaxP - aValue.Value;
                        smAvailableReserveDown = aValue.Value - syncMachine.MinP;
                        break;

                    case PowerType.Reactive:
                        smFlexibility          = syncMachine.DERFlexibilityQ;
                        smMaxPower             = syncMachine.MaxQ;
                        smMinPower             = syncMachine.MinQ;
                        smNominalPower         = syncMachine.NominalQ;
                        smAvailableReserveUp   = syncMachine.MaxQ - aValue.Value;
                        smAvailableReserveDown = aValue.Value - syncMachine.MinQ;
                        break;

                    default:
                        break;
                    }

                    if (aValue.Value == smMaxPower && isDeltaPositive == true)
                    {
                        continue;
                    }

                    if (aValue.Value == smMinPower && isDeltaPositive == false)
                    {
                        continue;
                    }

                    smDelta = coefficient * smNominalPower; // Proportionaly split required power, by nominalP value
                    smGid   = syncMachine.GlobalId;

                    smAvailableReserve = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown;

                    if (smAvailableReserve == 0)
                    {
                        LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " WARNING - CalculationEngineDistributer.cs - No available reserve for gid: " + gid);
                        continue;
                    }

                    //korak redukovanja K, ne moze biti veci od MAX ni manji od MIN
                    ReduceKToProperValue(ref smDelta, smAvailableReserve, isDeltaPositive, aValue);

                    if (Math.Abs(smDelta) <= smFlexibility) // ako delta ne prelazi max, da li je DER dovoljno flexibilan?
                    {
                        CheckDistributedPartsOnGoodFlex(PDistributionBySM, aValue, setpoint, smDelta, smFlexibility, isDeltaPositive, ref demandValue);
                    }
                    else // ako DER nije dovoljno fleksibilan
                    {
                        CheckDistributedPartsOnPoorFlex(PDistributionBySM, aValue, setpoint, smDelta, smFlexibility, isDeltaPositive, ref demandValue);
                    }
                }

                if (safetyCounter++ == 5)
                {
                    Trace.Write("Warning: 5 iterations were done, but no solution has been found.");
                    LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " WARNING - CalculationEngineDistributer.cs - 5 iterations were done, but no solution has been found to gid: " + gid);

                    return(setpoint);
                }
            }
            return(setpoint);
        }
        /// <summary>
        /// Helper function to distribute power when DER is not flexible enough
        /// </summary>
        /// <param name="aValue"></param>
        /// <param name="setpoint"></param>
        /// <param name="smDelta"></param>
        /// <param name="smFlexibility"></param>
        /// <param name="dValue"></param>
        private void CheckDistributedPartsOnPoorFlex(Dictionary <long, float> pDistributionBySM, AnalogValue aValue,
                                                     Setpoint setpoint, float smDelta, float smFlexibility, bool isPositiveD, ref float dValue)
        {
            long smGid = aValue.SynchronousMachine;

            LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute power for NOT flexible enough der: " + smGid);

            if (pDistributionBySM.ContainsKey(smGid))                                   // Da li je vec nesto rasporedjeno na DER?
            {
                float smDeltaPart = smFlexibility - Math.Abs(pDistributionBySM[smGid]); // zahtjeva se vrijednost koja je preko flex, stoga napunimo DER do kraja njegovog flexibility

                if (isPositiveD)                                                        //ubaceno zbog negativnih delti
                {
                    if (dValue >= smDeltaPart)
                    {
                        pDistributionBySM[smGid] += smDeltaPart;
                        dValue       -= smDeltaPart;
                        aValue.Value += smDeltaPart;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }

                    else
                    {
                        pDistributionBySM[smGid] += dValue;
                        aValue.Value             += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
                else
                {
                    if (dValue <= smDeltaPart)
                    {
                        pDistributionBySM[smGid] += smDeltaPart;
                        dValue       -= smDeltaPart;
                        aValue.Value += smDeltaPart;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }
                    else
                    {
                        pDistributionBySM[smGid] += dValue;
                        aValue.Value             += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
            }
            else
            {
                if (isPositiveD) // ubaceno zbog negativnih delti
                {
                    if (dValue >= smFlexibility)
                    {
                        pDistributionBySM.Add(smGid, smFlexibility); // napunjen je do kraja, a ostaka smDelte nas ne zanima
                        dValue       -= smFlexibility;
                        aValue.Value += smFlexibility;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }
                    else
                    {
                        pDistributionBySM.Add(smGid, dValue); // napunjen je do kraja, a ostaka smDelte nas ne zanima
                        aValue.Value += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
                else
                {
                    smFlexibility = smFlexibility * -1;
                    if (dValue <= smFlexibility)
                    {
                        pDistributionBySM.Add(smGid, smFlexibility);
                        dValue       -= smFlexibility;
                        aValue.Value += smFlexibility;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }
                    else
                    {
                        pDistributionBySM.Add(smGid, dValue);
                        aValue.Value += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
            }
        }
        /// <summary>
        /// Helper function to distribute power when DER is flexible enough
        /// </summary>
        /// <param name="aValue"></param>
        /// <param name="setpoint"></param>
        /// <param name="smDelta"></param>
        /// <param name="smFlexibility"></param>
        /// <param name="dValue"></param>
        private void CheckDistributedPartsOnGoodFlex(Dictionary <long, float> pDistributionBySM, AnalogValue aValue,
                                                     Setpoint setpoint, float smDelta, float smFlexibility, bool isPositiveD, ref float dValue)
        {
            long smGid = aValue.SynchronousMachine;

            LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute power for flexible enough der: " + smGid);

            if (pDistributionBySM.ContainsKey(smGid)) // ako se vec nalazi u listi za distr, provjeriti trenutno opterecenje
            {
                if (Math.Abs(pDistributionBySM[smGid] + smDelta) <= smFlexibility)
                {
                    if (isPositiveD) //ubaceno zbog negativnih delti
                    {
                        if (dValue >= smDelta)
                        {
                            pDistributionBySM[smGid] += smDelta;
                            dValue       -= smDelta;
                            aValue.Value += smDelta;
                            UpdateAnalogValuesList(aValue, setpoint);
                        }

                        else
                        {
                            pDistributionBySM[smGid] += dValue;
                            aValue.Value             += dValue;
                            UpdateAnalogValuesList(aValue, setpoint);
                            dValue = 0;
                        }
                    }
                    else
                    {
                        if (dValue <= smDelta)
                        {
                            pDistributionBySM[smGid] += smDelta;
                            dValue       -= smDelta;
                            aValue.Value += smDelta;
                            UpdateAnalogValuesList(aValue, setpoint);
                        }
                        else
                        {
                            pDistributionBySM[smGid] += dValue;
                            aValue.Value             += dValue;
                            UpdateAnalogValuesList(aValue, setpoint);
                            dValue = 0;
                        }
                    }
                }
                else // ne moze se dodati cjelokupna delta
                {
                    float availableOnDER = smFlexibility - Math.Abs(pDistributionBySM[smGid]);

                    if (isPositiveD) //ubaceno zbog negativnih delti
                    {
                        if (dValue >= availableOnDER)
                        {
                            pDistributionBySM[smGid] += availableOnDER;
                            dValue       -= availableOnDER;
                            aValue.Value += availableOnDER;
                            UpdateAnalogValuesList(aValue, setpoint);
                        }
                        else
                        {
                            pDistributionBySM[smGid] += dValue;
                            aValue.Value             += dValue;
                            UpdateAnalogValuesList(aValue, setpoint);
                            dValue = 0;
                        }
                    }
                    else
                    {
                        availableOnDER = availableOnDER * (-1);
                        if (dValue <= availableOnDER)
                        {
                            pDistributionBySM[smGid] += availableOnDER;
                            dValue       -= availableOnDER;
                            aValue.Value += availableOnDER;
                            UpdateAnalogValuesList(aValue, setpoint);
                        }
                        else
                        {
                            pDistributionBySM[smGid] += dValue;
                            aValue.Value             += dValue;
                            UpdateAnalogValuesList(aValue, setpoint);
                            dValue = 0;
                        }
                    }
                }
            }
            else // ako se prvi put pojavljuje ta SM u raspodjeli
            {
                if (isPositiveD) // ubaceno zbog negativnih delti
                {
                    if (dValue >= smDelta)
                    {
                        pDistributionBySM.Add(smGid, smDelta); // napunjen je do kraja, a ostaka smDelte nas ne zanima
                        dValue       -= smDelta;
                        aValue.Value += smDelta;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }
                    else
                    {
                        pDistributionBySM.Add(smGid, dValue); // napunjen je do kraja, a ostaka smDelte nas ne zanima
                        aValue.Value += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
                else
                {
                    if (dValue <= smDelta)
                    {
                        pDistributionBySM.Add(smGid, smDelta);
                        dValue       -= smDelta;
                        aValue.Value += smDelta;
                        UpdateAnalogValuesList(aValue, setpoint);
                    }
                    else
                    {
                        pDistributionBySM.Add(smGid, dValue);
                        aValue.Value += dValue;
                        UpdateAnalogValuesList(aValue, setpoint);
                        dValue = 0;
                    }
                }
            }
        }
        /// <summary>
        /// Distribute required power by available reserve per each DER
        /// </summary>
        /// <param name="gid"> Region, subRegion or Entire network</param>
        /// <param name="demandedValue">Demanded power value</param>
        /// <param name="powerType"> Power type (Active/Reactive)</param>
        /// <param name="anaValues"> List of Analog Values</param>
        /// <returns></returns>
        public Setpoint AvailableReserveDistribution(long gid, float demandedValue, PowerType powerType, List <AnalogValue> anaValues)
        {
            LogHelper.Log(LogTarget.File, LogService.CalculationEngineDistributer, " INFO - CalculationEngineDistributer.cs - Distribute required power by available reserve per each DER for gid: " + gid);

            List <SynchronousMachine> syncMachines = RDAdapter.GetDERs(gid); // Get all DERs from a region, subregion or substation
            List <AnalogValue>        analogValues = anaValues;
            SynchronousMachine        syncMachine  = null;

            Dictionary <long, float> PDistributionBySM = new Dictionary <long, float>(syncMachines.Count);

            //Dictionary<long, float> currentReserveBySm = new Dictionary<long, float>(syncMachines.Count);

            Setpoint setpoint = new Setpoint();

            setpoint.PDistributionByAV = new Dictionary <long, float>();

            float demandValue            = demandedValue;
            float smFlexibility          = 0;
            float smAvailableReserve     = 0;
            float smAvailableReserveUp   = 0;
            float smAvailableReserveDown = 0;
            float smAvailableReserveSum  = 0;
            float smMaxPower             = 0;
            float smMinPower             = 0;
            float safetyCounter          = 0;
            bool  isDeltaPositive        = false;

            isDeltaPositive = demandedValue >= 0;

            foreach (AnalogValue aValue in anaValues.Where(a => a.PowerType == powerType))
            {
                syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine);

                switch (powerType)
                {
                case PowerType.Active:
                    smAvailableReserveUp   = syncMachine.MaxP - aValue.Value;
                    smAvailableReserveDown = aValue.Value - syncMachine.MinP;
                    break;

                case PowerType.Reactive:
                    smAvailableReserveUp   = syncMachine.MaxQ - aValue.Value;
                    smAvailableReserveDown = aValue.Value - syncMachine.MinQ;
                    break;

                default:
                    throw new FormatException("Invalid power type assigned to AnalogValue.");
                }

                smAvailableReserve     = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown;
                smAvailableReserveSum += smAvailableReserve;
            }

            while (demandValue > 0 && isDeltaPositive == true ||
                   demandValue < 0 && isDeltaPositive == false)
            {
                foreach (AnalogValue aValue in anaValues.Where(a => a.PowerType == powerType))
                {
                    syncMachine = syncMachines.Find(sm => sm.GlobalId == aValue.SynchronousMachine);

                    switch (powerType)
                    {
                    case PowerType.Active:
                        smMaxPower             = syncMachine.MaxP;
                        smMinPower             = syncMachine.MinP;
                        smFlexibility          = syncMachine.DERFlexibilityP;
                        smAvailableReserveUp   = syncMachine.MaxP - aValue.Value;
                        smAvailableReserveDown = aValue.Value - syncMachine.MinP;
                        break;

                    case PowerType.Reactive:
                        smMaxPower             = syncMachine.MaxQ;
                        smMinPower             = syncMachine.MinQ;
                        smFlexibility          = syncMachine.DERFlexibilityQ;
                        smAvailableReserveUp   = syncMachine.MaxQ - aValue.Value;
                        smAvailableReserveDown = aValue.Value - syncMachine.MinQ;
                        break;

                    default:
                        break;
                    }

                    if (aValue.Value == smMaxPower && isDeltaPositive == true)
                    {
                        continue;
                    }

                    if (aValue.Value == smMinPower && isDeltaPositive == false)
                    {
                        continue;
                    }

                    long referencedSMgid = aValue.SynchronousMachine;

                    smAvailableReserve = isDeltaPositive ? smAvailableReserveUp : smAvailableReserveDown;

                    if (smAvailableReserve == 0)
                    {
                        continue;
                    }

                    float k = smAvailableReserve * demandedValue / smAvailableReserveSum;

                    //korak redukovanja K, ne moze biti veci od MAX ni manji od MIN
                    ReduceKToProperValue(ref k, smAvailableReserve, isDeltaPositive, aValue);

                    if (Math.Abs(k) <= smFlexibility)
                    {
                        CheckDistributedPartsOnGoodFlex(PDistributionBySM, aValue, setpoint, k, smFlexibility, isDeltaPositive, ref demandValue);
                    }
                    else
                    {
                        CheckDistributedPartsOnPoorFlex(PDistributionBySM, aValue, setpoint, k, smFlexibility, isDeltaPositive, ref demandValue);
                    }
                }

                if (safetyCounter++ == 5)
                {
                    Trace.Write("Warning: 5 iterations were done, but no solution has been found.");
                    return(setpoint);
                }
            }
            return(setpoint);
        }
Exemple #19
0
        private void ThermostatSetpoint_Changed(object sender, ReportEventArgs <ThermostatSetpointReport> e)
        {
            var setpoint = new Setpoint(e.Report.Value, e.Report.Scale == 0 ? Unit.Celsius : Unit.Fahrenheit);

            OnSetPointChanged(new SetpointEventArgs(setpoint));
        }
        public object FunctionHandler(object jsonString)
        {
            SmartHomeRequest request = JsonConvert.DeserializeObject <SmartHomeRequest>(jsonString.ToString());

            LambdaLogger.Log(JsonConvert.SerializeObject(request) + Environment.NewLine);


            if (request.Directive.Header.Name == HeaderNames.DISCOVERY_REQUEST)
            {
                SmartHomeResponse response = new SmartHomeResponse(request.Directive.Header);
                Event             e        = response.Event as Event;
                DiscoveryPayload  p        = e.Payload as DiscoveryPayload;



                foreach (var tem in domoticz.GetTemperatureDevice().result)
                {
                    var setTermostato = domoticz.GetDevices().result.Where(x => Convert.ToInt32(x.ID) == Convert.ToInt32(tem.ID) && x.SubType == "SetPoint").FirstOrDefault();
                    if (setTermostato != null)
                    {
                        List <DisplayCategory> categoriest = new List <DisplayCategory>()
                        {
                            DisplayCategory.THERMOSTAT
                        };
                        List <Capability> capabilitiest = new List <Capability>();
                        capabilitiest.Add(new AlexaInterface("Alexa", "3", null, null, null, null));
                        capabilitiest.Add(new AlexaInterface(Namespaces.ALEXA_THERMOSTATCONTROLLER, "3", new List <string>()
                        {
                            PropertyNames.TARGET_SETPOINT, PropertyNames.THERMOSTATMODE
                        }, true, true));
                        capabilitiest.Add(new AlexaInterface(Namespaces.ALEXA_TEMPERATURESENSOR, "3", new List <string>()
                        {
                            PropertyNames.TEMPERATURE
                        }, true, true));
                        capabilitiest.Add(new AlexaInterface(Namespaces.ALEXA_ENDPOINTHEALTH, "3", new List <string>()
                        {
                            PropertyNames.CONNECTIVITY
                        }, true, true));
                        p.Endpoints.Add(new ResponseEndpoint(setTermostato.idx, setTermostato.HardwareName, setTermostato.Name, setTermostato.Description, cookiesTermostato, categoriest, capabilitiest));
                    }
                    List <DisplayCategory> categories = new List <DisplayCategory>()
                    {
                        DisplayCategory.TEMPERATURE_SENSOR
                    };
                    List <Capability> capabilities = new List <Capability>();
                    capabilities.Add(new AlexaInterface("Alexa", "3", null, null, null, null));
                    //capabilities.Add(new AlexaInterface(Namespaces.ALEXA_THERMOSTATCONTROLLER, "3", new List<string>() { PropertyNames.TARGET_SETPOINT, PropertyNames.THERMOSTATMODE }, true, true));
                    capabilities.Add(new AlexaInterface(Namespaces.ALEXA_TEMPERATURESENSOR, "3", new List <string>()
                    {
                        PropertyNames.TEMPERATURE
                    }, true, true));
                    capabilities.Add(new AlexaInterface(Namespaces.ALEXA_ENDPOINTHEALTH, "3", new List <string>()
                    {
                        PropertyNames.CONNECTIVITY
                    }, true, true));
                    p.Endpoints.Add(new ResponseEndpoint(tem.idx, tem.HardwareName, tem.Name, tem.Description, cookiesTemperature, categories, capabilities));
                }


                return(response);
            }
            else if (request.Directive.Header.Name == HeaderNames.REPORT_STATE)
            {
                LambdaLogger.Log(request.Directive.Endpoint.Cookie.GetValueOrDefault("Termostato") + Environment.NewLine);
                SmartHomeResponse response = new SmartHomeResponse(request.Directive.Header);

                if (request.Directive.Endpoint.Cookie.GetValueOrDefault("Termostato") == "Termostato")
                {
                    response.Context = new Context();
                    Setpoint temperaturaset = new Setpoint(domoticz.GetTemperatureDataDevice(request.Directive.Endpoint.EndpointID), Scale.CELSIUS);

                    Property p  = new Property(Namespaces.ALEXA_THERMOSTATCONTROLLER, PropertyNames.TARGET_SETPOINT, temperaturaset, DateTime.Now, 200);
                    Property p3 = new Property(Namespaces.ALEXA_COLORTEMPERATURECONTROLLER, PropertyNames.THERMOSTATMODE, ThermostatModes.HEAT, DateTime.Now, 200);
                    ConnectivityPropertyValue value = new ConnectivityPropertyValue(ConnectivityModes.OK);
                    Property p4 = new Property(Namespaces.ALEXA_ENDPOINTHEALTH, PropertyNames.CONNECTIVITY, value, DateTime.Now, 200);
                    response.Context.Properties.Add(p);
                    response.Context.Properties.Add(p3);
                    response.Context.Properties.Add(p4);
                    Event e = response.Event as Event;
                    e.Endpoint = new Endpoint(request.Directive.Endpoint.EndpointID, request.Directive.Endpoint.Scope);
                }
                else if (request.Directive.Endpoint.Cookie.GetValueOrDefault("Temperatura") == "Temperatura")
                {
                    response.Context = new Context();
                    Setpoint s = new Setpoint(domoticz.GetTemperatureDataDevice(request.Directive.Endpoint.EndpointID), Scale.CELSIUS);
                    Property p = new Property(Namespaces.ALEXA_TEMPERATURESENSOR, PropertyNames.TEMPERATURE, s, DateTime.Now, 200);
                    ConnectivityPropertyValue value = new ConnectivityPropertyValue(ConnectivityModes.OK);
                    Property p2 = new Property(Namespaces.ALEXA_ENDPOINTHEALTH, PropertyNames.CONNECTIVITY, value, DateTime.Now, 200);
                    response.Context.Properties.Add(p);
                    response.Context.Properties.Add(p2);
                    Event e = response.Event as Event;
                    e.Endpoint = new Endpoint(request.Directive.Endpoint.EndpointID, request.Directive.Endpoint.Scope);
                }
                return(response);
            }
            else if (request.Directive.Header.Name == HeaderNames.SETTARGETTEMPERATURE)
            {
                SmartHomeResponse response = new SmartHomeResponse(request.Directive.Header);
                response.Context = new Context();

                LambdaLogger.Log(JsonConvert.SerializeObject(request.Directive.Payload) + Environment.NewLine);
                PayloadTermostato termostato = JsonConvert.DeserializeObject <PayloadTermostato>(JsonConvert.SerializeObject(request.Directive.Payload));
                Property          p          = new Property(Namespaces.ALEXA_THERMOSTATCONTROLLER, PropertyNames.TARGET_SETPOINT,
                                                            new Setpoint(termostato.targetSetpoint.value, Scale.CELSIUS), DateTime.Now, 200);
                Property p3 = new Property(Namespaces.ALEXA_COLORTEMPERATURECONTROLLER, PropertyNames.THERMOSTATMODE, ThermostatModes.HEAT, DateTime.Now, 200);
                ConnectivityPropertyValue value;
                if (domoticz.SetTemperatureTermostato(request.Directive.Endpoint.EndpointID, termostato.targetSetpoint.value.ToString()))
                {
                    value = new ConnectivityPropertyValue(ConnectivityModes.OK);
                }
                else
                {
                    value = new ConnectivityPropertyValue(ConnectivityModes.UNREACHABLE);
                }
                Property p4 = new Property(Namespaces.ALEXA_ENDPOINTHEALTH, PropertyNames.CONNECTIVITY, value, DateTime.Now, 200);
                response.Context.Properties.Add(p);
                response.Context.Properties.Add(p3);
                response.Context.Properties.Add(p4);
                Event e = response.Event as Event;
                e.Endpoint = new Endpoint(request.Directive.Endpoint.EndpointID, request.Directive.Endpoint.Scope);
                return(response);
            }
            else
            {
                return(request);
            }
        }