private void LoadFeatures(List <DeviceViewModel> deviceList = null) { if (deviceList == null) { var registeredDevices = Settings.RegisteredDevices; // Generate View Models for devices and assign to Device Collection deviceList = DeviceViewModel.GetViewModels(registeredDevices); NumberDevices = deviceList.Count; } int index = 0; if (deviceList != null) { _fullFeatureLists = new List <List <FeaturesViewModel> > (0); foreach (DeviceViewModel device in deviceList) { var fullFeatureList = FeaturesViewModel.GetFeaturesViewModels(device.DeviceFeatures, this); _fullFeatureLists.Add(fullFeatureList); } FullFeatureCollection = new ObservableCollection <List <FeaturesViewModel> >(_fullFeatureLists); if (deviceList.Count > 0) { if (CurrentDeviceSelection == -1) { index = (int)Math.Round((deviceList.Count - 1.0) / 2, 1); CurrentDeviceSelection = index; // will load Feature Collection } else { index = CurrentDeviceSelection; FeatureCollection = new ObservableCollection <FeaturesViewModel>(_fullFeatureLists[index].Where(f => !f.FeatureType.Equals(FeatureType.SubType) || f.Expanded)); } } } }
public static void AddOrUpdateSelection(int parentIndex, object value, Type valueType) { FeaturesViewModel parent = _fullFeatureCollection[_currentDeviceSelection].Where(f => f.Index.Equals(parentIndex)).First(); Selections[parent.Label] = new Tuple <object, Type>(value, valueType); // Update stored value Settings.Selections = Selections; }
public static List <FeaturesViewModel> GetFeaturesViewModels(List <Feature> features, BaseViewModel parentViewModel = null) { List <FeaturesViewModel> list = new List <FeaturesViewModel>(features?.Count ?? 0); int index = 0; foreach (Feature feature in features ?? new List <Feature>(0)) { var fvm = new FeaturesViewModel(feature, index, parentViewModel); // Add in the vm for the selection option entry if (feature.FeatureType == FeatureType.Selection) { // TODO: // NOTE: THE CURRENT DATA MODEL FROM THE SERVER DOES NOT SUPPORT ADDING THE SELECTION // CRITERIA IN AN ABSTRACT FASHION. IT WOULD NEED TO PASS THE PARAMETER TYPE(S), THE RANGE OR DESCRETE VALUES, // HOW MANY SUB-SELECTIONS, AND THE SELECTION CONTROL TYPE. // AS SUCH CURRENTLY ONLT HARD CODED TYPES AND HARD CODED SELECTION CRITERIA CAN BE SUPPORTED. NEW TYPES WILL // REQUIRE AN UPDATE TO THE APP // Check if a DUMMY feature in which case don't add anything - could add in but not at moment if (feature.FeatureName.Contains("Dummy")) { // Add to list but not any sub features list.Add(fvm); } else { //set the number of sub features fvm.NumberSubTypeChildren = 1; // Add to list list.Add(fvm); index++; //create new view model and add to list - hard coded (See above) // only brew strength currently defined if (feature.SubType == SubType.BrewStrength) { var vm = new FeaturesViewModel { Index = index, FeatureType = FeatureType.SubType, SubType = SubType.BrewStrength, ParentIndex = index - 1, FeatureName = "brewStrengthFeature", FeatureMethodName = "changeBrewStrength" }; list.Add(vm); } } } else { // Add to list list.Add(fvm); } index++; } return(list); }
public async Task OnListItemTapped(FeaturesViewModel vm) { // Check if the Feature is an Action if (vm.FeatureType == FeatureType.Action) { // NOTE: Currently hard coded to supported actions which will require a new version of the app to support new actions. // The server view models need to be changed to support the abstract definition of actions so they can be cerated and supported // dynamically without a change to the code vm.IsBusy = !vm.IsBusy; // persist the change in busy status FullFeatureCollection[CurrentDeviceSelection][vm.Index].IsBusy = vm.IsBusy; if (vm.FeatureName.Contains("brew") || vm.FeatureName.Contains("Brew")) { if (vm.IsBusy) { // if it is now busy, invoke the actions // set brew strength // try to get the brew strength if (!Selections.TryGetValue("Brew Strength", out Tuple <object, Type> brewStrength)) { brewStrength = new Tuple <object, Type>(1, typeof(int)); } var response1 = await IoTHubDataService.Instance.InvokeFeature(CurrentDeviceId, "changeBrewStrength", Convert.ToString(brewStrength.Item1)); if (response1 == null) { vm.IsBusy = false; await App.Current.MainPage.DisplayAlert("Sorry", "Your Device isn't responding. \nPlease ensure it has power and is connected, and try again.", "Ok"); } else if (response1.Status.ToLower() != "success") { vm.IsBusy = false; await App.Current.MainPage.DisplayAlert("Sorry", "Your Device has sent an error. \nPlease check it and try again", "Ok"); } else { // Invoke brew related feature action var response2 = await IoTHubDataService.Instance.InvokeFeature(CurrentDeviceId, vm.FeatureMethodName, vm.FeatureMethodParameter); // if it was actioned successfully if (response2 == null) { vm.IsBusy = false; await App.Current.MainPage.DisplayAlert("Sorry", "Your Device isn't responding. \nPlease ensure it has power and is connected, and try again.", "Ok"); } else if (response2.Status.ToLower() != "success") { vm.IsBusy = false; await App.Current.MainPage.DisplayAlert("Sorry", "Your Device has sent an error. \nPlease check it and try again", "Ok"); } else { //set an asynchronous timer based upon the returned DateTimeStamp var UTCCompleteTime = response2.TimeTillCompletion; var currentUTCTime = DateTime.Now.ToUniversalTime(); var completeInMs = UTCCompleteTime.Subtract(currentUTCTime).TotalMilliseconds > 0 ? UTCCompleteTime.Subtract(currentUTCTime).TotalMilliseconds : 0; TimerStateObjClass StateObj = new TimerStateObjClass { Vm = vm, SelectedDevice = CurrentDeviceSelection }; // Could move Timer to be a field of the deviceViewModel TimerCallback TimerDelegate = new System.Threading.TimerCallback((o) => { var state = (TimerStateObjClass)o; state.Vm.IsBusy = false; // Persist the busy state FullFeatureCollection[state.SelectedDevice][state.Vm.Index].IsBusy = false; state.TimerReference.Dispose(); }); vm.Timer = new Timer(TimerDelegate, StateObj, (int)completeInMs + 2000, Timeout.Infinite); StateObj.TimerReference = vm.Timer; } } } else { // Cancel the action var response2 = await IoTHubDataService.Instance.InvokeFeature(CurrentDeviceId, vm.FeatureMethodName, vm.FeatureMethodParameter); if (vm.Timer != null) { vm.Timer.Dispose(); } } } else { // Invoke feature action - manipulate Is busy as necessary var response2 = await IoTHubDataService.Instance.InvokeFeature(CurrentDeviceId, vm.FeatureMethodName, vm.FeatureMethodParameter); vm.IsBusy = false; } // persist the resultant busy state FullFeatureCollection[CurrentDeviceSelection][vm.Index].IsBusy = vm.IsBusy; } }