private List <SetChannelPropertyGrouping> GroupChannelsForMultipleSensorsAndChannels(ChannelParameter[] channelParameters, List <IGrouping <int, Channel> > groupedByChannel)
        {
            //4c, 4cf, 5cf

            var list = new List <SetChannelPropertyGrouping>();

            //Multiple channels across multiple sensors. For small numbers of channels it's concievable it would be better to group per-sensor
            //however generally we will be cutting across multiple sensors using the same channel ID
            foreach (var channelGroup in groupedByChannel)
            {
                foreach (var task in GetSetChannelPropertyTasks(channelGroup.DistinctBy(c => new { c.Id, c.SensorId }).ToList(), channelParameters))
                {
                    //Let's see whether we'll need any factors
                    var tempParameters = new SetChannelPropertyParameters(task.Channels.Select(c => c.SensorId).Distinct().ToArray(), channelGroup.Key, task.Parameters);

                    //5cf
                    if (NeedFactors(tempParameters, task.Parameters))
                    {
                        //4cf
                        list.AddRange(GetFactorParameters(tempParameters, task.Channels));
                    }
                    else
                    {
                        //4c
                        list.Add(new SetChannelPropertyGrouping(tempParameters, task.Channels.ToReadOnly()));
                    }
                }
            }

            return(list);
        }
        private bool NeedFactors(SetChannelPropertyParameters parameters, ChannelParameter[] channelParameters)
        {
            if (parameters.FactorParameters.Count > 0)
            {
                var factorProperties = parameters.FactorParameters.Select(p => p.Item1).OfType <ChannelProperty>().ToList();

                //We are inclined to say we need channels. However, if all of the factor parameters found were explicitly
                //specified, and all have a null or empty value, we don't need to include channels
                if (factorProperties.All(p =>
                {
                    var parameter = channelParameters.FirstOrDefault(pa => pa.Property == p);

                    //The parameter was specified and its value was null or empty. Don't need channels for that!
                    if (parameter != null && string.IsNullOrEmpty(parameter.Value?.ToString()))
                    {
                        return(true);
                    }

                    //Either the parameter wasn't explicitly specified (meaning it's someones dependent property) or
                    //its value wasn't null or empty; we'll need to retrieve channels to specify the factor value
                    return(false);
                }))
                {
                    return(false);
                }

                return(true);
            }

            return(false);
        }
        private List <SetChannelPropertyGrouping> GroupChannelsForOneSensorAndChannel(ChannelParameter[] channelParameters, IGrouping <int, Channel> sensorsChannels, IGrouping <int, Channel> channelGroup)
        {
            //1c, 1cf, 5cf

            //At this point, regardless of whether or not all factor properties are null or not (if we even need factors at all) we're going to be executing a single request
            var list = new List <SetChannelPropertyGrouping>();

            foreach (var task in GetSetChannelPropertyTasks(channelGroup.DistinctBy(c => new { c.Id, c.SensorId }).ToList(), channelParameters))
            {
                var parameters = new SetChannelPropertyParameters(new[] { sensorsChannels.Key }, channelGroup.Key, task.Parameters);

                //5cf. If we don't need factors, we're equal to 1c
                if (NeedFactors(parameters, task.Parameters))
                {
                    //Apply the factors to the parameters

                    //We could have the same sensor twice with multiple factors; only accept the first one
                    var factor = task.Channels.GroupBy(c => c.Factor).First();

                    AddFactorProperties(parameters, parameters, factor);
                }

                //One channel on one sensor
                list.Add(new SetChannelPropertyGrouping(parameters, sensorsChannels.ToReadOnly()));
            }

            return(list);
        }
        private List <SetChannelPropertyGrouping> GroupChannelsForMultipleSensorsAndOneChannel(ChannelParameter[] channelParameters, IGrouping <int, Channel> channelGroup)
        {
            //3c, 3cf, 5cf

            var list = new List <SetChannelPropertyGrouping>();

            foreach (var task in GetSetChannelPropertyTasks(channelGroup.DistinctBy(c => new { c.Id, c.SensorId }).ToList(), channelParameters))
            {
                var sensorIds = task.Channels.Select(c => c.SensorId).ToArray();

                var tempParameters = new SetChannelPropertyParameters(sensorIds, channelGroup.Key, task.Parameters);

                //5cf
                if (NeedFactors(tempParameters, task.Parameters))
                {
                    //3cf
                    list.AddRange(GetFactorParameters(tempParameters, task.Channels));
                }
                else
                {
                    //3c
                    list.Add(new SetChannelPropertyGrouping(tempParameters, task.Channels));
                }
            }

            return(list);
        }
        internal async Task SetChannelPropertyAsync(int[] sensorIds, int channelId, ChannelParameter[] @params, CancellationToken token)
        {
            var parameters = new SetChannelPropertyParameters(sensorIds, channelId, @params);

            if (NeedChannels(parameters, @params))
            {
                var channels = await GetChannelsAsync(null, sensorIds, channelId, token).ConfigureAwait(false);

                await SetChannelPropertyAsync(channels, @params, token).ConfigureAwait(false);
            }
            else
            {
                await client.SetObjectPropertyAsync(parameters, parameters.SensorIds.Length, token).ConfigureAwait(false);
            }
        }
        //######################################
        // SetChannelProperty
        //######################################

        internal void SetChannelProperty(int[] sensorIds, int channelId, ChannelParameter[] @params, CancellationToken token)
        {
            var parameters = new SetChannelPropertyParameters(sensorIds, channelId, @params);

            if (NeedChannels(parameters, @params))
            {
                var channels = GetChannels(null, sensorIds, channelId, token);

                SetChannelProperty(channels, @params, token);
            }
            else
            {
                client.SetObjectProperty(parameters, parameters.SensorIds.Length, token);
            }
        }
        public void IShallowCloneable_SetChannelPropertyParameters_CloneFully()
        {
            var ids     = new[] { 1001, 1002, 1003 };
            var @params = new[]
            {
                new ChannelParameter(ChannelProperty.UpperErrorLimit, 100),
                new ChannelParameter(ChannelProperty.SpikeFilterEnabled, true)
            };

            var parameters = new SetChannelPropertyParameters(ids, 1, @params)
            {
                Cookie = true
            };

            Clone(parameters);
        }
        protected IEnumerable <SetChannelPropertyGrouping> GetFactorParameters(SetChannelPropertyParameters tempParameters, IEnumerable <Channel> channels)
        {
            //Get the factors for all channels with the given ID
            var factors = channels.Select(g => g).DistinctBy(c => new { c.Id, c.SensorId }).GroupBy(c => c.Factor);

            foreach (var factor in factors)
            {
                //4cf
                var factorParameters = tempParameters.ShallowClone();
                factorParameters.SensorIds = factor.Select(c => c.SensorId).ToArray();

                AddFactorProperties(tempParameters, factorParameters, factor);

                yield return(new SetChannelPropertyGrouping(factorParameters, factor.ToReadOnly()));
            }
        }
        private List <SetChannelPropertyGrouping> GroupChannelsForOneSensorAndMultipleChannels(ChannelParameter[] channelParameters, IGrouping <int, Channel> sensorsChannels, List <IGrouping <int, Channel> > groupedByChannel)
        {
            //2c, 2cf, 5cf

            //One sensor, multiple channels

            SetChannelPropertyParameters masterParameters = null;

            foreach (var channelGroup in groupedByChannel)
            {
                foreach (var task in GetSetChannelPropertyTasks(channelGroup.DistinctBy(c => new { c.Id, c.SensorId }).ToList(), channelParameters))
                {
                    var localParameters = new SetChannelPropertyParameters(new[] { sensorsChannels.Key }, channelGroup.Key, task.Parameters);

                    //5cf
                    if (NeedFactors(localParameters, task.Parameters))
                    {
                        var factors = task.Channels.GroupBy(c => c.Factor);

                        foreach (var factor in factors)
                        {
                            AddFactorProperties(localParameters, localParameters, factor);
                        }
                    }

                    if (masterParameters == null)
                    {
                        masterParameters = localParameters;
                    }
                    else
                    {
                        masterParameters.CustomParameters.AddRange(localParameters.CustomParameters);
                    }
                }
            }

            masterParameters.RemoveDuplicateParameters();

            return(new List <SetChannelPropertyGrouping>
            {
                new SetChannelPropertyGrouping(masterParameters, groupedByChannel.SelectMany(c => c).ToReadOnly())
            });
        }
        private void AddFactorProperties(SetChannelPropertyParameters outerParameters, SetChannelPropertyParameters innerParameters, IGrouping <double?, Channel> factor)
        {
            if (factor.Key == null)
            {
                return;
            }

            //For each ChannelProperty that has a factor
            foreach (var obj in outerParameters.FactorParameters)
            {
                var prop = obj.Item2.Property;

                //Get the factor property that also needs to be included (e.g. UpperErrorLimitFactor)
                var cache = outerParameters.GetPropertyCache(prop);

                Debug.Assert(factor.All(g => (double?)cache.Property.GetValue(g) == factor.Key), "Generic and specific Factor were not equal for at least one channel");

                //Generate the factor's property name
                var name = outerParameters.GetFactorParameterName(prop, cache);

                //And add it
                innerParameters.CustomParameters.Add(new CustomParameter(name, factor.Key));
            }
        }
 protected virtual bool NeedChannels(SetChannelPropertyParameters parameters, ChannelParameter[] channelParameters)
 {
     return(NeedFactors(parameters, channelParameters));
 }
 public SetChannelPropertyGrouping(SetChannelPropertyParameters parameters, ReadOnlyCollection <Channel> channels)
 {
     Parameters = parameters;
     Channels   = channels;
 }
Esempio n. 13
0
 protected override bool NeedChannels(SetChannelPropertyParameters parameters, ChannelParameter[] channelParameters)
 {
     return(base.NeedChannels(parameters, channelParameters) || NeedsLimit(channelParameters));
 }