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